Merge pull request #2923 from rust-lang-nursery/kind

Rustup to 1ecf6929dc
This commit is contained in:
Manish Goregaokar 2018-07-16 16:41:50 -07:00 committed by GitHub
commit f27aaacb9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 1307 additions and 1267 deletions

View File

@ -93,9 +93,9 @@ a `.stdout` file with the generated code:
// ./tests/ui/my_lint.stdout // ./tests/ui/my_lint.stdout
if_chain! { if_chain! {
if let Expr_::ExprArray(ref elements) = stmt.node; if let ExprKind::Array(ref elements) = stmt.node;
if elements.len() == 1; if elements.len() == 1;
if let Expr_::ExprLit(ref lit) = elements[0].node; if let ExprKind::Lit(ref lit) = elements[0].node;
if let LitKind::Int(7, _) = lit.node; if let LitKind::Int(7, _) = lit.node;
then { then {
// report your lint here // report your lint here
@ -179,7 +179,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
``` ```
The [`rustc_plugin::PluginRegistry`][plugin_registry] provides two methods to register lints: [register_early_lint_pass][reg_early_lint_pass] and [register_late_lint_pass][reg_late_lint_pass]. The [`rustc_plugin::PluginRegistry`][plugin_registry] provides two methods to register lints: [register_early_lint_pass][reg_early_lint_pass] and [register_late_lint_pass][reg_late_lint_pass].
Both take an object that implements an [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass] respectively. This is done in every single lint. Both take an object that implements an [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass] respectively. This is done in every single lint.
It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerated by `util/update_lints.py` and you don't have to add anything by hand. When you are writing your own lint, you can use that script to save you some time. It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerated by `util/update_lints.py` and you don't have to add anything by hand. When you are writing your own lint, you can use that script to save you some time.
```rust ```rust

View File

@ -63,7 +63,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>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
if let ExprLit(ref lit) = e.node { if let ExprKind::Lit(ref lit) = e.node {
check_lit(cx, lit, e); check_lit(cx, lit, e);
} }
} }

View File

@ -55,21 +55,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
return; return;
} }
match expr.node { match expr.node {
hir::ExprBinary(ref op, ref l, ref r) => { hir::ExprKind::Binary(ref op, ref l, ref r) => {
match op.node { match op.node {
hir::BiAnd hir::BinOpKind::And
| hir::BiOr | hir::BinOpKind::Or
| hir::BiBitAnd | hir::BinOpKind::BitAnd
| hir::BiBitOr | hir::BinOpKind::BitOr
| hir::BiBitXor | hir::BinOpKind::BitXor
| hir::BiShl | hir::BinOpKind::Shl
| hir::BiShr | hir::BinOpKind::Shr
| hir::BiEq | hir::BinOpKind::Eq
| hir::BiLt | hir::BinOpKind::Lt
| hir::BiLe | hir::BinOpKind::Le
| hir::BiNe | hir::BinOpKind::Ne
| hir::BiGe | hir::BinOpKind::Ge
| hir::BiGt => return, | hir::BinOpKind::Gt => return,
_ => (), _ => (),
} }
let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r)); let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r));
@ -81,7 +81,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
self.span = Some(expr.span); self.span = Some(expr.span);
} }
}, },
hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => { hir::ExprKind::Unary(hir::UnOp::UnNeg, ref arg) => {
let ty = cx.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");

View File

@ -76,7 +76,7 @@ impl LintPass for AssignOps {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
match expr.node { match expr.node {
hir::ExprAssignOp(op, ref lhs, ref rhs) => { hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
span_lint_and_then(cx, ASSIGN_OPS, expr.span, "assign operation detected", |db| { span_lint_and_then(cx, ASSIGN_OPS, expr.span, "assign operation detected", |db| {
let lhs = &sugg::Sugg::hir(cx, lhs, ".."); let lhs = &sugg::Sugg::hir(cx, lhs, "..");
let rhs = &sugg::Sugg::hir(cx, rhs, ".."); let rhs = &sugg::Sugg::hir(cx, rhs, "..");
@ -87,7 +87,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
format!("{} = {}", lhs, sugg::make_binop(higher::binop(op.node), lhs, rhs)), format!("{} = {}", lhs, sugg::make_binop(higher::binop(op.node), lhs, rhs)),
); );
}); });
if let hir::ExprBinary(binop, ref l, ref r) = rhs.node { if let hir::ExprKind::Binary(binop, ref l, ref r) = rhs.node {
if op.node == binop.node { if op.node == binop.node {
let lint = |assignee: &hir::Expr, rhs_other: &hir::Expr| { let lint = |assignee: &hir::Expr, rhs_other: &hir::Expr| {
span_lint_and_then( span_lint_and_then(
@ -131,8 +131,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
} }
} }
}, },
hir::ExprAssign(ref assignee, ref e) => { hir::ExprKind::Assign(ref assignee, ref e) => {
if let hir::ExprBinary(op, ref l, ref r) = e.node { if let hir::ExprKind::Binary(op, ref l, ref r) = e.node {
#[allow(cyclomatic_complexity)] #[allow(cyclomatic_complexity)]
let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
let ty = cx.tables.expr_ty(assignee); let ty = cx.tables.expr_ty(assignee);
@ -142,9 +142,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
$cx:expr, $cx:expr,
$ty:expr, $ty:expr,
$rty:expr, $rty:expr,
$($trait_name:ident:$full_trait_name:ident),+) => { $($trait_name:ident),+) => {
match $op { match $op {
$(hir::$full_trait_name => { $(hir::BinOpKind::$trait_name => {
let [krate, module] = crate::utils::paths::OPS_MODULE; let [krate, module] = crate::utils::paths::OPS_MODULE;
let path = [krate, module, concat!(stringify!($trait_name), "Assign")]; let path = [krate, module, concat!(stringify!($trait_name), "Assign")];
let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) { let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) {
@ -159,7 +159,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
if_chain! { if_chain! {
if parent_impl != ast::CRATE_NODE_ID; if parent_impl != ast::CRATE_NODE_ID;
if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl); if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl);
if let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = if let hir::ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) =
item.node; item.node;
if trait_ref.path.def.def_id() == trait_id; if trait_ref.path.def.def_id() == trait_id;
then { return; } then { return; }
@ -175,18 +175,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
cx, cx,
ty, ty,
rty.into(), rty.into(),
Add: BiAdd, Add,
Sub: BiSub, Sub,
Mul: BiMul, Mul,
Div: BiDiv, Div,
Rem: BiRem, Rem,
And: BiAnd, And,
Or: BiOr, Or,
BitAnd: BiBitAnd, BitAnd,
BitOr: BiBitOr, BitOr,
BitXor: BiBitXor, BitXor,
Shr: BiShr, Shr,
Shl: BiShl Shl
) { ) {
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -224,13 +224,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
// a = b commutative_op a // a = b commutative_op a
if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) { if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) {
match op.node { match op.node {
hir::BiAdd hir::BinOpKind::Add
| hir::BiMul | hir::BinOpKind::Mul
| hir::BiAnd | hir::BinOpKind::And
| hir::BiOr | hir::BinOpKind::Or
| hir::BiBitXor | hir::BinOpKind::BitXor
| hir::BiBitAnd | hir::BinOpKind::BitAnd
| hir::BiBitOr => { | hir::BinOpKind::BitOr => {
lint(assignee, l); lint(assignee, l);
}, },
_ => {}, _ => {},
@ -244,11 +244,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
} }
} }
fn is_commutative(op: hir::BinOp_) -> bool { fn is_commutative(op: hir::BinOpKind) -> bool {
use rustc::hir::BinOp_::*; use rustc::hir::BinOpKind::*;
match op { match op {
BiAdd | BiMul | BiAnd | BiOr | BiBitXor | BiBitAnd | BiBitOr | BiEq | BiNe => true, Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true,
BiSub | BiDiv | BiRem | BiShl | BiShr | BiLt | BiLe | BiGe | BiGt => false, Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false,
} }
} }

View File

@ -154,7 +154,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
check_attrs(cx, item.span, item.name, &item.attrs) check_attrs(cx, item.span, item.name, &item.attrs)
} }
match item.node { match item.node {
ItemExternCrate(_) | ItemUse(_, _) => { ItemKind::ExternCrate(_) | ItemKind::Use(_, _) => {
for attr in &item.attrs { for attr in &item.attrs {
if let Some(ref lint_list) = attr.meta_item_list() { if let Some(ref lint_list) = attr.meta_item_list() {
match &*attr.name().as_str() { match &*attr.name().as_str() {
@ -162,7 +162,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
// whitelist `unused_imports` and `deprecated` // whitelist `unused_imports` and `deprecated`
for lint in lint_list { for lint in lint_list {
if is_word(lint, "unused_imports") || is_word(lint, "deprecated") { if is_word(lint, "unused_imports") || is_word(lint, "deprecated") {
if let ItemUse(_, _) = item.node { if let ItemKind::Use(_, _) = item.node {
return; return;
} }
} }
@ -207,7 +207,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
} }
fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool { fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool {
if let ItemFn(_, _, _, eid) = item.node { if let ItemKind::Fn(_, _, _, eid) = item.node {
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value) is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
} else { } else {
true true
@ -234,8 +234,8 @@ fn is_relevant_trait(tcx: TyCtxt, item: &TraitItem) -> bool {
fn is_relevant_block(tcx: TyCtxt, tables: &ty::TypeckTables, block: &Block) -> bool { fn is_relevant_block(tcx: TyCtxt, tables: &ty::TypeckTables, block: &Block) -> bool {
if let Some(stmt) = block.stmts.first() { if let Some(stmt) = block.stmts.first() {
match stmt.node { match stmt.node {
StmtDecl(_, _) => true, StmtKind::Decl(_, _) => true,
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => is_relevant_expr(tcx, tables, expr), StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => is_relevant_expr(tcx, tables, expr),
} }
} else { } else {
block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e)) block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e))
@ -244,10 +244,10 @@ fn is_relevant_block(tcx: TyCtxt, tables: &ty::TypeckTables, block: &Block) -> b
fn is_relevant_expr(tcx: TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool { fn is_relevant_expr(tcx: TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprBlock(ref block, _) => is_relevant_block(tcx, tables, block), ExprKind::Block(ref block, _) => is_relevant_block(tcx, tables, block),
ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e), ExprKind::Ret(Some(ref e)) => is_relevant_expr(tcx, tables, e),
ExprRet(None) | ExprBreak(_, None) => false, ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
ExprCall(ref path_expr, _) => if let ExprPath(ref qpath) = path_expr.node { ExprKind::Call(ref path_expr, _) => if let ExprKind::Path(ref qpath) = path_expr.node {
if let Some(fun_id) = opt_def_id(tables.qpath_def(qpath, path_expr.hir_id)) { if let Some(fun_id) = opt_def_id(tables.qpath_def(qpath, path_expr.hir_id)) {
!match_def_path(tcx, fun_id, &paths::BEGIN_PANIC) !match_def_path(tcx, fun_id, &paths::BEGIN_PANIC)
} else { } else {

View File

@ -109,7 +109,7 @@ impl LintPass for BitMask {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
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 ExprBinary(ref cmp, ref left, ref right) = e.node { if let ExprKind::Binary(ref cmp, ref left, ref right) = e.node {
if cmp.node.is_comparison() { if cmp.node.is_comparison() {
if let Some(cmp_opt) = fetch_int_literal(cx, right) { if let Some(cmp_opt) = fetch_int_literal(cx, right) {
check_compare(cx, left, cmp.node, cmp_opt, e.span) check_compare(cx, left, cmp.node, cmp_opt, e.span)
@ -119,13 +119,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
} }
} }
if_chain! { if_chain! {
if let Expr_::ExprBinary(ref op, ref left, ref right) = e.node; if let ExprKind::Binary(ref op, ref left, ref right) = e.node;
if BinOp_::BiEq == op.node; if BinOpKind::Eq == op.node;
if let Expr_::ExprBinary(ref op1, ref left1, ref right1) = left.node; if let ExprKind::Binary(ref op1, ref left1, ref right1) = left.node;
if BinOp_::BiBitAnd == op1.node; if BinOpKind::BitAnd == op1.node;
if let Expr_::ExprLit(ref lit) = right1.node; if let ExprKind::Lit(ref lit) = right1.node;
if let LitKind::Int(n, _) = lit.node; if let LitKind::Int(n, _) = lit.node;
if let Expr_::ExprLit(ref lit1) = right.node; if let ExprKind::Lit(ref lit1) = right.node;
if let LitKind::Int(0, _) = lit1.node; if let LitKind::Int(0, _) = lit1.node;
if n.leading_zeros() == n.count_zeros(); if n.leading_zeros() == n.count_zeros();
if n > u128::from(self.verbose_bit_mask_threshold); if n > u128::from(self.verbose_bit_mask_threshold);
@ -143,22 +143,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
} }
} }
fn invert_cmp(cmp: BinOp_) -> BinOp_ { fn invert_cmp(cmp: BinOpKind) -> BinOpKind {
match cmp { match cmp {
BiEq => BiEq, BinOpKind::Eq => BinOpKind::Eq,
BiNe => BiNe, BinOpKind::Ne => BinOpKind::Ne,
BiLt => BiGt, BinOpKind::Lt => BinOpKind::Gt,
BiGt => BiLt, BinOpKind::Gt => BinOpKind::Lt,
BiLe => BiGe, BinOpKind::Le => BinOpKind::Ge,
BiGe => BiLe, BinOpKind::Ge => BinOpKind::Le,
_ => BiOr, // Dummy _ => BinOpKind::Or, // Dummy
} }
} }
fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u128, span: Span) { fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOpKind, cmp_value: u128, span: Span) {
if let ExprBinary(ref op, ref left, ref right) = bit_op.node { if let ExprKind::Binary(ref op, ref left, ref right) = bit_op.node {
if op.node != BiBitAnd && op.node != BiBitOr { if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr {
return; return;
} }
fetch_int_literal(cx, right) fetch_int_literal(cx, right)
@ -167,10 +167,10 @@ fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u12
} }
} }
fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: u128, cmp_value: u128, span: Span) { fn check_bit_mask(cx: &LateContext, bit_op: BinOpKind, cmp_op: BinOpKind, mask_value: u128, cmp_value: u128, span: Span) {
match cmp_op { match cmp_op {
BiEq | BiNe => match bit_op { BinOpKind::Eq | BinOpKind::Ne => match bit_op {
BiBitAnd => if mask_value & cmp_value != cmp_value { BinOpKind::BitAnd => if mask_value & cmp_value != cmp_value {
if cmp_value != 0 { if cmp_value != 0 {
span_lint( span_lint(
cx, cx,
@ -186,7 +186,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
} else if mask_value == 0 { } else if mask_value == 0 {
span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero"); span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero");
}, },
BiBitOr => if mask_value | cmp_value != cmp_value { BinOpKind::BitOr => if mask_value | cmp_value != cmp_value {
span_lint( span_lint(
cx, cx,
BAD_BIT_MASK, BAD_BIT_MASK,
@ -200,8 +200,8 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
}, },
_ => (), _ => (),
}, },
BiLt | BiGe => match bit_op { BinOpKind::Lt | BinOpKind::Ge => match bit_op {
BiBitAnd => if mask_value < cmp_value { BinOpKind::BitAnd => if mask_value < cmp_value {
span_lint( span_lint(
cx, cx,
BAD_BIT_MASK, BAD_BIT_MASK,
@ -215,7 +215,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
} else if mask_value == 0 { } else if mask_value == 0 {
span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero"); span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero");
}, },
BiBitOr => if mask_value >= cmp_value { BinOpKind::BitOr => if mask_value >= cmp_value {
span_lint( span_lint(
cx, cx,
BAD_BIT_MASK, BAD_BIT_MASK,
@ -229,11 +229,11 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
} else { } else {
check_ineffective_lt(cx, span, mask_value, cmp_value, "|"); check_ineffective_lt(cx, span, mask_value, cmp_value, "|");
}, },
BiBitXor => check_ineffective_lt(cx, span, mask_value, cmp_value, "^"), BinOpKind::BitXor => check_ineffective_lt(cx, span, mask_value, cmp_value, "^"),
_ => (), _ => (),
}, },
BiLe | BiGt => match bit_op { BinOpKind::Le | BinOpKind::Gt => match bit_op {
BiBitAnd => if mask_value <= cmp_value { BinOpKind::BitAnd => if mask_value <= cmp_value {
span_lint( span_lint(
cx, cx,
BAD_BIT_MASK, BAD_BIT_MASK,
@ -247,7 +247,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
} else if mask_value == 0 { } else if mask_value == 0 {
span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero"); span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero");
}, },
BiBitOr => if mask_value > cmp_value { BinOpKind::BitOr => if mask_value > cmp_value {
span_lint( span_lint(
cx, cx,
BAD_BIT_MASK, BAD_BIT_MASK,
@ -261,7 +261,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
} else { } else {
check_ineffective_gt(cx, span, mask_value, cmp_value, "|"); check_ineffective_gt(cx, span, mask_value, cmp_value, "|");
}, },
BiBitXor => check_ineffective_gt(cx, span, mask_value, cmp_value, "^"), BinOpKind::BitXor => check_ineffective_gt(cx, span, mask_value, cmp_value, "^"),
_ => (), _ => (),
}, },
_ => (), _ => (),

View File

@ -56,10 +56,10 @@ struct ExVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx: 'a> Visitor<'tcx> for ExVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr) { fn visit_expr(&mut self, expr: &'tcx Expr) {
if let ExprClosure(_, _, eid, _, _) = expr.node { if let ExprKind::Closure(_, _, eid, _, _) = expr.node {
let body = self.cx.tcx.hir.body(eid); let body = self.cx.tcx.hir.body(eid);
let ex = &body.value; let ex = &body.value;
if matches!(ex.node, ExprBlock(_, _)) { if matches!(ex.node, ExprKind::Block(_, _)) {
self.found_block = Some(ex); self.found_block = Some(ex);
return; return;
} }
@ -77,8 +77,8 @@ const COMPLEX_BLOCK_MESSAGE: &str = "in an 'if' condition, avoid complex blocks
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition {
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 ExprIf(ref check, ref then, _) = expr.node { if let ExprKind::If(ref check, ref then, _) = expr.node {
if let ExprBlock(ref block, _) = check.node { if let ExprKind::Block(ref block, _) = check.node {
if block.rules == DefaultBlock { if block.rules == DefaultBlock {
if block.stmts.is_empty() { if block.stmts.is_empty() {
if let Some(ref ex) = block.expr { if let Some(ref ex) = block.expr {

View File

@ -84,9 +84,9 @@ struct Hir2Qmm<'a, 'tcx: 'a, 'v> {
} }
impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
fn extract(&mut self, op: BinOp_, a: &[&'v Expr], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> { fn extract(&mut self, op: BinOpKind, a: &[&'v Expr], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {
for a in a { for a in a {
if let ExprBinary(binop, ref lhs, ref rhs) = a.node { if let ExprKind::Binary(binop, ref lhs, ref rhs) = a.node {
if binop.node == op { if binop.node == op {
v = self.extract(op, &[lhs, rhs], v)?; v = self.extract(op, &[lhs, rhs], v)?;
continue; continue;
@ -101,13 +101,13 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
// prevent folding of `cfg!` macros and the like // prevent folding of `cfg!` macros and the like
if !in_macro(e.span) { if !in_macro(e.span) {
match e.node { match e.node {
ExprUnary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)), ExprKind::Unary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)),
ExprBinary(binop, ref lhs, ref rhs) => match binop.node { ExprKind::Binary(binop, ref lhs, ref rhs) => match binop.node {
BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)), BinOpKind::Or => return Ok(Bool::Or(self.extract(BinOpKind::Or, &[lhs, rhs], Vec::new())?)),
BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)), BinOpKind::And => return Ok(Bool::And(self.extract(BinOpKind::And, &[lhs, rhs], Vec::new())?)),
_ => (), _ => (),
}, },
ExprLit(ref lit) => match lit.node { ExprKind::Lit(ref lit) => match lit.node {
LitKind::Bool(true) => return Ok(Bool::True), LitKind::Bool(true) => return Ok(Bool::True),
LitKind::Bool(false) => return Ok(Bool::False), LitKind::Bool(false) => return Ok(Bool::False),
_ => (), _ => (),
@ -121,8 +121,8 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
return Ok(Bool::Term(n as u8)); return Ok(Bool::Term(n as u8));
} }
let negated = match e.node { let negated = match e.node {
ExprBinary(binop, ref lhs, ref rhs) => { ExprKind::Binary(binop, ref lhs, ref rhs) => {
if !implements_ord(self.cx, lhs) { if !implements_ord(self.cx, lhs) {
continue; continue;
} }
@ -133,16 +133,16 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
hir_id: DUMMY_HIR_ID, hir_id: DUMMY_HIR_ID,
span: DUMMY_SP, span: DUMMY_SP,
attrs: ThinVec::new(), attrs: ThinVec::new(),
node: ExprBinary(dummy_spanned(op), lhs.clone(), rhs.clone()), node: ExprKind::Binary(dummy_spanned(op), lhs.clone(), rhs.clone()),
} }
}; };
match binop.node { match binop.node {
BiEq => mk_expr(BiNe), BinOpKind::Eq => mk_expr(BinOpKind::Ne),
BiNe => mk_expr(BiEq), BinOpKind::Ne => mk_expr(BinOpKind::Eq),
BiGt => mk_expr(BiLe), BinOpKind::Gt => mk_expr(BinOpKind::Le),
BiGe => mk_expr(BiLt), BinOpKind::Ge => mk_expr(BinOpKind::Lt),
BiLt => mk_expr(BiGe), BinOpKind::Lt => mk_expr(BinOpKind::Ge),
BiLe => mk_expr(BiGt), BinOpKind::Le => mk_expr(BinOpKind::Gt),
_ => continue, _ => continue,
} }
}, },
@ -178,23 +178,23 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
fn simplify_not(&self, expr: &Expr) -> Option<String> { fn simplify_not(&self, expr: &Expr) -> Option<String> {
match expr.node { match expr.node {
ExprBinary(binop, ref lhs, ref rhs) => { ExprKind::Binary(binop, ref lhs, ref rhs) => {
if !implements_ord(self.cx, lhs) { if !implements_ord(self.cx, lhs) {
return None; return None;
} }
match binop.node { match binop.node {
BiEq => Some(" != "), BinOpKind::Eq => Some(" != "),
BiNe => Some(" == "), BinOpKind::Ne => Some(" == "),
BiLt => Some(" >= "), BinOpKind::Lt => Some(" >= "),
BiGt => Some(" <= "), BinOpKind::Gt => Some(" <= "),
BiLe => Some(" > "), BinOpKind::Le => Some(" > "),
BiGe => Some(" < "), BinOpKind::Ge => Some(" < "),
_ => None, _ => None,
}.and_then(|op| Some(format!("{}{}{}", self.snip(lhs)?, op, self.snip(rhs)?))) }.and_then(|op| Some(format!("{}{}{}", self.snip(lhs)?, op, self.snip(rhs)?)))
}, },
ExprMethodCall(ref path, _, ref args) if args.len() == 1 => { ExprKind::MethodCall(ref path, _, ref args) if args.len() == 1 => {
let type_of_receiver = self.cx.tables.expr_ty(&args[0]); let type_of_receiver = self.cx.tables.expr_ty(&args[0]);
if !match_type(self.cx, type_of_receiver, &paths::OPTION) && if !match_type(self.cx, type_of_receiver, &paths::OPTION) &&
!match_type(self.cx, type_of_receiver, &paths::RESULT) { !match_type(self.cx, type_of_receiver, &paths::RESULT) {
@ -441,8 +441,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
return; return;
} }
match e.node { match e.node {
ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e), ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => self.bool_expr(e),
ExprUnary(UnNot, ref inner) => if self.cx.tables.node_types()[inner.hir_id].is_bool() { ExprKind::Unary(UnNot, ref inner) => if self.cx.tables.node_types()[inner.hir_id].is_bool() {
self.bool_expr(e); self.bool_expr(e);
} else { } else {
walk_expr(self, e); walk_expr(self, e);

View File

@ -38,20 +38,20 @@ impl LintPass for ByteCount {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
if_chain! { if_chain! {
if let ExprMethodCall(ref count, _, ref count_args) = expr.node; if let ExprKind::MethodCall(ref count, _, ref count_args) = expr.node;
if count.ident.name == "count"; if count.ident.name == "count";
if count_args.len() == 1; if count_args.len() == 1;
if let ExprMethodCall(ref filter, _, ref filter_args) = count_args[0].node; if let ExprKind::MethodCall(ref filter, _, ref filter_args) = count_args[0].node;
if filter.ident.name == "filter"; if filter.ident.name == "filter";
if filter_args.len() == 2; if filter_args.len() == 2;
if let ExprClosure(_, _, body_id, _, _) = filter_args[1].node; if let ExprKind::Closure(_, _, body_id, _, _) = filter_args[1].node;
then { then {
let body = cx.tcx.hir.body(body_id); let body = cx.tcx.hir.body(body_id);
if_chain! { if_chain! {
if body.arguments.len() == 1; if body.arguments.len() == 1;
if let Some(argname) = get_pat_name(&body.arguments[0].pat); if let Some(argname) = get_pat_name(&body.arguments[0].pat);
if let ExprBinary(ref op, ref l, ref r) = body.value.node; if let ExprKind::Binary(ref op, ref l, ref r) = body.value.node;
if op.node == BiEq; if op.node == BinOpKind::Eq;
if match_type(cx, if match_type(cx,
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])), walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])),
&paths::SLICE_ITER); &paths::SLICE_ITER);
@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
if ty::TyUint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty { if ty::TyUint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty {
return; return;
} }
let haystack = if let ExprMethodCall(ref path, _, ref args) = let haystack = if let ExprKind::MethodCall(ref path, _, ref args) =
filter_args[0].node { filter_args[0].node {
let p = path.ident.name; let p = path.ident.name;
if (p == "iter" || p == "iter_mut") && args.len() == 1 { if (p == "iter" || p == "iter_mut") && args.len() == 1 {
@ -98,13 +98,13 @@ fn check_arg(name: Name, arg: Name, needle: &Expr) -> bool {
fn get_path_name(expr: &Expr) -> Option<Name> { fn get_path_name(expr: &Expr) -> Option<Name> {
match expr.node { match expr.node {
ExprBox(ref e) | ExprAddrOf(_, ref e) | ExprUnary(UnOp::UnDeref, ref e) => get_path_name(e), ExprKind::Box(ref e) | ExprKind::AddrOf(_, ref e) | ExprKind::Unary(UnOp::UnDeref, ref e) => get_path_name(e),
ExprBlock(ref b, _) => if b.stmts.is_empty() { ExprKind::Block(ref b, _) => if b.stmts.is_empty() {
b.expr.as_ref().and_then(|p| get_path_name(p)) b.expr.as_ref().and_then(|p| get_path_name(p))
} else { } else {
None None
}, },
ExprPath(ref qpath) => single_segment_path(qpath).map(|ps| ps.ident.name), ExprKind::Path(ref qpath) => single_segment_path(qpath).map(|ps| ps.ident.name),
_ => None, _ => None,
} }
} }

View File

@ -211,25 +211,25 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
/// simple constant folding: Insert an expression, get a constant or none. /// simple constant folding: Insert an expression, get a constant or none.
pub fn expr(&mut self, e: &Expr) -> Option<Constant> { pub fn expr(&mut self, e: &Expr) -> Option<Constant> {
match e.node { match e.node {
ExprPath(ref qpath) => self.fetch_path(qpath, e.hir_id), ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
ExprBlock(ref block, _) => self.block(block), ExprKind::Block(ref block, _) => self.block(block),
ExprIf(ref cond, ref then, ref otherwise) => self.ifthenelse(cond, then, otherwise), ExprKind::If(ref cond, ref then, ref otherwise) => self.ifthenelse(cond, then, otherwise),
ExprLit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))), ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))),
ExprArray(ref vec) => self.multi(vec).map(Constant::Vec), ExprKind::Array(ref vec) => self.multi(vec).map(Constant::Vec),
ExprTup(ref tup) => self.multi(tup).map(Constant::Tuple), ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
ExprRepeat(ref value, _) => { ExprKind::Repeat(ref value, _) => {
let n = match self.tables.expr_ty(e).sty { let n = match self.tables.expr_ty(e).sty {
ty::TyArray(_, n) => n.assert_usize(self.tcx).expect("array length"), ty::TyArray(_, n) => n.assert_usize(self.tcx).expect("array length"),
_ => span_bug!(e.span, "typeck error"), _ => span_bug!(e.span, "typeck error"),
}; };
self.expr(value).map(|v| Constant::Repeat(Box::new(v), n as u64)) self.expr(value).map(|v| Constant::Repeat(Box::new(v), n as u64))
}, },
ExprUnary(op, ref operand) => self.expr(operand).and_then(|o| match op { ExprKind::Unary(op, ref operand) => self.expr(operand).and_then(|o| match op {
UnNot => self.constant_not(&o, self.tables.expr_ty(e)), UnNot => self.constant_not(&o, self.tables.expr_ty(e)),
UnNeg => self.constant_negate(&o, self.tables.expr_ty(e)), UnNeg => self.constant_negate(&o, self.tables.expr_ty(e)),
UnDeref => Some(o), UnDeref => Some(o),
}), }),
ExprBinary(op, ref left, ref right) => self.binop(op, left, right), ExprKind::Binary(op, ref left, ref right) => self.binop(op, left, right),
// TODO: add other expressions // TODO: add other expressions
_ => None, _ => None,
} }
@ -279,7 +279,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
.collect::<Option<_>>() .collect::<Option<_>>()
} }
/// lookup a possibly constant expression from a ExprPath /// lookup a possibly constant expression from a ExprKind::Path
fn fetch_path(&mut self, qpath: &QPath, id: HirId) -> Option<Constant> { fn fetch_path(&mut self, qpath: &QPath, id: HirId) -> Option<Constant> {
let def = self.tables.qpath_def(qpath, id); let def = self.tables.qpath_def(qpath, id);
match def { match def {
@ -340,43 +340,43 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
let r = sext(self.tcx, r, ity); let r = sext(self.tcx, r, ity);
let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity)); let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));
match op.node { match op.node {
BiAdd => l.checked_add(r).map(zext), BinOpKind::Add => l.checked_add(r).map(zext),
BiSub => l.checked_sub(r).map(zext), BinOpKind::Sub => l.checked_sub(r).map(zext),
BiMul => l.checked_mul(r).map(zext), BinOpKind::Mul => l.checked_mul(r).map(zext),
BiDiv if r != 0 => l.checked_div(r).map(zext), BinOpKind::Div if r != 0 => l.checked_div(r).map(zext),
BiRem if r != 0 => l.checked_rem(r).map(zext), BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext),
BiShr => l.checked_shr(r as u128 as u32).map(zext), BinOpKind::Shr => l.checked_shr(r as u128 as u32).map(zext),
BiShl => l.checked_shl(r as u128 as u32).map(zext), BinOpKind::Shl => l.checked_shl(r as u128 as u32).map(zext),
BiBitXor => Some(zext(l ^ r)), BinOpKind::BitXor => Some(zext(l ^ r)),
BiBitOr => Some(zext(l | r)), BinOpKind::BitOr => Some(zext(l | r)),
BiBitAnd => Some(zext(l & r)), BinOpKind::BitAnd => Some(zext(l & r)),
BiEq => Some(Constant::Bool(l == r)), BinOpKind::Eq => Some(Constant::Bool(l == r)),
BiNe => Some(Constant::Bool(l != r)), BinOpKind::Ne => Some(Constant::Bool(l != r)),
BiLt => Some(Constant::Bool(l < r)), BinOpKind::Lt => Some(Constant::Bool(l < r)),
BiLe => Some(Constant::Bool(l <= r)), BinOpKind::Le => Some(Constant::Bool(l <= r)),
BiGe => Some(Constant::Bool(l >= r)), BinOpKind::Ge => Some(Constant::Bool(l >= r)),
BiGt => Some(Constant::Bool(l > r)), BinOpKind::Gt => Some(Constant::Bool(l > r)),
_ => None, _ => None,
} }
} }
ty::TyUint(_) => { ty::TyUint(_) => {
match op.node { match op.node {
BiAdd => l.checked_add(r).map(Constant::Int), BinOpKind::Add => l.checked_add(r).map(Constant::Int),
BiSub => l.checked_sub(r).map(Constant::Int), BinOpKind::Sub => l.checked_sub(r).map(Constant::Int),
BiMul => l.checked_mul(r).map(Constant::Int), BinOpKind::Mul => l.checked_mul(r).map(Constant::Int),
BiDiv => l.checked_div(r).map(Constant::Int), BinOpKind::Div => l.checked_div(r).map(Constant::Int),
BiRem => l.checked_rem(r).map(Constant::Int), BinOpKind::Rem => l.checked_rem(r).map(Constant::Int),
BiShr => l.checked_shr(r as u32).map(Constant::Int), BinOpKind::Shr => l.checked_shr(r as u32).map(Constant::Int),
BiShl => l.checked_shl(r as u32).map(Constant::Int), BinOpKind::Shl => l.checked_shl(r as u32).map(Constant::Int),
BiBitXor => Some(Constant::Int(l ^ r)), BinOpKind::BitXor => Some(Constant::Int(l ^ r)),
BiBitOr => Some(Constant::Int(l | r)), BinOpKind::BitOr => Some(Constant::Int(l | r)),
BiBitAnd => Some(Constant::Int(l & r)), BinOpKind::BitAnd => Some(Constant::Int(l & r)),
BiEq => Some(Constant::Bool(l == r)), BinOpKind::Eq => Some(Constant::Bool(l == r)),
BiNe => Some(Constant::Bool(l != r)), BinOpKind::Ne => Some(Constant::Bool(l != r)),
BiLt => Some(Constant::Bool(l < r)), BinOpKind::Lt => Some(Constant::Bool(l < r)),
BiLe => Some(Constant::Bool(l <= r)), BinOpKind::Le => Some(Constant::Bool(l <= r)),
BiGe => Some(Constant::Bool(l >= r)), BinOpKind::Ge => Some(Constant::Bool(l >= r)),
BiGt => Some(Constant::Bool(l > r)), BinOpKind::Gt => Some(Constant::Bool(l > r)),
_ => None, _ => None,
} }
}, },
@ -384,40 +384,40 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
} }
}, },
(Constant::F32(l), Some(Constant::F32(r))) => match op.node { (Constant::F32(l), Some(Constant::F32(r))) => match op.node {
BiAdd => Some(Constant::F32(l + r)), BinOpKind::Add => Some(Constant::F32(l + r)),
BiSub => Some(Constant::F32(l - r)), BinOpKind::Sub => Some(Constant::F32(l - r)),
BiMul => Some(Constant::F32(l * r)), BinOpKind::Mul => Some(Constant::F32(l * r)),
BiDiv => Some(Constant::F32(l / r)), BinOpKind::Div => Some(Constant::F32(l / r)),
BiRem => Some(Constant::F32(l % r)), BinOpKind::Rem => Some(Constant::F32(l % r)),
BiEq => Some(Constant::Bool(l == r)), BinOpKind::Eq => Some(Constant::Bool(l == r)),
BiNe => Some(Constant::Bool(l != r)), BinOpKind::Ne => Some(Constant::Bool(l != r)),
BiLt => Some(Constant::Bool(l < r)), BinOpKind::Lt => Some(Constant::Bool(l < r)),
BiLe => Some(Constant::Bool(l <= r)), BinOpKind::Le => Some(Constant::Bool(l <= r)),
BiGe => Some(Constant::Bool(l >= r)), BinOpKind::Ge => Some(Constant::Bool(l >= r)),
BiGt => Some(Constant::Bool(l > r)), BinOpKind::Gt => Some(Constant::Bool(l > r)),
_ => None, _ => None,
}, },
(Constant::F64(l), Some(Constant::F64(r))) => match op.node { (Constant::F64(l), Some(Constant::F64(r))) => match op.node {
BiAdd => Some(Constant::F64(l + r)), BinOpKind::Add => Some(Constant::F64(l + r)),
BiSub => Some(Constant::F64(l - r)), BinOpKind::Sub => Some(Constant::F64(l - r)),
BiMul => Some(Constant::F64(l * r)), BinOpKind::Mul => Some(Constant::F64(l * r)),
BiDiv => Some(Constant::F64(l / r)), BinOpKind::Div => Some(Constant::F64(l / r)),
BiRem => Some(Constant::F64(l % r)), BinOpKind::Rem => Some(Constant::F64(l % r)),
BiEq => Some(Constant::Bool(l == r)), BinOpKind::Eq => Some(Constant::Bool(l == r)),
BiNe => Some(Constant::Bool(l != r)), BinOpKind::Ne => Some(Constant::Bool(l != r)),
BiLt => Some(Constant::Bool(l < r)), BinOpKind::Lt => Some(Constant::Bool(l < r)),
BiLe => Some(Constant::Bool(l <= r)), BinOpKind::Le => Some(Constant::Bool(l <= r)),
BiGe => Some(Constant::Bool(l >= r)), BinOpKind::Ge => Some(Constant::Bool(l >= r)),
BiGt => Some(Constant::Bool(l > r)), BinOpKind::Gt => Some(Constant::Bool(l > r)),
_ => None, _ => None,
}, },
(l, r) => match (op.node, l, r) { (l, r) => match (op.node, l, r) {
(BiAnd, Constant::Bool(false), _) => Some(Constant::Bool(false)), (BinOpKind::And, Constant::Bool(false), _) => Some(Constant::Bool(false)),
(BiOr, Constant::Bool(true), _) => Some(Constant::Bool(true)), (BinOpKind::Or, Constant::Bool(true), _) => Some(Constant::Bool(true)),
(BiAnd, Constant::Bool(true), Some(r)) | (BiOr, Constant::Bool(false), Some(r)) => Some(r), (BinOpKind::And, Constant::Bool(true), Some(r)) | (BinOpKind::Or, Constant::Bool(false), Some(r)) => Some(r),
(BiBitXor, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l ^ r)), (BinOpKind::BitXor, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l ^ r)),
(BiBitAnd, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l & r)), (BinOpKind::BitAnd, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l & r)),
(BiBitOr, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l | r)), (BinOpKind::BitOr, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l | r)),
_ => None, _ => None,
}, },
} }

View File

@ -115,7 +115,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste {
if !in_macro(expr.span) { if !in_macro(expr.span) {
// skip ifs directly in else, it will be checked in the parent if // skip ifs directly in else, it will be checked in the parent if
if let Some(&Expr { if let Some(&Expr {
node: ExprIf(_, _, Some(ref else_expr)), node: ExprKind::If(_, _, Some(ref else_expr)),
.. ..
}) = get_parent_expr(cx, expr) }) = get_parent_expr(cx, expr)
{ {
@ -172,7 +172,7 @@ fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) {
/// Implementation of `MATCH_SAME_ARMS`. /// Implementation of `MATCH_SAME_ARMS`.
fn lint_match_arms(cx: &LateContext, expr: &Expr) { fn lint_match_arms(cx: &LateContext, expr: &Expr) {
if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node { if let ExprKind::Match(_, ref arms, MatchSource::Normal) = expr.node {
let hash = |&(_, arm): &(usize, &Arm)| -> u64 { let hash = |&(_, arm): &(usize, &Arm)| -> u64 {
let mut h = SpanlessHash::new(cx, cx.tables); let mut h = SpanlessHash::new(cx, cx.tables);
h.hash_expr(&arm.body); h.hash_expr(&arm.body);
@ -236,12 +236,12 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
let mut conds = SmallVector::new(); let mut conds = SmallVector::new();
let mut blocks: SmallVector<&Block> = SmallVector::new(); let mut blocks: SmallVector<&Block> = SmallVector::new();
while let ExprIf(ref cond, ref then_expr, ref else_expr) = expr.node { while let ExprKind::If(ref cond, ref then_expr, ref else_expr) = expr.node {
conds.push(&**cond); conds.push(&**cond);
if let ExprBlock(ref block, _) = then_expr.node { if let ExprKind::Block(ref block, _) = then_expr.node {
blocks.push(block); blocks.push(block);
} else { } else {
panic!("ExprIf node is not an ExprBlock"); panic!("ExprKind::If node is not an ExprKind::Block");
} }
if let Some(ref else_expr) = *else_expr { if let Some(ref else_expr) = *else_expr {
@ -253,7 +253,7 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
// final `else {..}` // final `else {..}`
if !blocks.is_empty() { if !blocks.is_empty() {
if let ExprBlock(ref block, _) = expr.node { if let ExprKind::Block(ref block, _) = expr.node {
blocks.push(&**block); blocks.push(&**block);
} }
} }

View File

@ -147,14 +147,14 @@ struct CCHelper<'a, 'tcx: 'a> {
impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
fn visit_expr(&mut self, e: &'tcx Expr) { fn visit_expr(&mut self, e: &'tcx Expr) {
match e.node { match e.node {
ExprMatch(_, ref arms, _) => { ExprKind::Match(_, ref arms, _) => {
walk_expr(self, e); walk_expr(self, e);
let arms_n: u64 = arms.iter().map(|arm| arm.pats.len() as u64).sum(); let arms_n: u64 = arms.iter().map(|arm| arm.pats.len() as u64).sum();
if arms_n > 1 { if arms_n > 1 {
self.match_arms += arms_n - 2; self.match_arms += arms_n - 2;
} }
}, },
ExprCall(ref callee, _) => { ExprKind::Call(ref callee, _) => {
walk_expr(self, e); walk_expr(self, e);
let ty = self.cx.tables.node_id_to_type(callee.hir_id); let ty = self.cx.tables.node_id_to_type(callee.hir_id);
match ty.sty { match ty.sty {
@ -167,15 +167,15 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
_ => (), _ => (),
} }
}, },
ExprClosure(.., _) => (), ExprKind::Closure(.., _) => (),
ExprBinary(op, _, _) => { ExprKind::Binary(op, _, _) => {
walk_expr(self, e); walk_expr(self, e);
match op.node { match op.node {
BiAnd | BiOr => self.short_circuits += 1, BinOpKind::And | BinOpKind::Or => self.short_circuits += 1,
_ => (), _ => (),
} }
}, },
ExprRet(_) => self.returns += 1, ExprKind::Ret(_) => self.returns += 1,
_ => walk_expr(self, e), _ => walk_expr(self, e),
} }
} }

View File

@ -38,9 +38,9 @@ impl LintPass for DefaultTraitAccess {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
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_chain! { if_chain! {
if let ExprCall(ref path, ..) = expr.node; if let ExprKind::Call(ref path, ..) = expr.node;
if !any_parent_is_automatically_derived(cx.tcx, expr.id); if !any_parent_is_automatically_derived(cx.tcx, expr.id);
if let ExprPath(ref qpath) = path.node; if let ExprKind::Path(ref qpath) = path.node;
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)); if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
if match_def_path(cx.tcx, def_id, &paths::DEFAULT_TRAIT_METHOD); if match_def_path(cx.tcx, def_id, &paths::DEFAULT_TRAIT_METHOD);
then { then {

View File

@ -70,7 +70,7 @@ impl LintPass for Derive {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive {
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 let ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node { if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node {
let ty = cx.tcx.type_of(cx.tcx.hir.local_def_id(item.id)); let ty = cx.tcx.type_of(cx.tcx.hir.local_def_id(item.id));
let is_automatically_derived = is_automatically_derived(&*item.attrs); let is_automatically_derived = is_automatically_derived(&*item.attrs);

View File

@ -41,13 +41,13 @@ impl<'a, 'tcx> DoubleComparisonPass {
fn check_binop( fn check_binop(
&self, &self,
cx: &LateContext<'a, 'tcx>, cx: &LateContext<'a, 'tcx>,
op: BinOp_, op: BinOpKind,
lhs: &'tcx Expr, lhs: &'tcx Expr,
rhs: &'tcx Expr, rhs: &'tcx Expr,
span: Span, span: Span,
) { ) {
let (lkind, llhs, lrhs, rkind, rlhs, rrhs) = match (lhs.node.clone(), rhs.node.clone()) { let (lkind, llhs, lrhs, rkind, rlhs, rrhs) = match (lhs.node.clone(), rhs.node.clone()) {
(ExprBinary(lb, llhs, lrhs), ExprBinary(rb, rlhs, rrhs)) => { (ExprKind::Binary(lb, llhs, lrhs), ExprKind::Binary(rb, rlhs, rrhs)) => {
(lb.node, llhs, lrhs, rb.node, rlhs, rrhs) (lb.node, llhs, lrhs, rb.node, rlhs, rrhs)
} }
_ => return, _ => return,
@ -67,10 +67,10 @@ impl<'a, 'tcx> DoubleComparisonPass {
}} }}
} }
match (op, lkind, rkind) { match (op, lkind, rkind) {
(BiOr, BiEq, BiLt) | (BiOr, BiLt, BiEq) => lint_double_comparison!(<=), (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Lt) | (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Eq) => lint_double_comparison!(<=),
(BiOr, BiEq, BiGt) | (BiOr, BiGt, BiEq) => lint_double_comparison!(>=), (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Eq) => lint_double_comparison!(>=),
(BiOr, BiLt, BiGt) | (BiOr, BiGt, BiLt) => lint_double_comparison!(!=), (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Lt) => lint_double_comparison!(!=),
(BiAnd, BiLe, BiGe) | (BiAnd, BiGe, BiLe) => lint_double_comparison!(==), (BinOpKind::And, BinOpKind::Le, BinOpKind::Ge) | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Le) => lint_double_comparison!(==),
_ => (), _ => (),
}; };
} }
@ -78,7 +78,7 @@ impl<'a, 'tcx> DoubleComparisonPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DoubleComparisonPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DoubleComparisonPass {
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 ExprBinary(ref kind, ref lhs, ref rhs) = expr.node { if let ExprKind::Binary(ref kind, ref lhs, ref rhs) = expr.node {
self.check_binop(cx, kind.node, lhs, rhs, expr.span); self.check_binop(cx, kind.node, lhs, rhs, expr.span);
} }
} }

View File

@ -116,8 +116,8 @@ 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_chain! { if_chain! {
if let ExprCall(ref path, ref args) = expr.node; if let ExprKind::Call(ref path, ref args) = expr.node;
if let ExprPath(ref qpath) = path.node; if let ExprKind::Path(ref qpath) = path.node;
if args.len() == 1; if args.len() == 1;
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)); if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
then { then {

View File

@ -38,8 +38,8 @@ impl LintPass for DurationSubsec {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec {
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_chain! { if_chain! {
if let ExprBinary(Spanned { node: BiDiv, .. }, ref left, ref right) = expr.node; if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.node;
if let ExprMethodCall(ref method_path, _ , ref args) = left.node; if let ExprKind::MethodCall(ref method_path, _ , ref args) = left.node;
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION); if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION);
if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right); if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right);
then { then {

View File

@ -34,7 +34,7 @@ impl LintPass for EmptyEnum {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum {
fn check_item(&mut self, cx: &LateContext, item: &Item) { fn check_item(&mut self, cx: &LateContext, item: &Item) {
let did = cx.tcx.hir.local_def_id(item.id); let did = cx.tcx.hir.local_def_id(item.id);
if let ItemEnum(..) = item.node { if let ItemKind::Enum(..) = item.node {
let ty = cx.tcx.type_of(did); let ty = cx.tcx.type_of(did);
let adt = ty.ty_adt_def() let adt = ty.ty_adt_def()
.expect("already checked whether this is an enum"); .expect("already checked whether this is an enum");

View File

@ -41,13 +41,13 @@ impl LintPass for HashMapLint {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint {
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 ExprIf(ref check, ref then_block, ref else_block) = expr.node { if let ExprKind::If(ref check, ref then_block, ref else_block) = expr.node {
if let ExprUnary(UnOp::UnNot, ref check) = check.node { if let ExprKind::Unary(UnOp::UnNot, ref check) = check.node {
if let Some((ty, map, key)) = check_cond(cx, check) { if let Some((ty, map, key)) = check_cond(cx, check) {
// in case of `if !m.contains_key(&k) { m.insert(k, v); }` // in case of `if !m.contains_key(&k) { m.insert(k, v); }`
// we can give a better error message // we can give a better error message
let sole_expr = { let sole_expr = {
else_block.is_none() && if let ExprBlock(ref then_block, _) = then_block.node { else_block.is_none() && if let ExprKind::Block(ref then_block, _) = then_block.node {
(then_block.expr.is_some() as usize) + then_block.stmts.len() == 1 (then_block.expr.is_some() as usize) + then_block.stmts.len() == 1
} else { } else {
true true
@ -88,10 +88,10 @@ fn check_cond<'a, 'tcx, 'b>(
check: &'b Expr, check: &'b Expr,
) -> Option<(&'static str, &'b Expr, &'b Expr)> { ) -> Option<(&'static str, &'b Expr, &'b Expr)> {
if_chain! { if_chain! {
if let ExprMethodCall(ref path, _, ref params) = check.node; if let ExprKind::MethodCall(ref path, _, ref params) = check.node;
if params.len() >= 2; if params.len() >= 2;
if path.ident.name == "contains_key"; if path.ident.name == "contains_key";
if let ExprAddrOf(_, ref key) = params[1].node; if let ExprKind::AddrOf(_, ref key) = params[1].node;
then { then {
let map = &params[0]; let map = &params[0];
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map)); let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map));
@ -123,7 +123,7 @@ struct InsertVisitor<'a, 'tcx: 'a, 'b> {
impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> { impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
fn visit_expr(&mut self, expr: &'tcx Expr) { fn visit_expr(&mut self, expr: &'tcx Expr) {
if_chain! { if_chain! {
if let ExprMethodCall(ref path, _, ref params) = expr.node; if let ExprKind::MethodCall(ref path, _, ref params) = expr.node;
if params.len() == 3; if params.len() == 3;
if path.ident.name == "insert"; if path.ident.name == "insert";
if get_item_name(self.cx, self.map) == get_item_name(self.cx, &params[0]); if get_item_name(self.cx, self.map) == get_item_name(self.cx, &params[0]);

View File

@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant {
if cx.tcx.data_layout.pointer_size.bits() != 64 { if cx.tcx.data_layout.pointer_size.bits() != 64 {
return; return;
} }
if let ItemEnum(ref def, _) = item.node { if let ItemKind::Enum(ref def, _) = item.node {
for var in &def.variants { for var in &def.variants {
let variant = &var.node; let variant = &var.node;
if let Some(ref anon_const) = variant.disr_expr { if let Some(ref anon_const) = variant.disr_expr {

View File

@ -47,7 +47,7 @@ impl EnumGlobUse {
if item.vis.node.is_pub() { if item.vis.node.is_pub() {
return; // re-exports are fine return; // re-exports are fine
} }
if let ItemUse(ref path, UseKind::Glob) = item.node { if let ItemKind::Use(ref path, UseKind::Glob) = item.node {
if let Def::Enum(_) = path.def { if let Def::Enum(_) = path.def {
span_lint( span_lint(
cx, cx,

View File

@ -52,7 +52,7 @@ impl LintPass for EqOp {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
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 ExprBinary(op, ref left, ref right) = e.node { if let ExprKind::Binary(op, ref left, ref right) = e.node {
if in_macro(e.span) { if in_macro(e.span) {
return; return;
} }
@ -66,28 +66,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
return; return;
} }
let (trait_id, requires_ref) = match op.node { let (trait_id, requires_ref) = match op.node {
BiAdd => (cx.tcx.lang_items().add_trait(), false), BinOpKind::Add => (cx.tcx.lang_items().add_trait(), false),
BiSub => (cx.tcx.lang_items().sub_trait(), false), BinOpKind::Sub => (cx.tcx.lang_items().sub_trait(), false),
BiMul => (cx.tcx.lang_items().mul_trait(), false), BinOpKind::Mul => (cx.tcx.lang_items().mul_trait(), false),
BiDiv => (cx.tcx.lang_items().div_trait(), false), BinOpKind::Div => (cx.tcx.lang_items().div_trait(), false),
BiRem => (cx.tcx.lang_items().rem_trait(), false), BinOpKind::Rem => (cx.tcx.lang_items().rem_trait(), false),
// don't lint short circuiting ops // don't lint short circuiting ops
BiAnd | BiOr => return, BinOpKind::And | BinOpKind::Or => return,
BiBitXor => (cx.tcx.lang_items().bitxor_trait(), false), BinOpKind::BitXor => (cx.tcx.lang_items().bitxor_trait(), false),
BiBitAnd => (cx.tcx.lang_items().bitand_trait(), false), BinOpKind::BitAnd => (cx.tcx.lang_items().bitand_trait(), false),
BiBitOr => (cx.tcx.lang_items().bitor_trait(), false), BinOpKind::BitOr => (cx.tcx.lang_items().bitor_trait(), false),
BiShl => (cx.tcx.lang_items().shl_trait(), false), BinOpKind::Shl => (cx.tcx.lang_items().shl_trait(), false),
BiShr => (cx.tcx.lang_items().shr_trait(), false), BinOpKind::Shr => (cx.tcx.lang_items().shr_trait(), false),
BiNe | BiEq => (cx.tcx.lang_items().eq_trait(), true), BinOpKind::Ne | BinOpKind::Eq => (cx.tcx.lang_items().eq_trait(), true),
BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items().ord_trait(), true), BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => (cx.tcx.lang_items().ord_trait(), true),
}; };
if let Some(trait_id) = trait_id { if let Some(trait_id) = trait_id {
#[allow(match_same_arms)] #[allow(match_same_arms)]
match (&left.node, &right.node) { match (&left.node, &right.node) {
// do not suggest to dereference literals // do not suggest to dereference literals
(&ExprLit(..), _) | (_, &ExprLit(..)) => {}, (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
// &foo == &bar // &foo == &bar
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => { (&ExprKind::AddrOf(_, ref l), &ExprKind::AddrOf(_, ref r)) => {
let lty = cx.tables.expr_ty(l); let lty = cx.tables.expr_ty(l);
let rty = cx.tables.expr_ty(r); let rty = cx.tables.expr_ty(r);
let lcpy = is_copy(cx, lty); let lcpy = is_copy(cx, lty);
@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
} }
}, },
// &foo == bar // &foo == bar
(&ExprAddrOf(_, ref l), _) => { (&ExprKind::AddrOf(_, ref l), _) => {
let lty = cx.tables.expr_ty(l); let lty = cx.tables.expr_ty(l);
let lcpy = is_copy(cx, lty); let lcpy = is_copy(cx, lty);
if (requires_ref || lcpy) && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) { if (requires_ref || lcpy) && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) {
@ -139,7 +139,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
} }
}, },
// foo == &bar // foo == &bar
(_, &ExprAddrOf(_, ref r)) => { (_, &ExprKind::AddrOf(_, ref r)) => {
let rty = cx.tables.expr_ty(r); let rty = cx.tables.expr_ty(r);
let rcpy = is_copy(cx, rty); let rcpy = is_copy(cx, rty);
if (requires_ref || rcpy) && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) { if (requires_ref || rcpy) && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) {
@ -159,7 +159,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
fn is_valid_operator(op: BinOp) -> bool { fn is_valid_operator(op: BinOp) -> bool {
match op.node { match op.node {
BiSub | BiDiv | BiEq | BiLt | BiLe | BiGt | BiGe | BiNe | BiAnd | BiOr | BiBitXor | BiBitAnd | BiBitOr => true, BinOpKind::Sub | BinOpKind::Div | BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge | BinOpKind::Ne | BinOpKind::And | BinOpKind::Or | BinOpKind::BitXor | BinOpKind::BitAnd | BinOpKind::BitOr => true,
_ => false, _ => false,
} }
} }

View File

@ -36,13 +36,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp {
if in_macro(e.span) { if in_macro(e.span) {
return; return;
} }
if let ExprBinary(ref cmp, ref left, ref right) = e.node { if let ExprKind::Binary(ref cmp, ref left, ref right) = e.node {
match cmp.node { match cmp.node {
BiMul | BiBitAnd => { BinOpKind::Mul | BinOpKind::BitAnd => {
check(cx, left, e.span); check(cx, left, e.span);
check(cx, right, e.span); check(cx, right, e.span);
}, },
BiDiv => check(cx, left, e.span), BinOpKind::Div => check(cx, left, e.span),
_ => (), _ => (),
} }
} }

View File

@ -110,10 +110,10 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
if let Categorization::Rvalue(..) = cmt.cat { if let Categorization::Rvalue(..) = cmt.cat {
let id = map.hir_to_node_id(cmt.hir_id); let id = map.hir_to_node_id(cmt.hir_id);
if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) { if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) {
if let StmtDecl(ref decl, _) = st.node { if let StmtKind::Decl(ref decl, _) = st.node {
if let DeclLocal(ref loc) = decl.node { if let DeclKind::Local(ref loc) = decl.node {
if let Some(ref ex) = loc.init { if let Some(ref ex) = loc.init {
if let ExprBox(..) = ex.node { if let ExprKind::Box(..) = ex.node {
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) { if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
// let x = box (...) // let x = box (...)
self.set.insert(consume_pat.id); self.set.insert(consume_pat.id);

View File

@ -37,7 +37,7 @@ impl LintPass for EtaPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
match expr.node { match expr.node {
ExprCall(_, ref args) | ExprMethodCall(_, _, ref args) => for arg in args { ExprKind::Call(_, ref args) | ExprKind::MethodCall(_, _, ref args) => for arg in args {
check_closure(cx, arg) check_closure(cx, arg)
}, },
_ => (), _ => (),
@ -46,10 +46,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass {
} }
fn check_closure(cx: &LateContext, expr: &Expr) { fn check_closure(cx: &LateContext, expr: &Expr) {
if let ExprClosure(_, ref decl, eid, _, _) = expr.node { if let ExprKind::Closure(_, ref decl, eid, _, _) = expr.node {
let body = cx.tcx.hir.body(eid); let body = cx.tcx.hir.body(eid);
let ex = &body.value; let ex = &body.value;
if let ExprCall(ref caller, ref args) = ex.node { if let ExprKind::Call(ref caller, ref args) = ex.node {
if args.len() != decl.inputs.len() { if args.len() != decl.inputs.len() {
// Not the same number of arguments, there // Not the same number of arguments, there
// is no way the closure is the same as the function // is no way the closure is the same as the function
@ -73,7 +73,7 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
for (a1, a2) in iter_input_pats(decl, body).zip(args) { for (a1, a2) in iter_input_pats(decl, body).zip(args) {
if let PatKind::Binding(_, _, ident, _) = a1.pat.node { if let PatKind::Binding(_, _, ident, _) = a1.pat.node {
// XXXManishearth Should I be checking the binding mode here? // XXXManishearth Should I be checking the binding mode here?
if let ExprPath(QPath::Resolved(None, ref p)) = a2.node { if let ExprKind::Path(QPath::Resolved(None, ref p)) = a2.node {
if p.segments.len() != 1 { if p.segments.len() != 1 {
// If it's a proper path, it can't be a local variable // If it's a proper path, it can't be a local variable
return; return;

View File

@ -62,7 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
// Find a write to a local variable. // Find a write to a local variable.
match expr.node { match expr.node {
ExprAssign(ref lhs, _) | ExprAssignOp(_, ref lhs, _) => if let ExprPath(ref qpath) = lhs.node { ExprKind::Assign(ref lhs, _) | ExprKind::AssignOp(_, ref lhs, _) => if let ExprKind::Path(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 {
if let def::Def::Local(var) = cx.tables.qpath_def(qpath, lhs.hir_id) { if let def::Def::Local(var) = cx.tables.qpath_def(qpath, lhs.hir_id) {
@ -82,8 +82,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence {
} }
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
match stmt.node { match stmt.node {
StmtExpr(ref e, _) | StmtSemi(ref e, _) => DivergenceVisitor { cx }.maybe_walk_expr(e), StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => DivergenceVisitor { cx }.maybe_walk_expr(e),
StmtDecl(ref d, _) => if let DeclLocal(ref local) = d.node { StmtKind::Decl(ref d, _) => if let DeclKind::Local(ref local) = d.node {
if let Local { if let Local {
init: Some(ref e), .. init: Some(ref e), ..
} = **local } = **local
@ -102,8 +102,8 @@ struct DivergenceVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
fn maybe_walk_expr(&mut self, e: &'tcx Expr) { fn maybe_walk_expr(&mut self, e: &'tcx Expr) {
match e.node { match e.node {
ExprClosure(.., _) => {}, ExprKind::Closure(.., _) => {},
ExprMatch(ref e, ref arms, _) => { ExprKind::Match(ref e, ref arms, _) => {
self.visit_expr(e); self.visit_expr(e);
for arm in arms { for arm in arms {
if let Some(ref guard) = arm.guard { if let Some(ref guard) = arm.guard {
@ -124,8 +124,8 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
fn visit_expr(&mut self, e: &'tcx Expr) { fn visit_expr(&mut self, e: &'tcx Expr) {
match e.node { match e.node {
ExprContinue(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e), ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e),
ExprCall(ref func, _) => { ExprKind::Call(ref func, _) => {
let typ = self.cx.tables.expr_ty(func); let typ = self.cx.tables.expr_ty(func);
match typ.sty { match typ.sty {
ty::TyFnDef(..) | ty::TyFnPtr(_) => { ty::TyFnDef(..) | ty::TyFnPtr(_) => {
@ -137,7 +137,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
_ => {}, _ => {},
} }
}, },
ExprMethodCall(..) => { ExprKind::MethodCall(..) => {
let borrowed_table = self.cx.tables; let borrowed_table = self.cx.tables;
if borrowed_table.expr_ty(e).is_never() { if borrowed_table.expr_ty(e).is_never() {
self.report_diverging_sub_expr(e); self.report_diverging_sub_expr(e);
@ -218,25 +218,25 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr) -> St
} }
match expr.node { match expr.node {
ExprArray(_) | ExprKind::Array(_) |
ExprTup(_) | ExprKind::Tup(_) |
ExprMethodCall(..) | ExprKind::MethodCall(..) |
ExprCall(_, _) | ExprKind::Call(_, _) |
ExprAssign(_, _) | ExprKind::Assign(_, _) |
ExprIndex(_, _) | ExprKind::Index(_, _) |
ExprRepeat(_, _) | ExprKind::Repeat(_, _) |
ExprStruct(_, _, _) => { ExprKind::Struct(_, _, _) => {
walk_expr(vis, expr); walk_expr(vis, expr);
}, },
ExprBinary(op, _, _) | ExprAssignOp(op, _, _) => { ExprKind::Binary(op, _, _) | ExprKind::AssignOp(op, _, _) => {
if op.node == BiAnd || op.node == BiOr { if op.node == BinOpKind::And || op.node == BinOpKind::Or {
// x && y and x || y always evaluate x first, so these are // x && y and x || y always evaluate x first, so these are
// strictly sequenced. // strictly sequenced.
} else { } else {
walk_expr(vis, expr); walk_expr(vis, expr);
} }
}, },
ExprClosure(_, _, _, _, _) => { ExprKind::Closure(_, _, _, _, _) => {
// Either // Either
// //
// * `var` is defined in the closure body, in which case we've // * `var` is defined in the closure body, in which case we've
@ -262,12 +262,12 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr) -> St
fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> StopEarly { fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> StopEarly {
match stmt.node { match stmt.node {
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => check_expr(vis, expr), StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => check_expr(vis, expr),
StmtDecl(ref decl, _) => { StmtKind::Decl(ref decl, _) => {
// If the declaration is of a local variable, check its initializer // If the declaration is of a local variable, check its initializer
// expression if it has one. Otherwise, keep going. // expression if it has one. Otherwise, keep going.
let local = match decl.node { let local = match decl.node {
DeclLocal(ref local) => Some(local), DeclKind::Local(ref local) => Some(local),
_ => None, _ => None,
}; };
local local
@ -297,7 +297,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
} }
match expr.node { match expr.node {
ExprPath(ref qpath) => { ExprKind::Path(ref qpath) => {
if_chain! { if_chain! {
if let QPath::Resolved(None, ref path) = *qpath; if let QPath::Resolved(None, ref path) = *qpath;
if path.segments.len() == 1; if path.segments.len() == 1;
@ -320,7 +320,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
// We're about to descend a closure. Since we don't know when (or // We're about to descend a closure. Since we don't know when (or
// if) the closure will be evaluated, any reads in it might not // if) the closure will be evaluated, any reads in it might not
// occur here (or ever). Like above, bail to avoid false positives. // occur here (or ever). Like above, bail to avoid false positives.
ExprClosure(_, _, _, _, _) | ExprKind::Closure(_, _, _, _, _) |
// We want to avoid a false positive when a variable name occurs // We want to avoid a false positive when a variable name occurs
// only to have its address taken, so we stop here. Technically, // only to have its address taken, so we stop here. Technically,
@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
// ``` // ```
// //
// TODO: fix this // TODO: fix this
ExprAddrOf(_, _) => { ExprKind::AddrOf(_, _) => {
return; return;
} }
_ => {} _ => {}
@ -348,7 +348,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
/// Returns true if `expr` is the LHS of an assignment, like `expr = ...`. /// Returns true if `expr` is the LHS of an assignment, like `expr = ...`.
fn is_in_assignment_position(cx: &LateContext, expr: &Expr) -> bool { fn is_in_assignment_position(cx: &LateContext, expr: &Expr) -> bool {
if let Some(parent) = get_parent_expr(cx, expr) { if let Some(parent) = get_parent_expr(cx, expr) {
if let ExprAssign(ref lhs, _) = parent.node { if let ExprKind::Assign(ref lhs, _) = parent.node {
return lhs.id == expr.id; return lhs.id == expr.id;
} }
} }

View File

@ -45,7 +45,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision {
if_chain! { if_chain! {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables.expr_ty(expr);
if let TypeVariants::TyFloat(fty) = ty.sty; if let TypeVariants::TyFloat(fty) = ty.sty;
if let hir::ExprLit(ref lit) = expr.node; if let hir::ExprKind::Lit(ref lit) = expr.node;
if let LitKind::Float(sym, _) | LitKind::FloatUnsuffixed(sym) = lit.node; if let LitKind::Float(sym, _) | LitKind::FloatUnsuffixed(sym) = lit.node;
if let Some(sugg) = self.check(sym, fty); if let Some(sugg) = self.check(sym, fty);
then { then {

View File

@ -35,17 +35,17 @@ 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_chain! { if_chain! {
// match call to unwrap // match call to unwrap
if let ExprMethodCall(ref unwrap_fun, _, ref unwrap_args) = expr.node; if let ExprKind::MethodCall(ref unwrap_fun, _, ref unwrap_args) = expr.node;
if unwrap_fun.ident.name == "unwrap"; if unwrap_fun.ident.name == "unwrap";
// match call to write_fmt // match call to write_fmt
if unwrap_args.len() > 0; if unwrap_args.len() > 0;
if let ExprMethodCall(ref write_fun, _, ref write_args) = if let ExprKind::MethodCall(ref write_fun, _, ref write_args) =
unwrap_args[0].node; unwrap_args[0].node;
if write_fun.ident.name == "write_fmt"; if write_fun.ident.name == "write_fmt";
// match calls to std::io::stdout() / std::io::stderr () // match calls to std::io::stdout() / std::io::stderr ()
if write_args.len() > 0; if write_args.len() > 0;
if let ExprCall(ref dest_fun, _) = write_args[0].node; if let ExprKind::Call(ref dest_fun, _) = write_args[0].node;
if let ExprPath(ref qpath) = dest_fun.node; if let ExprKind::Path(ref qpath) = dest_fun.node;
if let Some(dest_fun_id) = if let Some(dest_fun_id) =
opt_def_id(resolve_node(cx, qpath, dest_fun.hir_id)); opt_def_id(resolve_node(cx, qpath, dest_fun.hir_id));
if let Some(dest_name) = if match_def_path(cx.tcx, dest_fun_id, &["std", "io", "stdio", "stdout"]) { if let Some(dest_name) = if match_def_path(cx.tcx, dest_fun_id, &["std", "io", "stdio", "stdout"]) {

View File

@ -39,7 +39,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FallibleImplFrom {
// check for `impl From<???> for ..` // check for `impl From<???> for ..`
let impl_def_id = cx.tcx.hir.local_def_id(item.id); let impl_def_id = cx.tcx.hir.local_def_id(item.id);
if_chain! { if_chain! {
if let hir::ItemImpl(.., ref impl_items) = item.node; if let hir::ItemKind::Impl(.., ref impl_items) = item.node;
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id); if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id);
if match_def_path(cx.tcx, impl_trait_ref.def_id, &FROM_TRAIT); if match_def_path(cx.tcx, impl_trait_ref.def_id, &FROM_TRAIT);
then { then {
@ -63,8 +63,8 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
fn visit_expr(&mut self, expr: &'tcx Expr) { fn visit_expr(&mut self, expr: &'tcx Expr) {
// check for `begin_panic` // check for `begin_panic`
if_chain! { if_chain! {
if let ExprCall(ref func_expr, _) = expr.node; if let ExprKind::Call(ref func_expr, _) = expr.node;
if let ExprPath(QPath::Resolved(_, ref path)) = func_expr.node; if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.node;
if let Some(path_def_id) = opt_def_id(path.def); if let Some(path_def_id) = opt_def_id(path.def);
if match_def_path(self.tcx, path_def_id, &BEGIN_PANIC) || if match_def_path(self.tcx, path_def_id, &BEGIN_PANIC) ||
match_def_path(self.tcx, path_def_id, &BEGIN_PANIC_FMT); match_def_path(self.tcx, path_def_id, &BEGIN_PANIC_FMT);

View File

@ -46,9 +46,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
match expr.node { match expr.node {
// `format!("{}", foo)` expansion // `format!("{}", foo)` expansion
ExprCall(ref fun, ref args) => { ExprKind::Call(ref fun, ref args) => {
if_chain! { if_chain! {
if let ExprPath(ref qpath) = fun.node; if let ExprKind::Path(ref qpath) = fun.node;
if args.len() == 3; if args.len() == 3;
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)); if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
if match_def_path(cx.tcx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED); if match_def_path(cx.tcx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED);
@ -64,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
}, },
// `format!("foo")` expansion contains `match () { () => [], }` // `format!("foo")` expansion contains `match () { () => [], }`
ExprMatch(ref matchee, _, _) => if let ExprTup(ref tup) = matchee.node { ExprKind::Match(ref matchee, _, _) => if let ExprKind::Tup(ref tup) = matchee.node {
if tup.is_empty() { if tup.is_empty() {
let sugg = format!("{}.to_string()", snippet(cx, expr.span, "<expr>").into_owned()); let sugg = format!("{}.to_string()", snippet(cx, expr.span, "<expr>").into_owned());
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| { span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
@ -81,10 +81,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
/// Checks if the expressions matches `&[""]` /// Checks if the expressions matches `&[""]`
fn check_single_piece(expr: &Expr) -> bool { fn check_single_piece(expr: &Expr) -> bool {
if_chain! { if_chain! {
if let ExprAddrOf(_, ref expr) = expr.node; // &[""] if let ExprKind::AddrOf(_, ref expr) = expr.node; // &[""]
if let ExprArray(ref exprs) = expr.node; // [""] if let ExprKind::Array(ref exprs) = expr.node; // [""]
if exprs.len() == 1; if exprs.len() == 1;
if let ExprLit(ref lit) = exprs[0].node; if let ExprKind::Lit(ref lit) = exprs[0].node;
if let LitKind::Str(ref lit, _) = lit.node; if let LitKind::Str(ref lit, _) = lit.node;
then { then {
return lit.as_str().is_empty(); return lit.as_str().is_empty();
@ -105,23 +105,23 @@ fn check_single_piece(expr: &Expr) -> bool {
/// then returns the span of first element of the matched tuple /// then returns the span of first element of the matched tuple
fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> { fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> {
if_chain! { if_chain! {
if let ExprAddrOf(_, ref expr) = expr.node; if let ExprKind::AddrOf(_, ref expr) = expr.node;
if let ExprMatch(ref match_expr, ref arms, _) = expr.node; if let ExprKind::Match(ref match_expr, ref arms, _) = expr.node;
if arms.len() == 1; if arms.len() == 1;
if arms[0].pats.len() == 1; if arms[0].pats.len() == 1;
if let PatKind::Tuple(ref pat, None) = arms[0].pats[0].node; if let PatKind::Tuple(ref pat, None) = arms[0].pats[0].node;
if pat.len() == 1; if pat.len() == 1;
if let ExprArray(ref exprs) = arms[0].body.node; if let ExprKind::Array(ref exprs) = arms[0].body.node;
if exprs.len() == 1; if exprs.len() == 1;
if let ExprCall(_, ref args) = exprs[0].node; if let ExprKind::Call(_, ref args) = exprs[0].node;
if args.len() == 2; if args.len() == 2;
if let ExprPath(ref qpath) = args[1].node; if let ExprKind::Path(ref qpath) = args[1].node;
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, args[1].hir_id)); if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, args[1].hir_id));
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD); if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
then { then {
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0])); let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
if ty.sty == ty::TyStr || match_type(cx, ty, &paths::STRING) { if ty.sty == ty::TyStr || match_type(cx, ty, &paths::STRING) {
if let ExprTup(ref values) = match_expr.node { if let ExprKind::Tup(ref values) = match_expr.node {
return Some(values[0].span); return Some(values[0].span);
} }
} }
@ -143,14 +143,14 @@ fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> {
/// ``` /// ```
fn check_unformatted(expr: &Expr) -> bool { fn check_unformatted(expr: &Expr) -> bool {
if_chain! { if_chain! {
if let ExprAddrOf(_, ref expr) = expr.node; if let ExprKind::AddrOf(_, ref expr) = expr.node;
if let ExprArray(ref exprs) = expr.node; if let ExprKind::Array(ref exprs) = expr.node;
if exprs.len() == 1; if exprs.len() == 1;
if let ExprStruct(_, ref fields, _) = exprs[0].node; if let ExprKind::Struct(_, ref fields, _) = exprs[0].node;
if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format"); if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format");
if let ExprStruct(_, ref fields, _) = format_field.expr.node; if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node;
if let Some(align_field) = fields.iter().find(|f| f.ident.name == "width"); if let Some(align_field) = fields.iter().find(|f| f.ident.name == "width");
if let ExprPath(ref qpath) = align_field.expr.node; if let ExprKind::Path(ref qpath) = align_field.expr.node;
if last_path_segment(qpath).ident.name == "Implied"; if last_path_segment(qpath).ident.name == "Implied";
then { then {
return true; return true;

View File

@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
use rustc::hir::map::Node::*; use rustc::hir::map::Node::*;
let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) { let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
matches!(item.node, hir::ItemImpl(_, _, _, _, Some(_), _, _)) matches!(item.node, hir::ItemKind::Impl(_, _, _, _, Some(_), _, _))
} else { } else {
false false
}; };
@ -168,7 +168,7 @@ impl<'a, 'tcx> Functions {
} }
fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<ast::NodeId> { fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<ast::NodeId> {
if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &ty.node) { if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyKind::Ptr(_)) = (&arg.pat.node, &ty.node) {
Some(id) Some(id)
} else { } else {
None None
@ -184,7 +184,7 @@ struct DerefVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> { 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::ExprKind::Call(ref f, ref args) => {
let ty = self.tables.expr_ty(f); let ty = self.tables.expr_ty(f);
if type_is_unsafe_function(self.cx, ty) { if type_is_unsafe_function(self.cx, ty) {
@ -193,7 +193,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
} }
} }
}, },
hir::ExprMethodCall(_, _, ref args) => { hir::ExprKind::MethodCall(_, _, ref args) => {
let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id(); let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id();
let base_type = self.cx.tcx.type_of(def_id); let base_type = self.cx.tcx.type_of(def_id);
@ -203,7 +203,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
} }
} }
}, },
hir::ExprUnary(hir::UnDeref, ref ptr) => self.check_arg(ptr), hir::ExprKind::Unary(hir::UnDeref, ref ptr) => self.check_arg(ptr),
_ => (), _ => (),
} }
@ -216,7 +216,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::ExprKind::Path(ref qpath) = ptr.node {
if let Def::Local(id) = self.cx.tables.qpath_def(qpath, ptr.hir_id) { if let Def::Local(id) = self.cx.tables.qpath_def(qpath, ptr.hir_id) {
if self.ptrs.contains(&id) { if self.ptrs.contains(&id) {
span_lint( span_lint(

View File

@ -43,19 +43,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
} }
match e.node { match e.node {
ExprMatch(_, ref arms, MatchSource::TryDesugar) => { ExprKind::Match(_, ref arms, MatchSource::TryDesugar) => {
let e = match arms[0].body.node { let e = match arms[0].body.node {
ExprRet(Some(ref e)) | ExprBreak(_, Some(ref e)) => e, ExprKind::Ret(Some(ref e)) | ExprKind::Break(_, Some(ref e)) => e,
_ => return, _ => return,
}; };
if let ExprCall(_, ref args) = e.node { if let ExprKind::Call(_, ref args) = e.node {
self.try_desugar_arm.push(args[0].id); self.try_desugar_arm.push(args[0].id);
} else { } else {
return; return;
} }
}, },
ExprMethodCall(ref name, .., ref args) => { ExprKind::MethodCall(ref name, .., ref args) => {
if match_trait_method(cx, e, &paths::INTO[..]) && &*name.ident.as_str() == "into" { if match_trait_method(cx, e, &paths::INTO[..]) && &*name.ident.as_str() == "into" {
let a = cx.tables.expr_ty(e); let a = cx.tables.expr_ty(e);
let b = cx.tables.expr_ty(&args[0]); let b = cx.tables.expr_ty(&args[0]);
@ -68,7 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
} }
}, },
ExprCall(ref path, ref args) => if let ExprPath(ref qpath) = path.node { ExprKind::Call(ref path, ref args) => if let ExprKind::Path(ref qpath) = path.node {
if let Some(def_id) = opt_def_id(resolve_node(cx, qpath, path.hir_id)) { if let Some(def_id) = opt_def_id(resolve_node(cx, qpath, path.hir_id)) {
if match_def_path(cx.tcx, def_id, &paths::FROM_FROM[..]) { if match_def_path(cx.tcx, def_id, &paths::FROM_FROM[..]) {
let a = cx.tables.expr_ty(e); let a = cx.tables.expr_ty(e);

View File

@ -36,19 +36,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
if in_macro(e.span) { if in_macro(e.span) {
return; return;
} }
if let ExprBinary(ref cmp, ref left, ref right) = e.node { if let ExprKind::Binary(ref cmp, ref left, ref right) = e.node {
match cmp.node { match cmp.node {
BiAdd | BiBitOr | BiBitXor => { BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {
check(cx, left, 0, e.span, right.span); check(cx, left, 0, e.span, right.span);
check(cx, right, 0, e.span, left.span); check(cx, right, 0, e.span, left.span);
}, },
BiShl | BiShr | BiSub => check(cx, right, 0, e.span, left.span), BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub => check(cx, right, 0, e.span, left.span),
BiMul => { BinOpKind::Mul => {
check(cx, left, 1, e.span, right.span); check(cx, left, 1, e.span, right.span);
check(cx, right, 1, e.span, left.span); check(cx, right, 1, e.span, left.span);
}, },
BiDiv => check(cx, right, 1, e.span, left.span), BinOpKind::Div => check(cx, right, 1, e.span, left.span),
BiBitAnd => { BinOpKind::BitAnd => {
check(cx, left, -1, e.span, right.span); check(cx, left, -1, e.span, right.span);
check(cx, right, -1, e.span, left.span); check(cx, right, -1, e.span, left.span);
}, },

View File

@ -45,7 +45,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 ExprMatch(ref op, ref arms, MatchSource::IfLetDesugar { .. }) = expr.node { if let ExprKind::Match(ref op, ref arms, MatchSource::IfLetDesugar { .. }) = expr.node {
if arms[0].pats.len() == 1 { if arms[0].pats.len() == 1 {
let good_method = match arms[0].pats[0].node { let good_method = match arms[0].pats[0].node {
PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 => { PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 => {

View File

@ -94,7 +94,7 @@ impl LintPass for IndexingSlicing {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
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 ExprIndex(ref array, ref index) = &expr.node { if let ExprKind::Index(ref array, ref index) = &expr.node {
let ty = cx.tables.expr_ty(array); let ty = cx.tables.expr_ty(array);
if let Some(range) = higher::range(cx, index) { if let Some(range) = higher::range(cx, index) {
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..] // Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]

View File

@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_local(&mut self, cx: &LateContext<'a, 'tcx>, local: &'tcx Local) { fn check_local(&mut self, cx: &LateContext<'a, 'tcx>, local: &'tcx Local) {
if_chain! { if_chain! {
if let Some(ref expr) = local.init; if let Some(ref expr) = local.init;
if let Expr_::ExprMatch(ref target, ref arms, MatchSource::Normal) = expr.node; if let ExprKind::Match(ref target, ref arms, MatchSource::Normal) = expr.node;
if arms.len() == 1 && arms[0].pats.len() == 1 && arms[0].guard.is_none(); if arms.len() == 1 && arms[0].pats.len() == 1 && arms[0].guard.is_none();
if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pats[0].node; if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pats[0].node;
if args.len() == 1; if args.len() == 1;

View File

@ -141,7 +141,7 @@ static HEURISTICS: &[(&str, usize, Heuristic, Finiteness)] = &[
fn is_infinite(cx: &LateContext, expr: &Expr) -> Finiteness { fn is_infinite(cx: &LateContext, expr: &Expr) -> Finiteness {
match expr.node { match expr.node {
ExprMethodCall(ref method, _, ref args) => { ExprKind::MethodCall(ref method, _, ref args) => {
for &(name, len, heuristic, cap) in HEURISTICS.iter() { for &(name, len, heuristic, cap) in HEURISTICS.iter() {
if method.ident.name == name && args.len() == len { if method.ident.name == name && args.len() == len {
return (match heuristic { return (match heuristic {
@ -153,21 +153,21 @@ fn is_infinite(cx: &LateContext, expr: &Expr) -> Finiteness {
} }
} }
if method.ident.name == "flat_map" && args.len() == 2 { if method.ident.name == "flat_map" && args.len() == 2 {
if let ExprClosure(_, _, body_id, _, _) = args[1].node { if let ExprKind::Closure(_, _, body_id, _, _) = args[1].node {
let body = cx.tcx.hir.body(body_id); let body = cx.tcx.hir.body(body_id);
return is_infinite(cx, &body.value); return is_infinite(cx, &body.value);
} }
} }
Finite Finite
}, },
ExprBlock(ref block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)), ExprKind::Block(ref block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
ExprBox(ref e) | ExprAddrOf(_, ref e) => is_infinite(cx, e), ExprKind::Box(ref e) | ExprKind::AddrOf(_, ref e) => is_infinite(cx, e),
ExprCall(ref path, _) => if let ExprPath(ref qpath) = path.node { ExprKind::Call(ref path, _) => if let ExprKind::Path(ref qpath) = path.node {
match_qpath(qpath, &paths::REPEAT).into() match_qpath(qpath, &paths::REPEAT).into()
} else { } else {
Finite Finite
}, },
ExprStruct(..) => higher::range(cx, expr) ExprKind::Struct(..) => higher::range(cx, expr)
.map_or(false, |r| r.end.is_none()) .map_or(false, |r| r.end.is_none())
.into(), .into(),
_ => Finite, _ => Finite,
@ -205,7 +205,7 @@ static COMPLETING_METHODS: &[(&str, usize)] = &[
fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness { fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness {
match expr.node { match expr.node {
ExprMethodCall(ref method, _, ref args) => { ExprKind::MethodCall(ref method, _, ref args) => {
for &(name, len) in COMPLETING_METHODS.iter() { for &(name, len) in COMPLETING_METHODS.iter() {
if method.ident.name == name && args.len() == len { if method.ident.name == name && args.len() == len {
return is_infinite(cx, &args[0]); return is_infinite(cx, &args[0]);
@ -224,11 +224,11 @@ fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness {
} }
} }
}, },
ExprBinary(op, ref l, ref r) => if op.node.is_comparison() { ExprKind::Binary(op, ref l, ref r) => if op.node.is_comparison() {
return is_infinite(cx, l) return is_infinite(cx, l)
.and(is_infinite(cx, r)) .and(is_infinite(cx, r))
.and(MaybeInfinite); .and(MaybeInfinite);
}, // TODO: ExprLoop + Match }, // TODO: ExprKind::Loop + Match
_ => (), _ => (),
} }
Finite Finite

View File

@ -56,7 +56,7 @@ impl LintPass for Pass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item) { fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item) {
if let Item_::ItemImpl(_, _, _, ref generics, None, _, _) = item.node { if let ItemKind::Impl(_, _, _, ref generics, None, _, _) = item.node {
// Remember for each inherent implementation encoutered its span and generics // Remember for each inherent implementation encoutered its span and generics
self.impls self.impls
.insert(item.hir_id.owner_def_id(), (item.span, generics.clone())); .insert(item.hir_id.owner_def_id(), (item.span, generics.clone()));

View File

@ -35,8 +35,8 @@ impl LintPass for InvalidRef {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidRef { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidRef {
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_chain! { if_chain! {
if let ExprCall(ref path, ref args) = expr.node; if let ExprKind::Call(ref path, ref args) = expr.node;
if let ExprPath(ref qpath) = path.node; if let ExprKind::Path(ref qpath) = path.node;
if args.len() == 0; if args.len() == 0;
if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty; if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty;
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)); if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));

View File

@ -49,7 +49,7 @@ impl LintPass for LargeEnumVariant {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
fn check_item(&mut self, cx: &LateContext, item: &Item) { fn check_item(&mut self, cx: &LateContext, item: &Item) {
let did = cx.tcx.hir.local_def_id(item.id); let did = cx.tcx.hir.local_def_id(item.id);
if let ItemEnum(ref def, _) = item.node { if let ItemKind::Enum(ref def, _) = item.node {
let ty = cx.tcx.type_of(did); let ty = cx.tcx.type_of(did);
let adt = ty.ty_adt_def() let adt = ty.ty_adt_def()
.expect("already checked whether this is an enum"); .expect("already checked whether this is an enum");

View File

@ -68,8 +68,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
} }
match item.node { match item.node {
ItemTrait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_items), ItemKind::Trait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_items),
ItemImpl(_, _, _, _, None, _, ref impl_items) => check_impl_items(cx, item, impl_items), ItemKind::Impl(_, _, _, _, None, _, ref impl_items) => check_impl_items(cx, item, impl_items),
_ => (), _ => (),
} }
} }
@ -79,26 +79,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
return; return;
} }
if let ExprBinary(Spanned { node: cmp, .. }, ref left, ref right) = expr.node { if let ExprKind::Binary(Spanned { node: cmp, .. }, ref left, ref right) = expr.node {
match cmp { match cmp {
BiEq => { BinOpKind::Eq => {
check_cmp(cx, expr.span, left, right, "", 0); // len == 0 check_cmp(cx, expr.span, left, right, "", 0); // len == 0
check_cmp(cx, expr.span, right, left, "", 0); // 0 == len check_cmp(cx, expr.span, right, left, "", 0); // 0 == len
}, },
BiNe => { BinOpKind::Ne => {
check_cmp(cx, expr.span, left, right, "!", 0); // len != 0 check_cmp(cx, expr.span, left, right, "!", 0); // len != 0
check_cmp(cx, expr.span, right, left, "!", 0); // 0 != len check_cmp(cx, expr.span, right, left, "!", 0); // 0 != len
}, },
BiGt => { BinOpKind::Gt => {
check_cmp(cx, expr.span, left, right, "!", 0); // len > 0 check_cmp(cx, expr.span, left, right, "!", 0); // len > 0
check_cmp(cx, expr.span, right, left, "", 1); // 1 > len check_cmp(cx, expr.span, right, left, "", 1); // 1 > len
}, },
BiLt => { BinOpKind::Lt => {
check_cmp(cx, expr.span, left, right, "", 1); // len < 1 check_cmp(cx, expr.span, left, right, "", 1); // len < 1
check_cmp(cx, expr.span, right, left, "!", 0); // 0 < len check_cmp(cx, expr.span, right, left, "!", 0); // 0 < len
}, },
BiGe => check_cmp(cx, expr.span, left, right, "!", 1), // len <= 1 BinOpKind::Ge => check_cmp(cx, expr.span, left, right, "!", 1), // len <= 1
BiLe => check_cmp(cx, expr.span, right, left, "!", 1), // 1 >= len BinOpKind::Le => check_cmp(cx, expr.span, right, left, "!", 1), // 1 >= len
_ => (), _ => (),
} }
} }
@ -194,7 +194,7 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
} }
fn check_cmp(cx: &LateContext, span: Span, method: &Expr, lit: &Expr, op: &str, compare_to: u32) { fn check_cmp(cx: &LateContext, span: Span, method: &Expr, lit: &Expr, op: &str, compare_to: u32) {
if let (&ExprMethodCall(ref method_path, _, ref args), &ExprLit(ref lit)) = (&method.node, &lit.node) { if let (&ExprKind::MethodCall(ref method_path, _, ref args), &ExprKind::Lit(ref lit)) = (&method.node, &lit.node) {
// check if we are in an is_empty() method // check if we are in an is_empty() method
if let Some(name) = get_item_name(cx, method) { if let Some(name) = get_item_name(cx, method) {
if name == "is_empty" { if name == "is_empty" {

View File

@ -65,20 +65,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
while let Some(stmt) = it.next() { while let Some(stmt) = it.next() {
if_chain! { if_chain! {
if let Some(expr) = it.peek(); if let Some(expr) = it.peek();
if let hir::StmtDecl(ref decl, _) = stmt.node; if let hir::StmtKind::Decl(ref decl, _) = stmt.node;
if let hir::DeclLocal(ref decl) = decl.node; if let hir::DeclKind::Local(ref decl) = decl.node;
if let hir::PatKind::Binding(mode, canonical_id, ident, None) = decl.pat.node; if let hir::PatKind::Binding(mode, canonical_id, ident, None) = decl.pat.node;
if let hir::StmtExpr(ref if_, _) = expr.node; if let hir::StmtKind::Expr(ref if_, _) = expr.node;
if let hir::ExprIf(ref cond, ref then, ref else_) = if_.node; if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.node;
if !used_in_expr(cx, canonical_id, cond); if !used_in_expr(cx, canonical_id, cond);
if let hir::ExprBlock(ref then, _) = then.node; if let hir::ExprKind::Block(ref then, _) = then.node;
if let Some(value) = check_assign(cx, canonical_id, &*then); if let Some(value) = check_assign(cx, canonical_id, &*then);
if !used_in_expr(cx, canonical_id, value); if !used_in_expr(cx, canonical_id, value);
then { then {
let span = stmt.span.to(if_.span); let span = stmt.span.to(if_.span);
let (default_multi_stmts, default) = if let Some(ref else_) = *else_ { let (default_multi_stmts, default) = if let Some(ref else_) = *else_ {
if let hir::ExprBlock(ref else_, _) = else_.node { if let hir::ExprKind::Block(ref else_, _) = else_.node {
if let Some(default) = check_assign(cx, canonical_id, else_) { if let Some(default) = check_assign(cx, canonical_id, else_) {
(else_.stmts.len() > 1, default) (else_.stmts.len() > 1, default)
} else if let Some(ref default) = decl.init { } else if let Some(ref default) = decl.init {
@ -140,7 +140,7 @@ struct UsedVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> { 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_chain! { if_chain! {
if let hir::ExprPath(ref qpath) = expr.node; if let hir::ExprKind::Path(ref qpath) = expr.node;
if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id); if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id);
if self.id == local_id; if self.id == local_id;
then { then {
@ -163,9 +163,9 @@ fn check_assign<'a, 'tcx>(
if_chain! { if_chain! {
if block.expr.is_none(); if block.expr.is_none();
if let Some(expr) = block.stmts.iter().last(); if let Some(expr) = block.stmts.iter().last();
if let hir::StmtSemi(ref expr, _) = expr.node; if let hir::StmtKind::Semi(ref expr, _) = expr.node;
if let hir::ExprAssign(ref var, ref value) = expr.node; if let hir::ExprKind::Assign(ref var, ref value) = expr.node;
if let hir::ExprPath(ref qpath) = var.node; if let hir::ExprKind::Path(ref qpath) = var.node;
if let Def::Local(local_id) = cx.tables.qpath_def(qpath, var.hir_id); if let Def::Local(local_id) = cx.tables.qpath_def(qpath, var.hir_id);
if decl == local_id; if decl == local_id;
then { then {

View File

@ -59,7 +59,7 @@ impl LintPass for LifetimePass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
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 let ItemFn(ref decl, _, ref generics, id) = item.node { if let ItemKind::Fn(ref decl, _, ref generics, id) = item.node {
check_fn_inner(cx, decl, Some(id), generics, item.span); check_fn_inner(cx, decl, Some(id), generics, item.span);
} }
} }
@ -338,14 +338,14 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &'tcx Ty) { fn visit_ty(&mut self, ty: &'tcx Ty) {
match ty.node { match ty.node {
TyRptr(ref lt, _) if lt.is_elided() => { TyKind::Rptr(ref lt, _) if lt.is_elided() => {
self.record(&None); self.record(&None);
}, },
TyPath(ref path) => { TyKind::Path(ref path) => {
if let QPath::Resolved(_, ref path) = *path { if let QPath::Resolved(_, ref path) = *path {
if let Def::Existential(def_id) = path.def { if let Def::Existential(def_id) = path.def {
let node_id = self.cx.tcx.hir.as_local_node_id(def_id).unwrap(); let node_id = self.cx.tcx.hir.as_local_node_id(def_id).unwrap();
if let ItemExistential(ref exist_ty) = self.cx.tcx.hir.expect_item(node_id).node { if let ItemKind::Existential(ref exist_ty) = self.cx.tcx.hir.expect_item(node_id).node {
for bound in &exist_ty.bounds { for bound in &exist_ty.bounds {
if let GenericBound::Outlives(_) = *bound { if let GenericBound::Outlives(_) = *bound {
self.record(&None); self.record(&None);
@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
} }
self.collect_anonymous_lifetimes(path, ty); self.collect_anonymous_lifetimes(path, ty);
} }
TyTraitObject(ref bounds, ref lt) => { TyKind::TraitObject(ref bounds, ref lt) => {
if !lt.is_elided() { if !lt.is_elided() {
self.abort = true; self.abort = true;
} }

View File

@ -411,7 +411,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
// check for never_loop // check for never_loop
match expr.node { match expr.node {
ExprWhile(_, ref block, _) | ExprLoop(ref block, _, _) => { ExprKind::While(_, ref block, _) | ExprKind::Loop(ref block, _, _) => {
match never_loop_block(block, expr.id) { match never_loop_block(block, expr.id) {
NeverLoopResult::AlwaysBreak => NeverLoopResult::AlwaysBreak =>
span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"), span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"),
@ -424,7 +424,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
// check for `loop { if let {} else break }` that could be `while let` // check for `loop { if let {} else break }` that could be `while let`
// (also matches an explicit "match" instead of "if let") // (also matches an explicit "match" instead of "if let")
// (even if the "match" or "if let" is used for declaration) // (even if the "match" or "if let" is used for declaration)
if let ExprLoop(ref block, _, LoopSource::Loop) = expr.node { if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.node {
// also check for empty `loop {}` statements // also check for empty `loop {}` statements
if block.stmts.is_empty() && block.expr.is_none() { if block.stmts.is_empty() && block.expr.is_none() {
span_lint( span_lint(
@ -440,7 +440,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let inner_stmt_expr = extract_expr_from_first_stmt(block); let inner_stmt_expr = extract_expr_from_first_stmt(block);
// or extract the first expression (if any) from the block // or extract the first expression (if any) from the block
if let Some(inner) = inner_stmt_expr.or_else(|| extract_first_expr(block)) { if let Some(inner) = inner_stmt_expr.or_else(|| extract_first_expr(block)) {
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node { if let ExprKind::Match(ref matchexpr, ref arms, ref source) = inner.node {
// ensure "if let" compatible match structure // ensure "if let" compatible match structure
match *source { match *source {
MatchSource::Normal | MatchSource::IfLetDesugar { .. } => { MatchSource::Normal | MatchSource::IfLetDesugar { .. } => {
@ -476,11 +476,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
} }
} }
if let ExprMatch(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.node { if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.node {
let pat = &arms[0].pats[0].node; let pat = &arms[0].pats[0].node;
if let ( if let (
&PatKind::TupleStruct(ref qpath, ref pat_args, _), &PatKind::TupleStruct(ref qpath, ref pat_args, _),
&ExprMethodCall(ref method_path, _, ref method_args), &ExprKind::MethodCall(ref method_path, _, ref method_args),
) = (pat, &match_expr.node) ) = (pat, &match_expr.node)
{ {
let iter_expr = &method_args[0]; let iter_expr = &method_args[0];
@ -505,14 +505,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
// check for while loops which conditions never change // check for while loops which conditions never change
if let ExprWhile(ref cond, _, _) = expr.node { if let ExprKind::While(ref cond, _, _) = expr.node {
check_infinite_loop(cx, cond, expr); check_infinite_loop(cx, cond, expr);
} }
} }
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
if let StmtSemi(ref expr, _) = stmt.node { if let StmtKind::Semi(ref expr, _) = stmt.node {
if let ExprMethodCall(ref method, _, ref args) = expr.node { if let ExprKind::MethodCall(ref method, _, ref args) = expr.node {
if args.len() == 1 && method.ident.name == "collect" && match_trait_method(cx, expr, &paths::ITERATOR) { if args.len() == 1 && method.ident.name == "collect" && match_trait_method(cx, expr, &paths::ITERATOR) {
span_lint( span_lint(
cx, cx,
@ -584,53 +584,53 @@ fn never_loop_block(block: &Block, main_loop_id: NodeId) -> NeverLoopResult {
fn stmt_to_expr(stmt: &Stmt) -> Option<&Expr> { fn stmt_to_expr(stmt: &Stmt) -> Option<&Expr> {
match stmt.node { match stmt.node {
StmtSemi(ref e, ..) | StmtExpr(ref e, ..) => Some(e), StmtKind::Semi(ref e, ..) | StmtKind::Expr(ref e, ..) => Some(e),
StmtDecl(ref d, ..) => decl_to_expr(d), StmtKind::Decl(ref d, ..) => decl_to_expr(d),
} }
} }
fn decl_to_expr(decl: &Decl) -> Option<&Expr> { fn decl_to_expr(decl: &Decl) -> Option<&Expr> {
match decl.node { match decl.node {
DeclLocal(ref local) => local.init.as_ref().map(|p| &**p), DeclKind::Local(ref local) => local.init.as_ref().map(|p| &**p),
_ => None, _ => None,
} }
} }
fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult { fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
match expr.node { match expr.node {
ExprBox(ref e) | ExprKind::Box(ref e) |
ExprUnary(_, ref e) | ExprKind::Unary(_, ref e) |
ExprCast(ref e, _) | ExprKind::Cast(ref e, _) |
ExprType(ref e, _) | ExprKind::Type(ref e, _) |
ExprField(ref e, _) | ExprKind::Field(ref e, _) |
ExprAddrOf(_, ref e) | ExprKind::AddrOf(_, ref e) |
ExprStruct(_, _, Some(ref e)) | ExprKind::Struct(_, _, Some(ref e)) |
ExprRepeat(ref e, _) => never_loop_expr(e, main_loop_id), ExprKind::Repeat(ref e, _) => never_loop_expr(e, main_loop_id),
ExprArray(ref es) | ExprMethodCall(_, _, ref es) | ExprTup(ref es) => { ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es) | ExprKind::Tup(ref es) => {
never_loop_expr_all(&mut es.iter(), main_loop_id) never_loop_expr_all(&mut es.iter(), main_loop_id)
}, },
ExprCall(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id), ExprKind::Call(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id),
ExprBinary(_, ref e1, ref e2) | ExprKind::Binary(_, ref e1, ref e2) |
ExprAssign(ref e1, ref e2) | ExprKind::Assign(ref e1, ref e2) |
ExprAssignOp(_, ref e1, ref e2) | ExprKind::AssignOp(_, ref e1, ref e2) |
ExprIndex(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id), ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
ExprIf(ref e, ref e2, ref e3) => { ExprKind::If(ref e, ref e2, ref e3) => {
let e1 = never_loop_expr(e, main_loop_id); let e1 = never_loop_expr(e, main_loop_id);
let e2 = never_loop_expr(e2, main_loop_id); let e2 = never_loop_expr(e2, main_loop_id);
let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id)); let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id));
combine_seq(e1, combine_branches(e2, e3)) combine_seq(e1, combine_branches(e2, e3))
}, },
ExprLoop(ref b, _, _) => { ExprKind::Loop(ref b, _, _) => {
// Break can come from the inner loop so remove them. // Break can come from the inner loop so remove them.
absorb_break(&never_loop_block(b, main_loop_id)) absorb_break(&never_loop_block(b, main_loop_id))
}, },
ExprWhile(ref e, ref b, _) => { ExprKind::While(ref e, ref b, _) => {
let e = never_loop_expr(e, main_loop_id); let e = never_loop_expr(e, main_loop_id);
let result = never_loop_block(b, main_loop_id); let result = never_loop_block(b, main_loop_id);
// Break can come from the inner loop so remove them. // Break can come from the inner loop so remove them.
combine_seq(e, absorb_break(&result)) combine_seq(e, absorb_break(&result))
}, },
ExprMatch(ref e, ref arms, _) => { ExprKind::Match(ref e, ref arms, _) => {
let e = never_loop_expr(e, main_loop_id); let e = never_loop_expr(e, main_loop_id);
if arms.is_empty() { if arms.is_empty() {
e e
@ -639,8 +639,8 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
combine_seq(e, arms) combine_seq(e, arms)
} }
}, },
ExprBlock(ref b, _) => never_loop_block(b, main_loop_id), ExprKind::Block(ref b, _) => never_loop_block(b, main_loop_id),
ExprContinue(d) => { ExprKind::Continue(d) => {
let id = d.target_id let id = d.target_id
.expect("target id can only be missing in the presence of compilation errors"); .expect("target id can only be missing in the presence of compilation errors");
if id == main_loop_id { if id == main_loop_id {
@ -649,22 +649,22 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
NeverLoopResult::AlwaysBreak NeverLoopResult::AlwaysBreak
} }
}, },
ExprBreak(_, _) => { ExprKind::Break(_, _) => {
NeverLoopResult::AlwaysBreak NeverLoopResult::AlwaysBreak
}, },
ExprRet(ref e) => { ExprKind::Ret(ref e) => {
if let Some(ref e) = *e { if let Some(ref e) = *e {
combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak) combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)
} else { } else {
NeverLoopResult::AlwaysBreak NeverLoopResult::AlwaysBreak
} }
}, },
ExprStruct(_, _, None) | ExprKind::Struct(_, _, None) |
ExprYield(_) | ExprKind::Yield(_) |
ExprClosure(_, _, _, _, _) | ExprKind::Closure(_, _, _, _, _) |
ExprInlineAsm(_, _, _) | ExprKind::InlineAsm(_, _, _) |
ExprPath(_) | ExprKind::Path(_) |
ExprLit(_) => NeverLoopResult::Otherwise, ExprKind::Lit(_) => NeverLoopResult::Otherwise,
} }
} }
@ -701,7 +701,7 @@ fn check_for_loop<'a, 'tcx>(
fn same_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> bool { fn same_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> bool {
if_chain! { if_chain! {
if let ExprPath(ref qpath) = expr.node; if let ExprKind::Path(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; if path.segments.len() == 1;
if let Def::Local(local_id) = cx.tables.qpath_def(qpath, expr.hir_id); if let Def::Local(local_id) = cx.tables.qpath_def(qpath, expr.hir_id);
@ -754,24 +754,24 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty) -> bool {
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> Option<FixedOffsetVar> { fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> Option<FixedOffsetVar> {
fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option<String> { fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option<String> {
match e.node { match e.node {
ExprLit(ref l) => match l.node { ExprKind::Lit(ref l) => match l.node {
ast::LitKind::Int(x, _ty) => Some(x.to_string()), ast::LitKind::Int(x, _ty) => Some(x.to_string()),
_ => None, _ => None,
}, },
ExprPath(..) if !same_var(cx, e, var) => Some(snippet_opt(cx, e.span).unwrap_or_else(|| "??".into())), ExprKind::Path(..) if !same_var(cx, e, var) => Some(snippet_opt(cx, e.span).unwrap_or_else(|| "??".into())),
_ => None, _ => None,
} }
} }
if let ExprIndex(ref seqexpr, ref idx) = expr.node { if let ExprKind::Index(ref seqexpr, ref idx) = expr.node {
let ty = cx.tables.expr_ty(seqexpr); let ty = cx.tables.expr_ty(seqexpr);
if !is_slice_like(cx, ty) { if !is_slice_like(cx, ty) {
return None; return None;
} }
let offset = match idx.node { let offset = match idx.node {
ExprBinary(op, ref lhs, ref rhs) => match op.node { ExprKind::Binary(op, ref lhs, ref rhs) => match op.node {
BinOp_::BiAdd => { BinOpKind::Add => {
let offset_opt = if same_var(cx, lhs, var) { let offset_opt = if same_var(cx, lhs, var) {
extract_offset(cx, rhs, var) extract_offset(cx, rhs, var)
} else if same_var(cx, rhs, var) { } else if same_var(cx, rhs, var) {
@ -782,10 +782,10 @@ fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var:
offset_opt.map(Offset::positive) offset_opt.map(Offset::positive)
}, },
BinOp_::BiSub if same_var(cx, lhs, var) => extract_offset(cx, rhs, var).map(Offset::negative), BinOpKind::Sub if same_var(cx, lhs, var) => extract_offset(cx, rhs, var).map(Offset::negative),
_ => None, _ => None,
}, },
ExprPath(..) => if same_var(cx, idx, var) { ExprKind::Path(..) => if same_var(cx, idx, var) {
Some(Offset::positive("0".into())) Some(Offset::positive("0".into()))
} else { } else {
None None
@ -810,7 +810,7 @@ fn fetch_cloned_fixed_offset_var<'a, 'tcx>(
var: ast::NodeId, var: ast::NodeId,
) -> Option<FixedOffsetVar> { ) -> Option<FixedOffsetVar> {
if_chain! { if_chain! {
if let ExprMethodCall(ref method, _, ref args) = expr.node; if let ExprKind::MethodCall(ref method, _, ref args) = expr.node;
if method.ident.name == "clone"; if method.ident.name == "clone";
if args.len() == 1; if args.len() == 1;
if let Some(arg) = args.get(0); if let Some(arg) = args.get(0);
@ -832,7 +832,7 @@ fn get_indexed_assignments<'a, 'tcx>(
e: &Expr, e: &Expr,
var: ast::NodeId, var: ast::NodeId,
) -> Option<(FixedOffsetVar, FixedOffsetVar)> { ) -> Option<(FixedOffsetVar, FixedOffsetVar)> {
if let Expr_::ExprAssign(ref lhs, ref rhs) = e.node { if let ExprKind::Assign(ref lhs, ref rhs) = e.node {
match (get_fixed_offset_var(cx, lhs, var), fetch_cloned_fixed_offset_var(cx, rhs, var)) { match (get_fixed_offset_var(cx, lhs, var), fetch_cloned_fixed_offset_var(cx, rhs, var)) {
(Some(offset_left), Some(offset_right)) => { (Some(offset_left), Some(offset_right)) => {
// Source and destination must be different // Source and destination must be different
@ -849,7 +849,7 @@ fn get_indexed_assignments<'a, 'tcx>(
} }
} }
if let Expr_::ExprBlock(ref b, _) = body.node { if let ExprKind::Block(ref b, _) = body.node {
let Block { let Block {
ref stmts, ref stmts,
ref expr, ref expr,
@ -859,8 +859,8 @@ fn get_indexed_assignments<'a, 'tcx>(
stmts stmts
.iter() .iter()
.map(|stmt| match stmt.node { .map(|stmt| match stmt.node {
Stmt_::StmtDecl(..) => None, StmtKind::Decl(..) => None,
Stmt_::StmtExpr(ref e, _node_id) | Stmt_::StmtSemi(ref e, _node_id) => Some(get_assignment(cx, e, var)), StmtKind::Expr(ref e, _node_id) | StmtKind::Semi(ref e, _node_id) => Some(get_assignment(cx, e, var)),
}) })
.chain( .chain(
expr.as_ref() expr.as_ref()
@ -906,7 +906,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
let print_limit = |end: &Option<&Expr>, offset: Offset, var_name: &str| if let Some(end) = *end { let print_limit = |end: &Option<&Expr>, offset: Offset, var_name: &str| if let Some(end) = *end {
if_chain! { if_chain! {
if let ExprMethodCall(ref method, _, ref len_args) = end.node; if let ExprKind::MethodCall(ref method, _, ref len_args) = end.node;
if method.ident.name == "len"; if method.ident.name == "len";
if len_args.len() == 1; if len_args.len() == 1;
if let Some(arg) = len_args.get(0); if let Some(arg) = len_args.get(0);
@ -1098,10 +1098,10 @@ fn check_for_loop_range<'a, 'tcx>(
fn is_len_call(expr: &Expr, var: Name) -> bool { fn is_len_call(expr: &Expr, var: Name) -> bool {
if_chain! { if_chain! {
if let ExprMethodCall(ref method, _, ref len_args) = expr.node; if let ExprKind::MethodCall(ref method, _, ref len_args) = expr.node;
if len_args.len() == 1; if len_args.len() == 1;
if method.ident.name == "len"; if method.ident.name == "len";
if let ExprPath(QPath::Resolved(_, ref path)) = len_args[0].node; if let ExprKind::Path(QPath::Resolved(_, ref path)) = len_args[0].node;
if path.segments.len() == 1; if path.segments.len() == 1;
if path.segments[0].ident.name == var; if path.segments[0].ident.name == var;
then { then {
@ -1203,7 +1203,7 @@ fn lint_iter_method(cx: &LateContext, args: &[Expr], arg: &Expr, method_name: &s
fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used
if let ExprMethodCall(ref method, _, ref args) = arg.node { if let ExprKind::MethodCall(ref method, _, ref args) = arg.node {
// just the receiver, no arguments // just the receiver, no arguments
if args.len() == 1 { if args.len() == 1 {
let method_name = &*method.ident.as_str(); let method_name = &*method.ident.as_str();
@ -1377,7 +1377,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
MutMutable => "_mut", MutMutable => "_mut",
}; };
let arg = match arg.node { let arg = match arg.node {
ExprAddrOf(_, ref expr) => &**expr, ExprKind::AddrOf(_, ref expr) => &**expr,
_ => arg, _ => arg,
}; };
@ -1483,7 +1483,7 @@ fn mut_warn_with_span(cx: &LateContext, span: Option<Span>) {
fn check_for_mutability(cx: &LateContext, bound: &Expr) -> Option<NodeId> { fn check_for_mutability(cx: &LateContext, bound: &Expr) -> Option<NodeId> {
if_chain! { if_chain! {
if let ExprPath(ref qpath) = bound.node; if let ExprKind::Path(ref qpath) = bound.node;
if let QPath::Resolved(None, _) = *qpath; if let QPath::Resolved(None, _) = *qpath;
then { then {
let def = cx.tables.qpath_def(qpath, bound.hir_id); let def = cx.tables.qpath_def(qpath, bound.hir_id);
@ -1598,7 +1598,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
fn check(&mut self, idx: &'tcx Expr, seqexpr: &'tcx Expr, expr: &'tcx Expr) -> bool { fn check(&mut self, idx: &'tcx Expr, seqexpr: &'tcx Expr, expr: &'tcx Expr) -> bool {
if_chain! { if_chain! {
// the indexed container is referenced by a name // the indexed container is referenced by a name
if let ExprPath(ref seqpath) = seqexpr.node; if let ExprKind::Path(ref seqpath) = seqexpr.node;
if let QPath::Resolved(None, ref seqvar) = *seqpath; if let QPath::Resolved(None, ref seqvar) = *seqpath;
if seqvar.segments.len() == 1; if seqvar.segments.len() == 1;
then { then {
@ -1655,7 +1655,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_chain! { if_chain! {
// a range index op // a range index op
if let ExprMethodCall(ref meth, _, ref args) = expr.node; if let ExprKind::MethodCall(ref meth, _, ref args) = expr.node;
if (meth.ident.name == "index" && match_trait_method(self.cx, expr, &paths::INDEX)) if (meth.ident.name == "index" && match_trait_method(self.cx, expr, &paths::INDEX))
|| (meth.ident.name == "index_mut" && match_trait_method(self.cx, expr, &paths::INDEX_MUT)); || (meth.ident.name == "index_mut" && match_trait_method(self.cx, expr, &paths::INDEX_MUT));
if !self.check(&args[1], &args[0], expr); if !self.check(&args[1], &args[0], expr);
@ -1664,14 +1664,14 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
if_chain! { if_chain! {
// an index op // an index op
if let ExprIndex(ref seqexpr, ref idx) = expr.node; if let ExprKind::Index(ref seqexpr, ref idx) = expr.node;
if !self.check(idx, seqexpr, expr); if !self.check(idx, seqexpr, expr);
then { return } then { return }
} }
if_chain! { if_chain! {
// directly using a variable // directly using a variable
if let ExprPath(ref qpath) = expr.node; if let ExprKind::Path(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; if path.segments.len() == 1;
if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id); if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id);
@ -1687,20 +1687,20 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
} }
let old = self.prefer_mutable; let old = self.prefer_mutable;
match expr.node { match expr.node {
ExprAssignOp(_, ref lhs, ref rhs) | ExprKind::AssignOp(_, ref lhs, ref rhs) |
ExprAssign(ref lhs, ref rhs) => { ExprKind::Assign(ref lhs, ref rhs) => {
self.prefer_mutable = true; self.prefer_mutable = true;
self.visit_expr(lhs); self.visit_expr(lhs);
self.prefer_mutable = false; self.prefer_mutable = false;
self.visit_expr(rhs); self.visit_expr(rhs);
}, },
ExprAddrOf(mutbl, ref expr) => { ExprKind::AddrOf(mutbl, ref expr) => {
if mutbl == MutMutable { if mutbl == MutMutable {
self.prefer_mutable = true; self.prefer_mutable = true;
} }
self.visit_expr(expr); self.visit_expr(expr);
}, },
ExprCall(ref f, ref args) => { ExprKind::Call(ref f, ref args) => {
self.visit_expr(f); self.visit_expr(f);
for expr in args { for expr in args {
let ty = self.cx.tables.expr_ty_adjusted(expr); let ty = self.cx.tables.expr_ty_adjusted(expr);
@ -1713,7 +1713,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
self.visit_expr(expr); self.visit_expr(expr);
} }
}, },
ExprMethodCall(_, _, ref args) => { ExprKind::MethodCall(_, _, ref args) => {
let def_id = self.cx.tables.type_dependent_defs()[expr.hir_id].def_id(); let def_id = self.cx.tables.type_dependent_defs()[expr.hir_id].def_id();
for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) {
self.prefer_mutable = false; self.prefer_mutable = false;
@ -1809,8 +1809,8 @@ fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> {
if block.stmts.is_empty() { if block.stmts.is_empty() {
return None; return None;
} }
if let StmtDecl(ref decl, _) = block.stmts[0].node { if let StmtKind::Decl(ref decl, _) = block.stmts[0].node {
if let DeclLocal(ref local) = decl.node { if let DeclKind::Local(ref local) = decl.node {
if let Some(ref expr) = local.init { if let Some(ref expr) = local.init {
Some(expr) Some(expr)
} else { } else {
@ -1829,8 +1829,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
match block.expr { match block.expr {
Some(ref expr) if block.stmts.is_empty() => Some(expr), Some(ref expr) if block.stmts.is_empty() => Some(expr),
None if !block.stmts.is_empty() => match block.stmts[0].node { None if !block.stmts.is_empty() => match block.stmts[0].node {
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => Some(expr), StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => Some(expr),
StmtDecl(..) => None, StmtKind::Decl(..) => None,
}, },
_ => None, _ => None,
} }
@ -1841,8 +1841,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
/// passed expression. The expression may be within a block. /// passed expression. The expression may be within a block.
fn is_simple_break_expr(expr: &Expr) -> bool { fn is_simple_break_expr(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprBreak(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true, ExprKind::Break(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true,
ExprBlock(ref b, _) => match extract_first_expr(b) { ExprKind::Block(ref b, _) => match extract_first_expr(b) {
Some(subexpr) => is_simple_break_expr(subexpr), Some(subexpr) => is_simple_break_expr(subexpr),
None => false, None => false,
}, },
@ -1882,9 +1882,9 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
let state = self.states.entry(def_id).or_insert(VarState::Initial); let state = self.states.entry(def_id).or_insert(VarState::Initial);
match parent.node { match parent.node {
ExprAssignOp(op, ref lhs, ref rhs) => { ExprKind::AssignOp(op, ref lhs, ref rhs) => {
if lhs.id == expr.id { if lhs.id == expr.id {
if op.node == BiAdd && is_integer_literal(rhs, 1) { if op.node == BinOpKind::Add && is_integer_literal(rhs, 1) {
*state = match *state { *state = match *state {
VarState::Initial if self.depth == 0 => VarState::IncrOnce, VarState::Initial if self.depth == 0 => VarState::IncrOnce,
_ => VarState::DontWarn, _ => VarState::DontWarn,
@ -1895,8 +1895,8 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
} }
} }
}, },
ExprAssign(ref lhs, _) if lhs.id == expr.id => *state = VarState::DontWarn, ExprKind::Assign(ref lhs, _) if lhs.id == expr.id => *state = VarState::DontWarn,
ExprAddrOf(mutability, _) if mutability == MutMutable => *state = VarState::DontWarn, ExprKind::AddrOf(mutability, _) if mutability == MutMutable => *state = VarState::DontWarn,
_ => (), _ => (),
} }
} }
@ -1931,7 +1931,7 @@ struct InitializeVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
fn visit_decl(&mut self, decl: &'tcx Decl) { fn visit_decl(&mut self, decl: &'tcx Decl) {
// Look for declarations of the variable // Look for declarations of the variable
if let DeclLocal(ref local) = decl.node { if let DeclKind::Local(ref local) = decl.node {
if local.pat.id == self.var_id { if local.pat.id == self.var_id {
if let PatKind::Binding(_, _, ident, _) = local.pat.node { if let PatKind::Binding(_, _, ident, _) = local.pat.node {
self.name = Some(ident.name); self.name = Some(ident.name);
@ -1969,17 +1969,17 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
if var_def_id(self.cx, expr) == Some(self.var_id) { if var_def_id(self.cx, expr) == Some(self.var_id) {
if let Some(parent) = get_parent_expr(self.cx, expr) { if let Some(parent) = get_parent_expr(self.cx, expr) {
match parent.node { match parent.node {
ExprAssignOp(_, ref lhs, _) if lhs.id == expr.id => { ExprKind::AssignOp(_, ref lhs, _) if lhs.id == expr.id => {
self.state = VarState::DontWarn; self.state = VarState::DontWarn;
}, },
ExprAssign(ref lhs, ref rhs) if lhs.id == expr.id => { ExprKind::Assign(ref lhs, ref rhs) if lhs.id == expr.id => {
self.state = if is_integer_literal(rhs, 0) && self.depth == 0 { self.state = if is_integer_literal(rhs, 0) && self.depth == 0 {
VarState::Warn VarState::Warn
} else { } else {
VarState::DontWarn VarState::DontWarn
} }
}, },
ExprAddrOf(mutability, _) if mutability == MutMutable => self.state = VarState::DontWarn, ExprKind::AddrOf(mutability, _) if mutability == MutMutable => self.state = VarState::DontWarn,
_ => (), _ => (),
} }
} }
@ -2005,7 +2005,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 ExprKind::Path(ref qpath) = expr.node {
let path_res = cx.tables.qpath_def(qpath, expr.hir_id); let path_res = cx.tables.qpath_def(qpath, expr.hir_id);
if let Def::Local(node_id) = path_res { if let Def::Local(node_id) = path_res {
return Some(node_id); return Some(node_id);
@ -2016,14 +2016,14 @@ fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
fn is_loop(expr: &Expr) -> bool { fn is_loop(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprLoop(..) | ExprWhile(..) => true, ExprKind::Loop(..) | ExprKind::While(..) => true,
_ => false, _ => false,
} }
} }
fn is_conditional(expr: &Expr) -> bool { fn is_conditional(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprIf(..) | ExprMatch(..) => true, ExprKind::If(..) | ExprKind::Match(..) => true,
_ => false, _ => false,
} }
} }
@ -2053,7 +2053,7 @@ fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool
} }
match cx.tcx.hir.find(parent) { match cx.tcx.hir.find(parent) {
Some(NodeExpr(expr)) => match expr.node { Some(NodeExpr(expr)) => match expr.node {
ExprLoop(..) | ExprWhile(..) => { ExprKind::Loop(..) | ExprKind::While(..) => {
return true; return true;
}, },
_ => (), _ => (),
@ -2111,7 +2111,7 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
return; return;
} }
match expr.node { match expr.node {
ExprAssign(ref path, _) | ExprAssignOp(_, ref path, _) => if match_var(path, self.iterator) { ExprKind::Assign(ref path, _) | ExprKind::AssignOp(_, ref path, _) => if match_var(path, self.iterator) {
self.nesting = RuledOut; self.nesting = RuledOut;
}, },
_ => walk_expr(self, expr), _ => walk_expr(self, expr),
@ -2137,7 +2137,7 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
} }
fn path_name(e: &Expr) -> Option<Name> { fn path_name(e: &Expr) -> Option<Name> {
if let ExprPath(QPath::Resolved(_, ref path)) = e.node { if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
let segments = &path.segments; let segments = &path.segments;
if segments.len() == 1 { if segments.len() == 1 {
return Some(segments[0].ident.name); return Some(segments[0].ident.name);
@ -2193,7 +2193,7 @@ struct VarCollectorVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> { impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
fn insert_def_id(&mut self, ex: &'tcx Expr) { fn insert_def_id(&mut self, ex: &'tcx Expr) {
if_chain! { if_chain! {
if let ExprPath(ref qpath) = ex.node; if let ExprKind::Path(ref qpath) = ex.node;
if let QPath::Resolved(None, _) = *qpath; if let QPath::Resolved(None, _) = *qpath;
let def = self.cx.tables.qpath_def(qpath, ex.hir_id); let def = self.cx.tables.qpath_def(qpath, ex.hir_id);
then { then {
@ -2214,9 +2214,9 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
fn visit_expr(&mut self, ex: &'tcx Expr) { fn visit_expr(&mut self, ex: &'tcx Expr) {
match ex.node { match ex.node {
ExprPath(_) => self.insert_def_id(ex), ExprKind::Path(_) => self.insert_def_id(ex),
// If there is any fuction/method call… we just stop analysis // If there is any fuction/method call… we just stop analysis
ExprCall(..) | ExprMethodCall(..) => self.skip = true, ExprKind::Call(..) | ExprKind::MethodCall(..) => self.skip = true,
_ => walk_expr(self, ex), _ => walk_expr(self, ex),
} }

View File

@ -30,10 +30,10 @@ pub struct 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) {
// call to .map() // call to .map()
if let ExprMethodCall(ref method, _, ref args) = expr.node { if let ExprKind::MethodCall(ref method, _, ref args) = expr.node {
if method.ident.name == "map" && args.len() == 2 { if method.ident.name == "map" && args.len() == 2 {
match args[1].node { match args[1].node {
ExprClosure(_, ref decl, closure_eid, _, _) => { ExprKind::Closure(_, ref decl, closure_eid, _, _) => {
let body = cx.tcx.hir.body(closure_eid); let body = cx.tcx.hir.body(closure_eid);
let closure_expr = remove_blocks(&body.value); let closure_expr = remove_blocks(&body.value);
if_chain! { if_chain! {
@ -62,7 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
} }
// explicit clone() calls ( .map(|x| x.clone()) ) // explicit clone() calls ( .map(|x| x.clone()) )
else if let ExprMethodCall(ref clone_call, _, ref clone_args) = closure_expr.node { else if let ExprKind::MethodCall(ref clone_call, _, ref clone_args) = closure_expr.node {
if clone_call.ident.name == "clone" && if clone_call.ident.name == "clone" &&
clone_args.len() == 1 && clone_args.len() == 1 &&
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
@ -77,7 +77,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
} }
}, },
ExprPath(ref path) => if match_qpath(path, &paths::CLONE) { ExprKind::Path(ref path) => if match_qpath(path, &paths::CLONE) {
let type_name = get_type_name(cx, expr, &args[0]).unwrap_or("_"); let type_name = get_type_name(cx, expr, &args[0]).unwrap_or("_");
span_help_and_lint( span_help_and_lint(
cx, cx,
@ -100,7 +100,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn expr_eq_name(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool { fn expr_eq_name(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool {
match expr.node { match expr.node {
ExprPath(QPath::Resolved(None, ref path)) => { ExprKind::Path(QPath::Resolved(None, ref path)) => {
let arg_segment = [ let arg_segment = [
PathSegment { PathSegment {
ident: id, ident: id,
@ -126,7 +126,7 @@ fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static s
fn only_derefs(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool { fn only_derefs(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool {
match expr.node { match expr.node {
ExprUnary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => only_derefs(cx, subexpr, id), ExprKind::Unary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => only_derefs(cx, subexpr, id),
_ => expr_eq_name(cx, expr, id), _ => expr_eq_name(cx, expr, id),
} }
} }

View File

@ -1,7 +1,7 @@
use rustc::hir; use rustc::hir;
use rustc::lint::*; use rustc::lint::*;
use rustc::ty; use rustc::ty;
use rustc_errors::{Applicability}; use rustc_errors::Applicability;
use syntax::codemap::Span; use syntax::codemap::Span;
use crate::utils::{in_macro, iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then}; use crate::utils::{in_macro, iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then};
use crate::utils::paths; use crate::utils::paths;
@ -115,12 +115,12 @@ fn reduce_unit_expression<'a>(cx: &LateContext, expr: &'a hir::Expr) -> Option<S
} }
match expr.node { match expr.node {
hir::ExprCall(_, _) | hir::ExprKind::Call(_, _) |
hir::ExprMethodCall(_, _, _) => { hir::ExprKind::MethodCall(_, _, _) => {
// Calls can't be reduced any more // Calls can't be reduced any more
Some(expr.span) Some(expr.span)
}, },
hir::ExprBlock(ref block, _) => { hir::ExprKind::Block(ref block, _) => {
match (&block.stmts[..], block.expr.as_ref()) { match (&block.stmts[..], block.expr.as_ref()) {
(&[], Some(inner_expr)) => { (&[], Some(inner_expr)) => {
// If block only contains an expression, // If block only contains an expression,
@ -131,9 +131,9 @@ fn reduce_unit_expression<'a>(cx: &LateContext, expr: &'a hir::Expr) -> Option<S
// If block only contains statements, // If block only contains statements,
// reduce `{ X; }` to `X` or `X;` // reduce `{ X; }` to `X` or `X;`
match inner_stmt.node { match inner_stmt.node {
hir::StmtDecl(ref d, _) => Some(d.span), hir::StmtKind::Decl(ref d, _) => Some(d.span),
hir::StmtExpr(ref e, _) => Some(e.span), hir::StmtKind::Expr(ref e, _) => Some(e.span),
hir::StmtSemi(_, _) => Some(inner_stmt.span), hir::StmtKind::Semi(_, _) => Some(inner_stmt.span),
} }
}, },
_ => { _ => {
@ -151,7 +151,7 @@ fn reduce_unit_expression<'a>(cx: &LateContext, expr: &'a hir::Expr) -> Option<S
} }
fn unit_closure<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'a hir::Expr) -> Option<(&'tcx hir::Arg, &'a hir::Expr)> { fn unit_closure<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'a hir::Expr) -> Option<(&'tcx hir::Arg, &'a hir::Expr)> {
if let hir::ExprClosure(_, ref decl, inner_expr_id, _, _) = expr.node { if let hir::ExprKind::Closure(_, ref decl, inner_expr_id, _, _) = expr.node {
let body = cx.tcx.hir.body(inner_expr_id); let body = cx.tcx.hir.body(inner_expr_id);
let body_expr = &body.value; let body_expr = &body.value;
@ -175,8 +175,8 @@ fn unit_closure<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'a hir::Expr) -> Op
/// Anything else will return `_`. /// Anything else will return `_`.
fn let_binding_name(cx: &LateContext, var_arg: &hir::Expr) -> String { fn let_binding_name(cx: &LateContext, var_arg: &hir::Expr) -> String {
match &var_arg.node { match &var_arg.node {
hir::ExprField(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"), hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"),
hir::ExprPath(_) => format!("_{}", snippet(cx, var_arg.span, "")), hir::ExprKind::Path(_) => format!("_{}", snippet(cx, var_arg.span, "")),
_ => "_".to_string() _ => "_".to_string()
} }
} }
@ -247,8 +247,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
return; return;
} }
if let hir::StmtSemi(ref expr, _) = stmt.node { if let hir::StmtKind::Semi(ref expr, _) = stmt.node {
if let hir::ExprMethodCall(_, _, _) = expr.node { if let hir::ExprKind::MethodCall(_, _, _) = expr.node {
if let Some(arglists) = method_chain_args(expr, &["map"]) { if let Some(arglists) = method_chain_args(expr, &["map"]) {
lint_map_unit_fn(cx, stmt, expr, arglists[0]); lint_map_unit_fn(cx, stmt, expr, arglists[0]);
} }

View File

@ -184,14 +184,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass {
if in_external_macro(cx, expr.span) { if in_external_macro(cx, expr.span) {
return; return;
} }
if let ExprMatch(ref ex, ref arms, MatchSource::Normal) = expr.node { if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.node {
check_single_match(cx, ex, arms, expr); check_single_match(cx, ex, arms, expr);
check_match_bool(cx, ex, arms, expr); check_match_bool(cx, ex, arms, expr);
check_overlapping_arms(cx, ex, arms); check_overlapping_arms(cx, ex, arms);
check_wild_err_arm(cx, ex, arms); check_wild_err_arm(cx, ex, arms);
check_match_as_ref(cx, ex, arms, expr); check_match_as_ref(cx, ex, arms, expr);
} }
if let ExprMatch(ref ex, ref arms, _) = expr.node { if let ExprKind::Match(ref ex, ref arms, _) = expr.node {
check_match_ref_pats(cx, ex, arms, expr); check_match_ref_pats(cx, ex, arms, expr);
} }
} }
@ -205,7 +205,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
let els = remove_blocks(&arms[1].body); let els = remove_blocks(&arms[1].body);
let els = if is_unit_expr(els) { let els = if is_unit_expr(els) {
None None
} else if let ExprBlock(_, _) = els.node { } else if let ExprKind::Block(_, _) = els.node {
// matches with blocks that contain statements are prettier as `if let + else` // matches with blocks that contain statements are prettier as `if let + else`
Some(els) Some(els)
} else { } else {
@ -294,7 +294,7 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
if arms.len() == 2 && arms[0].pats.len() == 1 { if arms.len() == 2 && arms[0].pats.len() == 1 {
// no guards // no guards
let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node { let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node {
if let ExprLit(ref lit) = arm_bool.node { if let ExprKind::Lit(ref lit) = arm_bool.node {
match lit.node { match lit.node {
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)), LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)), LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
@ -372,7 +372,7 @@ fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
if_chain! { if_chain! {
if path_str == "Err"; if path_str == "Err";
if inner.iter().any(is_wild); if inner.iter().any(is_wild);
if let ExprBlock(ref block, _) = arm.body.node; if let ExprKind::Block(ref block, _) = arm.body.node;
if is_panic_block(block); if is_panic_block(block);
then { then {
// `Err(_)` arm with `panic!` found // `Err(_)` arm with `panic!` found
@ -406,7 +406,7 @@ fn is_panic_block(block: &Block) -> bool {
fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
if has_only_ref_pats(arms) { if has_only_ref_pats(arms) {
let mut suggs = Vec::new(); let mut suggs = Vec::new();
let (title, msg) = if let ExprAddrOf(Mutability::MutImmutable, ref inner) = ex.node { let (title, msg) = if let ExprKind::AddrOf(Mutability::MutImmutable, ref inner) = ex.node {
suggs.push((ex.span, Sugg::hir(cx, inner, "..").to_string())); suggs.push((ex.span, Sugg::hir(cx, inner, "..").to_string()));
( (
"you don't need to add `&` to both the expression and the patterns", "you don't need to add `&` to both the expression and the patterns",
@ -540,8 +540,8 @@ fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {
fn is_unit_expr(expr: &Expr) -> bool { fn is_unit_expr(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprTup(ref v) if v.is_empty() => true, ExprKind::Tup(ref v) if v.is_empty() => true,
ExprBlock(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true, ExprKind::Block(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true,
_ => false, _ => false,
} }
} }
@ -561,10 +561,10 @@ fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME); if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
if let PatKind::Binding(rb, _, ident, _) = pats[0].node; if let PatKind::Binding(rb, _, ident, _) = pats[0].node;
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut; if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
if let ExprCall(ref e, ref args) = remove_blocks(&arm.body).node; if let ExprKind::Call(ref e, ref args) = remove_blocks(&arm.body).node;
if let ExprPath(ref some_path) = e.node; if let ExprKind::Path(ref some_path) = e.node;
if match_qpath(some_path, &paths::OPTION_SOME) && args.len() == 1; if match_qpath(some_path, &paths::OPTION_SOME) && args.len() == 1;
if let ExprPath(ref qpath) = args[0].node; if let ExprKind::Path(ref qpath) = args[0].node;
if let &QPath::Resolved(_, ref path2) = qpath; if let &QPath::Resolved(_, ref path2) = qpath;
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name; if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
then { then {

View File

@ -1,5 +1,5 @@
use rustc::lint::*; use rustc::lint::*;
use rustc::hir::{Expr, ExprCall, ExprPath}; use rustc::hir::{Expr, ExprKind};
use crate::utils::{match_def_path, opt_def_id, paths, span_lint}; use crate::utils::{match_def_path, opt_def_id, paths, span_lint};
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is /// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
@ -30,8 +30,8 @@ impl LintPass for MemForget {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget { 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 ExprKind::Call(ref path_expr, ref args) = e.node {
if let ExprPath(ref qpath) = path_expr.node { if let ExprKind::Path(ref qpath) = path_expr.node {
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) { if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) {
if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) { if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
let forgot_ty = cx.tables.expr_ty(&args[0]); let forgot_ty = cx.tables.expr_ty(&args[0]);

View File

@ -718,7 +718,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
match expr.node { match expr.node {
hir::ExprMethodCall(ref method_call, ref method_span, ref args) => { hir::ExprKind::MethodCall(ref method_call, ref method_span, ref args) => {
// Chain calls // Chain calls
// GET_UNWRAP needs to be checked before general `UNWRAP` lints // GET_UNWRAP needs to be checked before general `UNWRAP` lints
if let Some(arglists) = method_chain_args(expr, &["get", "unwrap"]) { if let Some(arglists) = method_chain_args(expr, &["get", "unwrap"]) {
@ -789,12 +789,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
_ => (), _ => (),
} }
}, },
hir::ExprBinary(op, ref lhs, ref rhs) if op.node == hir::BiEq || op.node == hir::BiNe => { hir::ExprKind::Binary(op, ref lhs, ref rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
let mut info = BinaryExprInfo { let mut info = BinaryExprInfo {
expr, expr,
chain: lhs, chain: lhs,
other: rhs, other: rhs,
eq: op.node == hir::BiEq, eq: op.node == hir::BinOpKind::Eq,
}; };
lint_binary_expr_with_method_call(cx, &mut info); lint_binary_expr_with_method_call(cx, &mut info);
}, },
@ -813,7 +813,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if let hir::ImplItemKind::Method(ref sig, id) = implitem.node; if let hir::ImplItemKind::Method(ref sig, id) = implitem.node;
if let Some(first_arg_ty) = sig.decl.inputs.get(0); if let Some(first_arg_ty) = sig.decl.inputs.get(0);
if let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir.body(id)).next(); if let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir.body(id)).next();
if let hir::ItemImpl(_, _, _, _, None, ref self_ty, _) = item.node; if let hir::ItemKind::Impl(_, _, _, _, None, ref self_ty, _) = item.node;
then { then {
if cx.access_levels.is_exported(implitem.id) { if cx.access_levels.is_exported(implitem.id) {
// check missing trait implementations // check missing trait implementations
@ -889,7 +889,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name:
} }
if name == "unwrap_or" { if name == "unwrap_or" {
if let hir::ExprPath(ref qpath) = fun.node { if let hir::ExprKind::Path(ref qpath) = fun.node {
let path = &*last_path_segment(qpath).ident.as_str(); let path = &*last_path_segment(qpath).ident.as_str();
if ["default", "new"].contains(&path) { if ["default", "new"].contains(&path) {
@ -982,13 +982,13 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name:
if args.len() == 2 { if args.len() == 2 {
match args[1].node { match args[1].node {
hir::ExprCall(ref fun, ref or_args) => { hir::ExprKind::Call(ref fun, ref or_args) => {
let or_has_args = !or_args.is_empty(); let or_has_args = !or_args.is_empty();
if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) { if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) {
check_general_case(cx, name, method_span, fun.span, &args[0], &args[1], or_has_args, expr.span); check_general_case(cx, name, method_span, fun.span, &args[0], &args[1], or_has_args, expr.span);
} }
}, },
hir::ExprMethodCall(_, span, ref or_args) => { hir::ExprKind::MethodCall(_, span, ref or_args) => {
check_general_case(cx, name, method_span, span, &args[0], &args[1], !or_args.is_empty(), expr.span) check_general_case(cx, name, method_span, span, &args[0], &args[1], !or_args.is_empty(), expr.span)
}, },
_ => {}, _ => {},
@ -999,10 +999,10 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name:
/// Checks for the `EXPECT_FUN_CALL` lint. /// Checks for the `EXPECT_FUN_CALL` lint.
fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) { fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) {
fn extract_format_args(arg: &hir::Expr) -> Option<&hir::HirVec<hir::Expr>> { fn extract_format_args(arg: &hir::Expr) -> Option<&hir::HirVec<hir::Expr>> {
if let hir::ExprAddrOf(_, ref addr_of) = arg.node { if let hir::ExprKind::AddrOf(_, ref addr_of) = arg.node {
if let hir::ExprCall(ref inner_fun, ref inner_args) = addr_of.node { if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = addr_of.node {
if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 { if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 {
if let hir::ExprCall(_, ref format_args) = inner_args[0].node { if let hir::ExprKind::Call(_, ref format_args) = inner_args[0].node {
return Some(format_args); return Some(format_args);
} }
} }
@ -1013,9 +1013,9 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n
} }
fn generate_format_arg_snippet(cx: &LateContext, a: &hir::Expr) -> String { fn generate_format_arg_snippet(cx: &LateContext, a: &hir::Expr) -> String {
if let hir::ExprAddrOf(_, ref format_arg) = a.node { if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node {
if let hir::ExprMatch(ref format_arg_expr, _, _) = format_arg.node { if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.node {
if let hir::ExprTup(ref format_arg_expr_tup) = format_arg_expr.node { if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.node {
return snippet(cx, format_arg_expr_tup[0].span, "..").into_owned(); return snippet(cx, format_arg_expr_tup[0].span, "..").into_owned();
} }
} }
@ -1090,7 +1090,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n
if args.len() == 2 { if args.len() == 2 {
match args[1].node { match args[1].node {
hir::ExprLit(_) => {}, hir::ExprKind::Lit(_) => {},
_ => check_general_case(cx, name, method_span, &args[0], &args[1], expr.span), _ => check_general_case(cx, name, method_span, &args[0], &args[1], expr.span),
} }
} }
@ -1133,14 +1133,14 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
match cx.tcx.hir.get(parent) { match cx.tcx.hir.get(parent) {
hir::map::NodeExpr(parent) => match parent.node { hir::map::NodeExpr(parent) => match parent.node {
// &*x is a nop, &x.clone() is not // &*x is a nop, &x.clone() is not
hir::ExprAddrOf(..) | hir::ExprKind::AddrOf(..) |
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably // (*x).func() is useless, x.clone().func() can work in case func borrows mutably
hir::ExprMethodCall(..) => return, hir::ExprKind::MethodCall(..) => return,
_ => {}, _ => {},
} }
hir::map::NodeStmt(stmt) => { hir::map::NodeStmt(stmt) => {
if let hir::StmtDecl(ref decl, _) = stmt.node { if let hir::StmtKind::Decl(ref decl, _) = stmt.node {
if let hir::DeclLocal(ref loc) = decl.node { if let hir::DeclKind::Local(ref loc) = decl.node {
if let hir::PatKind::Ref(..) = loc.pat.node { if let hir::PatKind::Ref(..) = loc.pat.node {
// let ref y = *x borrows x, let ref y = x.clone() does not // let ref y = *x borrows x, let ref y = x.clone() does not
return; return;
@ -1229,9 +1229,9 @@ fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwrap: &hir::Expr) { fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwrap: &hir::Expr) {
if_chain! { if_chain! {
if let hir::ExprCall(ref fun, ref args) = new.node; if let hir::ExprKind::Call(ref fun, ref args) = new.node;
if args.len() == 1; if args.len() == 1;
if let hir::ExprPath(ref path) = fun.node; if let hir::ExprKind::Path(ref path) = fun.node;
if let Def::Method(did) = cx.tables.qpath_def(path, fun.hir_id); if let Def::Method(did) = cx.tables.qpath_def(path, fun.hir_id);
if match_def_path(cx.tcx, did, &paths::CSTRING_NEW); if match_def_path(cx.tcx, did, &paths::CSTRING_NEW);
then { then {
@ -1274,18 +1274,18 @@ fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::E
fn check_fold_with_op( fn check_fold_with_op(
cx: &LateContext, cx: &LateContext,
fold_args: &[hir::Expr], fold_args: &[hir::Expr],
op: hir::BinOp_, op: hir::BinOpKind,
replacement_method_name: &str, replacement_method_name: &str,
replacement_has_args: bool) { replacement_has_args: bool) {
if_chain! { if_chain! {
// Extract the body of the closure passed to fold // Extract the body of the closure passed to fold
if let hir::ExprClosure(_, _, body_id, _, _) = fold_args[2].node; if let hir::ExprKind::Closure(_, _, body_id, _, _) = fold_args[2].node;
let closure_body = cx.tcx.hir.body(body_id); let closure_body = cx.tcx.hir.body(body_id);
let closure_expr = remove_blocks(&closure_body.value); let closure_expr = remove_blocks(&closure_body.value);
// Check if the closure body is of the form `acc <op> some_expr(x)` // Check if the closure body is of the form `acc <op> some_expr(x)`
if let hir::ExprBinary(ref bin_op, ref left_expr, ref right_expr) = closure_expr.node; if let hir::ExprKind::Binary(ref bin_op, ref left_expr, ref right_expr) = closure_expr.node;
if bin_op.node == op; if bin_op.node == op;
// Extract the names of the two arguments to the closure // Extract the names of the two arguments to the closure
@ -1329,19 +1329,19 @@ fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::E
// Check if the first argument to .fold is a suitable literal // Check if the first argument to .fold is a suitable literal
match fold_args[1].node { match fold_args[1].node {
hir::ExprLit(ref lit) => { hir::ExprKind::Lit(ref lit) => {
match lit.node { match lit.node {
ast::LitKind::Bool(false) => check_fold_with_op( ast::LitKind::Bool(false) => check_fold_with_op(
cx, fold_args, hir::BinOp_::BiOr, "any", true cx, fold_args, hir::BinOpKind::Or, "any", true
), ),
ast::LitKind::Bool(true) => check_fold_with_op( ast::LitKind::Bool(true) => check_fold_with_op(
cx, fold_args, hir::BinOp_::BiAnd, "all", true cx, fold_args, hir::BinOpKind::And, "all", true
), ),
ast::LitKind::Int(0, _) => check_fold_with_op( ast::LitKind::Int(0, _) => check_fold_with_op(
cx, fold_args, hir::BinOp_::BiAdd, "sum", false cx, fold_args, hir::BinOpKind::Add, "sum", false
), ),
ast::LitKind::Int(1, _) => check_fold_with_op( ast::LitKind::Int(1, _) => check_fold_with_op(
cx, fold_args, hir::BinOp_::BiMul, "product", false cx, fold_args, hir::BinOpKind::Mul, "product", false
), ),
_ => return _ => return
} }
@ -1437,7 +1437,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: Ty) -> Option<sugg::S
} }
} }
if let hir::ExprMethodCall(ref path, _, ref args) = expr.node { if let hir::ExprKind::MethodCall(ref path, _, ref args) = expr.node {
if path.ident.name == "iter" && may_slice(cx, cx.tables.expr_ty(&args[0])) { if path.ident.name == "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 {
@ -1615,7 +1615,7 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(
fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_or_args: &'tcx [hir::Expr]) { fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_or_args: &'tcx [hir::Expr]) {
if match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::OPTION) { if match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::OPTION) {
// check if the first non-self argument to map_or() is None // check if the first non-self argument to map_or() is None
let map_or_arg_is_none = if let hir::Expr_::ExprPath(ref qpath) = map_or_args[1].node { let map_or_arg_is_none = if let hir::ExprKind::Path(ref qpath) = map_or_args[1].node {
match_qpath(qpath, &paths::OPTION_NONE) match_qpath(qpath, &paths::OPTION_NONE)
} else { } else {
false false
@ -1790,9 +1790,9 @@ fn lint_chars_cmp<'a, 'tcx>(
) -> bool { ) -> bool {
if_chain! { if_chain! {
if let Some(args) = method_chain_args(info.chain, chain_methods); if let Some(args) = method_chain_args(info.chain, chain_methods);
if let hir::ExprCall(ref fun, ref arg_char) = info.other.node; if let hir::ExprKind::Call(ref fun, ref arg_char) = info.other.node;
if arg_char.len() == 1; if arg_char.len() == 1;
if let hir::ExprPath(ref qpath) = fun.node; if let hir::ExprKind::Path(ref qpath) = fun.node;
if let Some(segment) = single_segment_path(qpath); if let Some(segment) = single_segment_path(qpath);
if segment.ident.name == "Some"; if segment.ident.name == "Some";
then { then {
@ -1844,7 +1844,7 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
) -> bool { ) -> bool {
if_chain! { if_chain! {
if let Some(args) = method_chain_args(info.chain, chain_methods); if let Some(args) = method_chain_args(info.chain, chain_methods);
if let hir::ExprLit(ref lit) = info.other.node; if let hir::ExprKind::Lit(ref lit) = info.other.node;
if let ast::LitKind::Char(c) = lit.node; if let ast::LitKind::Char(c) = lit.node;
then { then {
span_lint_and_sugg( span_lint_and_sugg(
@ -2057,7 +2057,7 @@ impl SelfKind {
return true; return true;
} }
match ty.node { match ty.node {
hir::TyRptr(_, ref mt_ty) => { hir::TyKind::Rptr(_, ref mt_ty) => {
let mutability_match = if self == SelfKind::Ref { let mutability_match = if self == SelfKind::Ref {
mt_ty.mutbl == hir::MutImmutable mt_ty.mutbl == hir::MutImmutable
} else { } else {
@ -2128,8 +2128,8 @@ fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Gener
fn is_ty(ty: &hir::Ty, self_ty: &hir::Ty) -> bool { fn is_ty(ty: &hir::Ty, self_ty: &hir::Ty) -> bool {
match (&ty.node, &self_ty.node) { match (&ty.node, &self_ty.node) {
( (
&hir::TyPath(hir::QPath::Resolved(_, ref ty_path)), &hir::TyKind::Path(hir::QPath::Resolved(_, ref ty_path)),
&hir::TyPath(hir::QPath::Resolved(_, ref self_ty_path)), &hir::TyKind::Path(hir::QPath::Resolved(_, ref self_ty_path)),
) => ty_path ) => ty_path
.segments .segments
.iter() .iter()
@ -2140,7 +2140,7 @@ fn is_ty(ty: &hir::Ty, self_ty: &hir::Ty) -> bool {
} }
fn single_segment_ty(ty: &hir::Ty) -> Option<&hir::PathSegment> { fn single_segment_ty(ty: &hir::Ty) -> Option<&hir::PathSegment> {
if let hir::TyPath(ref path) = ty.node { if let hir::TyKind::Path(ref path) = ty.node {
single_segment_path(path) single_segment_path(path)
} else { } else {
None None
@ -2175,20 +2175,20 @@ enum OutType {
impl OutType { impl OutType {
fn matches(self, cx: &LateContext, ty: &hir::FunctionRetTy) -> bool { fn matches(self, cx: &LateContext, ty: &hir::FunctionRetTy) -> bool {
let is_unit = |ty: &hir::Ty| SpanlessEq::new(cx).eq_ty_kind(&ty.node, &hir::TyTup(vec![].into())); let is_unit = |ty: &hir::Ty| SpanlessEq::new(cx).eq_ty_kind(&ty.node, &hir::TyKind::Tup(vec![].into()));
match (self, ty) { match (self, ty) {
(OutType::Unit, &hir::DefaultReturn(_)) => true, (OutType::Unit, &hir::DefaultReturn(_)) => true,
(OutType::Unit, &hir::Return(ref ty)) if is_unit(ty) => true, (OutType::Unit, &hir::Return(ref ty)) if is_unit(ty) => true,
(OutType::Bool, &hir::Return(ref ty)) if is_bool(ty) => true, (OutType::Bool, &hir::Return(ref ty)) if is_bool(ty) => true,
(OutType::Any, &hir::Return(ref ty)) if !is_unit(ty) => true, (OutType::Any, &hir::Return(ref ty)) if !is_unit(ty) => true,
(OutType::Ref, &hir::Return(ref ty)) => matches!(ty.node, hir::TyRptr(_, _)), (OutType::Ref, &hir::Return(ref ty)) => matches!(ty.node, hir::TyKind::Rptr(_, _)),
_ => false, _ => false,
} }
} }
} }
fn is_bool(ty: &hir::Ty) -> bool { fn is_bool(ty: &hir::Ty) -> bool {
if let hir::TyPath(ref p) = ty.node { if let hir::TyKind::Path(ref p) = ty.node {
match_qpath(p, &["bool"]) match_qpath(p, &["bool"])
} else { } else {
false false

View File

@ -66,8 +66,8 @@ 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 ExprKind::Call(ref path, ref args) = expr.node {
if let ExprPath(ref qpath) = path.node { if let ExprKind::Path(ref qpath) = path.node {
opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)).and_then(|def_id| { opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)).and_then(|def_id| {
if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) { if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) {
fetch_const(cx, args, MinMax::Min) fetch_const(cx, args, MinMax::Min)

View File

@ -269,8 +269,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, s: &'tcx Stmt) { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, s: &'tcx Stmt) {
if_chain! { if_chain! {
if let StmtDecl(ref d, _) = s.node; if let StmtKind::Decl(ref d, _) = s.node;
if let DeclLocal(ref l) = d.node; if let DeclKind::Local(ref l) = d.node;
if let PatKind::Binding(an, _, i, None) = l.pat.node; if let PatKind::Binding(an, _, i, None) = l.pat.node;
if let Some(ref init) = l.init; if let Some(ref init) = l.init;
then { then {
@ -303,9 +303,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
}; };
if_chain! { if_chain! {
if let StmtSemi(ref expr, _) = s.node; if let StmtKind::Semi(ref expr, _) = s.node;
if let Expr_::ExprBinary(ref binop, ref a, ref b) = expr.node; if let ExprKind::Binary(ref binop, ref a, ref b) = expr.node;
if binop.node == BiAnd || binop.node == BiOr; if binop.node == BinOpKind::And || binop.node == BinOpKind::Or;
if let Some(sugg) = Sugg::hir_opt(cx, a); if let Some(sugg) = Sugg::hir_opt(cx, a);
then { then {
span_lint_and_then(cx, span_lint_and_then(cx,
@ -313,7 +313,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
s.span, s.span,
"boolean short circuit operator in statement may be clearer using an explicit test", "boolean short circuit operator in statement may be clearer using an explicit test",
|db| { |db| {
let sugg = if binop.node == BiOr { !sugg } else { sugg }; let sugg = if binop.node == BinOpKind::Or { !sugg } else { sugg };
db.span_suggestion(s.span, "replace it with", db.span_suggestion(s.span, "replace it with",
format!("if {} {{ {}; }}", sugg, &snippet(cx, b.span, ".."))); format!("if {} {{ {}; }}", sugg, &snippet(cx, b.span, "..")));
}); });
@ -323,23 +323,23 @@ 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) {
match expr.node { match expr.node {
ExprCast(ref e, ref ty) => { ExprKind::Cast(ref e, ref ty) => {
check_cast(cx, expr.span, e, ty); check_cast(cx, expr.span, e, ty);
return; return;
}, },
ExprBinary(ref cmp, ref left, ref right) => { ExprKind::Binary(ref cmp, ref left, ref right) => {
let op = cmp.node; let op = cmp.node;
if op.is_comparison() { if op.is_comparison() {
if let ExprPath(QPath::Resolved(_, ref path)) = left.node { if let ExprKind::Path(QPath::Resolved(_, ref path)) = left.node {
check_nan(cx, path, expr); check_nan(cx, path, expr);
} }
if let ExprPath(QPath::Resolved(_, ref path)) = right.node { if let ExprKind::Path(QPath::Resolved(_, ref path)) = right.node {
check_nan(cx, path, expr); check_nan(cx, path, expr);
} }
check_to_owned(cx, left, right); check_to_owned(cx, left, right);
check_to_owned(cx, right, left); check_to_owned(cx, right, left);
} }
if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) { if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) {
if is_allowed(cx, left) || is_allowed(cx, right) { if is_allowed(cx, left) || is_allowed(cx, right) {
return; return;
} }
@ -367,7 +367,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
); );
db.span_note(expr.span, "std::f32::EPSILON and std::f64::EPSILON are available."); db.span_note(expr.span, "std::f32::EPSILON and std::f64::EPSILON are available.");
}); });
} else if op == BiRem && is_integer_literal(right, 1) { } else if op == BinOpKind::Rem && is_integer_literal(right, 1) {
span_lint(cx, MODULO_ONE, expr.span, "any number modulo 1 will be 0"); span_lint(cx, MODULO_ONE, expr.span, "any number modulo 1 will be 0");
} }
}, },
@ -378,7 +378,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
return; return;
} }
let binding = match expr.node { let binding = match expr.node {
ExprPath(ref qpath) => { ExprKind::Path(ref qpath) => {
let binding = last_path_segment(qpath).ident.as_str(); let binding = last_path_segment(qpath).ident.as_str();
if binding.starts_with('_') && if binding.starts_with('_') &&
!binding.starts_with("__") && !binding.starts_with("__") &&
@ -392,7 +392,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
None None
} }
}, },
ExprField(_, ident) => { ExprKind::Field(_, ident) => {
let name = ident.as_str(); let name = ident.as_str();
if name.starts_with('_') && !name.starts_with("__") { if name.starts_with('_') && !name.starts_with("__") {
Some(name) Some(name)
@ -467,14 +467,14 @@ fn is_float(cx: &LateContext, expr: &Expr) -> bool {
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) {
let (arg_ty, snip) = match expr.node { let (arg_ty, snip) = match expr.node {
ExprMethodCall(.., ref args) if args.len() == 1 => { ExprKind::MethodCall(.., ref args) if args.len() == 1 => {
if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) {
(cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) (cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, ".."))
} else { } else {
return; return;
} }
}, },
ExprCall(ref path, ref v) if v.len() == 1 => if let ExprPath(ref path) = path.node { ExprKind::Call(ref path, ref v) if v.len() == 1 => if let ExprKind::Path(ref path) = path.node {
if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) { if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) {
(cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, "..")) (cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, ".."))
} else { } else {
@ -520,7 +520,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) {
let parent_impl = cx.tcx.hir.get_parent(parent_fn); let parent_impl = cx.tcx.hir.get_parent(parent_fn);
if parent_impl != CRATE_NODE_ID { if parent_impl != CRATE_NODE_ID {
if let map::NodeItem(item) = cx.tcx.hir.get(parent_impl) { if let map::NodeItem(item) = cx.tcx.hir.get(parent_impl) {
if let ItemImpl(.., Some(ref trait_ref), _, _) = item.node { if let ItemKind::Impl(.., Some(ref trait_ref), _, _) = item.node {
if trait_ref.path.def.def_id() == partial_eq_trait_id { if trait_ref.path.def.def_id() == partial_eq_trait_id {
// we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise // we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise
// we go into // we go into
@ -542,7 +542,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) {
fn is_used(cx: &LateContext, expr: &Expr) -> bool { fn is_used(cx: &LateContext, expr: &Expr) -> bool {
if let Some(parent) = get_parent_expr(cx, expr) { if let Some(parent) = get_parent_expr(cx, expr) {
match parent.node { match parent.node {
ExprAssign(_, ref rhs) | ExprAssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr), ExprKind::Assign(_, ref rhs) | ExprKind::AssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr),
_ => is_used(cx, parent), _ => is_used(cx, parent),
} }
} else { } else {
@ -571,8 +571,8 @@ fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool {
fn check_cast(cx: &LateContext, span: Span, e: &Expr, ty: &Ty) { fn check_cast(cx: &LateContext, span: Span, e: &Expr, ty: &Ty) {
if_chain! { if_chain! {
if let TyPtr(MutTy { mutbl, .. }) = ty.node; if let TyKind::Ptr(MutTy { mutbl, .. }) = ty.node;
if let ExprLit(ref lit) = e.node; if let ExprKind::Lit(ref lit) = e.node;
if let LitKind::Int(value, ..) = lit.node; if let LitKind::Int(value, ..) = lit.node;
if value == 0; if value == 0;
if !in_constant(cx, e.id); if !in_constant(cx, e.id);

View File

@ -122,9 +122,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item) { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item) {
let desc = match it.node { let desc = match it.node {
hir::ItemConst(..) => "a constant", hir::ItemKind::Const(..) => "a constant",
hir::ItemEnum(..) => "an enum", hir::ItemKind::Enum(..) => "an enum",
hir::ItemFn(..) => { hir::ItemKind::Fn(..) => {
// ignore main() // ignore main()
if it.name == "main" { if it.name == "main" {
let def_id = cx.tcx.hir.local_def_id(it.id); let def_id = cx.tcx.hir.local_def_id(it.id);
@ -135,19 +135,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
} }
"a function" "a function"
}, },
hir::ItemMod(..) => "a module", hir::ItemKind::Mod(..) => "a module",
hir::ItemStatic(..) => "a static", hir::ItemKind::Static(..) => "a static",
hir::ItemStruct(..) => "a struct", hir::ItemKind::Struct(..) => "a struct",
hir::ItemTrait(..) => "a trait", hir::ItemKind::Trait(..) => "a trait",
hir::ItemTraitAlias(..) => "a trait alias", hir::ItemKind::TraitAlias(..) => "a trait alias",
hir::ItemGlobalAsm(..) => "an assembly blob", hir::ItemKind::GlobalAsm(..) => "an assembly blob",
hir::ItemTy(..) => "a type alias", hir::ItemKind::Ty(..) => "a type alias",
hir::ItemUnion(..) => "a union", hir::ItemKind::Union(..) => "a union",
hir::ItemExistential(..) => "an existential type", hir::ItemKind::Existential(..) => "an existential type",
hir::ItemExternCrate(..) | hir::ItemKind::ExternCrate(..) |
hir::ItemForeignMod(..) | hir::ItemKind::ForeignMod(..) |
hir::ItemImpl(..) | hir::ItemKind::Impl(..) |
hir::ItemUse(..) => return, hir::ItemKind::Use(..) => return,
}; };
self.check_missing_docs_attrs(cx, &it.attrs, it.span, desc); self.check_missing_docs_attrs(cx, &it.attrs, it.span, desc);

View File

@ -108,11 +108,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
return; return;
} }
match it.node { match it.node {
hir::ItemFn(..) => { hir::ItemKind::Fn(..) => {
let desc = "a function"; let desc = "a function";
check_missing_inline_attrs(cx, &it.attrs, it.span, desc); check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
}, },
hir::ItemTrait(ref _is_auto, ref _unsafe, ref _generics, hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics,
ref _bounds, ref trait_items) => { ref _bounds, ref trait_items) => {
// note: we need to check if the trait is exported so we can't use // note: we need to check if the trait is exported so we can't use
// `LateLintPass::check_trait_item` here. // `LateLintPass::check_trait_item` here.
@ -134,20 +134,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
} }
} }
} }
hir::ItemConst(..) | hir::ItemKind::Const(..) |
hir::ItemEnum(..) | hir::ItemKind::Enum(..) |
hir::ItemMod(..) | hir::ItemKind::Mod(..) |
hir::ItemStatic(..) | hir::ItemKind::Static(..) |
hir::ItemStruct(..) | hir::ItemKind::Struct(..) |
hir::ItemTraitAlias(..) | hir::ItemKind::TraitAlias(..) |
hir::ItemGlobalAsm(..) | hir::ItemKind::GlobalAsm(..) |
hir::ItemTy(..) | hir::ItemKind::Ty(..) |
hir::ItemUnion(..) | hir::ItemKind::Union(..) |
hir::ItemExistential(..) | hir::ItemKind::Existential(..) |
hir::ItemExternCrate(..) | hir::ItemKind::ExternCrate(..) |
hir::ItemForeignMod(..) | hir::ItemKind::ForeignMod(..) |
hir::ItemImpl(..) | hir::ItemKind::Impl(..) |
hir::ItemUse(..) => {}, hir::ItemKind::Use(..) => {},
}; };
} }

View File

@ -62,8 +62,8 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
// Let's ignore the generated code. // Let's ignore the generated code.
intravisit::walk_expr(self, arg); intravisit::walk_expr(self, arg);
intravisit::walk_expr(self, body); intravisit::walk_expr(self, body);
} else if let hir::ExprAddrOf(hir::MutMutable, ref e) = expr.node { } else if let hir::ExprKind::AddrOf(hir::MutMutable, ref e) = expr.node {
if let hir::ExprAddrOf(hir::MutMutable, _) = e.node { if let hir::ExprKind::AddrOf(hir::MutMutable, _) = e.node {
span_lint( span_lint(
self.cx, self.cx,
MUT_MUT, MUT_MUT,
@ -87,7 +87,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
} }
fn visit_ty(&mut self, ty: &'tcx hir::Ty) { fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
if let hir::TyRptr( if let hir::TyKind::Rptr(
_, _,
hir::MutTy { hir::MutTy {
ty: ref pty, ty: ref pty,
@ -95,7 +95,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
}, },
) = ty.node ) = ty.node
{ {
if let hir::TyRptr( if let hir::TyKind::Rptr(
_, _,
hir::MutTy { hir::MutTy {
mutbl: hir::MutMutable, mutbl: hir::MutMutable,

View File

@ -36,7 +36,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) {
match e.node { match e.node {
ExprCall(ref fn_expr, ref arguments) => if let ExprPath(ref path) = fn_expr.node { ExprKind::Call(ref fn_expr, ref arguments) => if let ExprKind::Path(ref path) = fn_expr.node {
check_arguments( check_arguments(
cx, cx,
arguments, arguments,
@ -44,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
&print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)), &print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)),
); );
}, },
ExprMethodCall(ref path, _, ref arguments) => { ExprKind::MethodCall(ref path, _, ref arguments) => {
let def_id = cx.tables.type_dependent_defs()[e.hir_id].def_id(); let def_id = cx.tables.type_dependent_defs()[e.hir_id].def_id();
let substs = cx.tables.node_substs(e.hir_id); let substs = cx.tables.node_substs(e.hir_id);
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
@ -69,7 +69,7 @@ fn check_arguments<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arguments: &[Expr], typ
ty::TyRawPtr(ty::TypeAndMut { ty::TyRawPtr(ty::TypeAndMut {
mutbl: MutImmutable, mutbl: MutImmutable,
.. ..
}) => if let ExprAddrOf(MutMutable, _) = argument.node { }) => if let ExprKind::AddrOf(MutMutable, _) = argument.node {
span_lint( span_lint(
cx, cx,
UNNECESSARY_MUT_PASSED, UNNECESSARY_MUT_PASSED,

View File

@ -60,7 +60,7 @@ impl LintPass for NeedlessBool {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
use self::Expression::*; use self::Expression::*;
if let ExprIf(ref pred, ref then_block, Some(ref else_expr)) = e.node { if let ExprKind::If(ref pred, ref then_block, Some(ref else_expr)) = e.node {
let reduce = |ret, not| { let reduce = |ret, not| {
let snip = Sugg::hir(cx, pred, "<predicate>"); let snip = Sugg::hir(cx, pred, "<predicate>");
let snip = if not { !snip } else { snip }; let snip = if not { !snip } else { snip };
@ -80,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
hint, hint,
); );
}; };
if let ExprBlock(ref then_block, _) = then_block.node { if let ExprKind::Block(ref then_block, _) = then_block.node {
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) { match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
(RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => { (RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => {
span_lint( span_lint(
@ -105,7 +105,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
_ => (), _ => (),
} }
} else { } else {
panic!("IfExpr 'then' node is not an ExprBlock"); panic!("IfExpr 'then' node is not an ExprKind::Block");
} }
} }
} }
@ -123,7 +123,7 @@ impl LintPass for BoolComparison {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
use self::Expression::*; use self::Expression::*;
if let ExprBinary(Spanned { node: BiEq, .. }, ref left_side, ref right_side) = e.node { if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node {
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) { match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
(Bool(true), Other) => { (Bool(true), Other) => {
let hint = snippet(cx, right_side.span, "..").into_owned(); let hint = snippet(cx, right_side.span, "..").into_owned();
@ -184,8 +184,8 @@ enum Expression {
fn fetch_bool_block(block: &Block) -> Expression { fn fetch_bool_block(block: &Block) -> Expression {
match (&*block.stmts, block.expr.as_ref()) { match (&*block.stmts, block.expr.as_ref()) {
(&[], Some(e)) => fetch_bool_expr(&**e), (&[], Some(e)) => fetch_bool_expr(&**e),
(&[ref e], None) => if let StmtSemi(ref e, _) = e.node { (&[ref e], None) => if let StmtKind::Semi(ref e, _) = e.node {
if let ExprRet(_) = e.node { if let ExprKind::Ret(_) = e.node {
fetch_bool_expr(&**e) fetch_bool_expr(&**e)
} else { } else {
Expression::Other Expression::Other
@ -199,13 +199,13 @@ fn fetch_bool_block(block: &Block) -> Expression {
fn fetch_bool_expr(expr: &Expr) -> Expression { fn fetch_bool_expr(expr: &Expr) -> Expression {
match expr.node { match expr.node {
ExprBlock(ref block, _) => fetch_bool_block(block), ExprKind::Block(ref block, _) => fetch_bool_block(block),
ExprLit(ref lit_ptr) => if let LitKind::Bool(value) = lit_ptr.node { ExprKind::Lit(ref lit_ptr) => if let LitKind::Bool(value) = lit_ptr.node {
Expression::Bool(value) Expression::Bool(value)
} else { } else {
Expression::Other Expression::Other
}, },
ExprRet(Some(ref expr)) => match fetch_bool_expr(expr) { ExprKind::Ret(Some(ref expr)) => match fetch_bool_expr(expr) {
Expression::Bool(value) => Expression::RetBool(value), Expression::Bool(value) => Expression::RetBool(value),
_ => Expression::Other, _ => Expression::Other,
}, },

View File

@ -3,7 +3,7 @@
//! This lint is **warn** by default //! This lint is **warn** by default
use rustc::lint::*; use rustc::lint::*;
use rustc::hir::{BindingAnnotation, Expr, ExprAddrOf, MutImmutable, Pat, PatKind}; use rustc::hir::{BindingAnnotation, Expr, ExprKind, MutImmutable, Pat, PatKind};
use rustc::ty; use rustc::ty;
use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc::ty::adjustment::{Adjust, Adjustment};
use crate::utils::{in_macro, snippet_opt, span_lint_and_then}; use crate::utils::{in_macro, snippet_opt, span_lint_and_then};
@ -40,7 +40,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
if in_macro(e.span) { if in_macro(e.span) {
return; return;
} }
if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ExprKind::AddrOf(MutImmutable, ref inner) = e.node {
if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty {
for adj3 in cx.tables.expr_adjustments(e).windows(3) { for adj3 in cx.tables.expr_adjustments(e).windows(3) {
if let [Adjustment { if let [Adjustment {

View File

@ -88,8 +88,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
// Exclude non-inherent impls // Exclude non-inherent impls
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) { if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) | if matches!(item.node, ItemKind::Impl(_, _, _, _, Some(_), _, _) |
ItemTrait(..)) ItemKind::Trait(..))
{ {
return; return;
} }
@ -215,7 +215,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
if match_type(cx, ty, &paths::VEC); if match_type(cx, ty, &paths::VEC);
if let Some(clone_spans) = if let Some(clone_spans) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_owned()")]); get_spans(cx, Some(body.id()), idx, &[("clone", ".to_owned()")]);
if let TyPath(QPath::Resolved(_, ref path)) = input.node; if let TyKind::Path(QPath::Resolved(_, ref path)) = input.node;
if let Some(elem_ty) = path.segments.iter() if let Some(elem_ty) = path.segments.iter()
.find(|seg| seg.ident.name == "Vec") .find(|seg| seg.ident.name == "Vec")
.and_then(|ps| ps.args.as_ref()) .and_then(|ps| ps.args.as_ref())
@ -339,7 +339,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
match node { match node {
map::Node::NodeExpr(e) => { map::Node::NodeExpr(e) => {
// `match` and `if let` // `match` and `if let`
if let ExprMatch(ref c, ..) = e.node { if let ExprKind::Match(ref c, ..) = e.node {
self.spans_need_deref self.spans_need_deref
.entry(vid) .entry(vid)
.or_insert_with(HashSet::new) .or_insert_with(HashSet::new)
@ -350,8 +350,8 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
map::Node::NodeStmt(s) => { map::Node::NodeStmt(s) => {
// `let <pat> = x;` // `let <pat> = x;`
if_chain! { if_chain! {
if let StmtDecl(ref decl, _) = s.node; if let StmtKind::Decl(ref decl, _) = s.node;
if let DeclLocal(ref local) = decl.node; if let DeclKind::Local(ref local) = decl.node;
then { then {
self.spans_need_deref self.spans_need_deref
.entry(vid) .entry(vid)

View File

@ -1,6 +1,6 @@
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::ty; use rustc::ty;
use rustc::hir::{Expr, ExprStruct}; use rustc::hir::{Expr, ExprKind};
use crate::utils::span_lint; use crate::utils::span_lint;
/// **What it does:** Checks for needlessly including a base struct on update /// **What it does:** Checks for needlessly including a base struct on update
@ -32,7 +32,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 ExprKind::Struct(_, ref fields, Some(ref base)) = expr.node {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables.expr_ty(expr);
if let ty::TyAdt(def, _) = ty.sty { if let ty::TyAdt(def, _) = ty.sty {
if fields.len() == def.non_enum_variant().fields.len() { if fields.len() == def.non_enum_variant().fields.len() {

View File

@ -18,20 +18,20 @@ use crate::utils::{self, paths, span_lint, in_external_macro};
/// ///
/// ```rust /// ```rust
/// use core::cmp::Ordering; /// use core::cmp::Ordering;
/// ///
/// // Bad /// // Bad
/// let a = 1.0; /// let a = 1.0;
/// let b = std::f64::NAN; /// let b = std::f64::NAN;
/// ///
/// let _not_less_or_equal = !(a <= b); /// let _not_less_or_equal = !(a <= b);
/// ///
/// // Good /// // Good
/// let a = 1.0; /// let a = 1.0;
/// let b = std::f64::NAN; /// let b = std::f64::NAN;
/// ///
/// let _not_less_or_equal = match a.partial_cmp(&b) { /// let _not_less_or_equal = match a.partial_cmp(&b) {
/// None | Some(Ordering::Greater) => true, /// None | Some(Ordering::Greater) => true,
/// _ => false, /// _ => false,
/// }; /// };
/// ``` /// ```
declare_clippy_lint! { declare_clippy_lint! {
@ -54,9 +54,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd {
if_chain! { if_chain! {
if !in_external_macro(cx, expr.span); if !in_external_macro(cx, expr.span);
if let Expr_::ExprUnary(UnOp::UnNot, ref inner) = expr.node; if let ExprKind::Unary(UnOp::UnNot, ref inner) = expr.node;
if let Expr_::ExprBinary(ref op, ref left, _) = inner.node; if let ExprKind::Binary(ref op, ref left, _) = inner.node;
if let BinOp_::BiLe | BinOp_::BiGe | BinOp_::BiLt | BinOp_::BiGt = op.node; if let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node;
then { then {

View File

@ -33,11 +33,11 @@ impl LintPass for NegMultiply {
#[allow(match_same_arms)] #[allow(match_same_arms)]
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
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 ExprBinary(Spanned { node: BiMul, .. }, ref l, ref r) = e.node { if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref l, ref r) = e.node {
match (&l.node, &r.node) { match (&l.node, &r.node) {
(&ExprUnary(..), &ExprUnary(..)) => (), (&ExprKind::Unary(..), &ExprKind::Unary(..)) => (),
(&ExprUnary(UnNeg, ref lit), _) => check_mul(cx, e.span, lit, r), (&ExprKind::Unary(UnNeg, ref lit), _) => check_mul(cx, e.span, lit, r),
(_, &ExprUnary(UnNeg, ref lit)) => check_mul(cx, e.span, lit, l), (_, &ExprKind::Unary(UnNeg, ref lit)) => check_mul(cx, e.span, lit, l),
_ => (), _ => (),
} }
} }
@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) { fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) {
if_chain! { if_chain! {
if let ExprLit(ref l) = lit.node; if let ExprKind::Lit(ref l) = lit.node;
if let Constant::Int(val) = consts::lit_to_constant(&l.node, cx.tables.expr_ty(lit)); if let Constant::Int(val) = consts::lit_to_constant(&l.node, cx.tables.expr_ty(lit));
if val == 1; if val == 1;
if cx.tables.expr_ty(exp).is_integral(); if cx.tables.expr_ty(exp).is_integral();

View File

@ -89,7 +89,7 @@ impl LintPass for NewWithoutDefault {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
if let hir::ItemImpl(_, _, _, _, None, _, ref items) = item.node { if let hir::ItemKind::Impl(_, _, _, _, None, _, ref items) = item.node {
for assoc_item in items { for assoc_item in items {
if let hir::AssociatedItemKind::Method { has_self: false } = assoc_item.kind { if let hir::AssociatedItemKind::Method { has_self: false } = assoc_item.kind {
let impl_item = cx.tcx.hir.impl_item(assoc_item.id); let impl_item = cx.tcx.hir.impl_item(assoc_item.id);

View File

@ -1,6 +1,6 @@
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::hir::def::Def; use rustc::hir::def::Def;
use rustc::hir::{BiAnd, BiOr, BlockCheckMode, Expr, Expr_, Stmt, StmtSemi, UnsafeSource}; use rustc::hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource};
use crate::utils::{has_drop, in_macro, snippet_opt, span_lint, span_lint_and_sugg}; use crate::utils::{has_drop, in_macro, snippet_opt, span_lint, span_lint_and_sugg};
use std::ops::Deref; use std::ops::Deref;
@ -45,26 +45,26 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
return false; return false;
} }
match expr.node { match expr.node {
Expr_::ExprLit(..) | Expr_::ExprClosure(.., _) => true, ExprKind::Lit(..) | ExprKind::Closure(.., _) => true,
Expr_::ExprPath(..) => !has_drop(cx, expr), ExprKind::Path(..) => !has_drop(cx, expr),
Expr_::ExprIndex(ref a, ref b) | Expr_::ExprBinary(_, ref a, ref b) => { ExprKind::Index(ref a, ref b) | ExprKind::Binary(_, ref a, ref b) => {
has_no_effect(cx, a) && has_no_effect(cx, b) has_no_effect(cx, a) && has_no_effect(cx, b)
}, },
Expr_::ExprArray(ref v) | Expr_::ExprTup(ref v) => v.iter().all(|val| has_no_effect(cx, val)), ExprKind::Array(ref v) | ExprKind::Tup(ref v) => v.iter().all(|val| has_no_effect(cx, val)),
Expr_::ExprRepeat(ref inner, _) | ExprKind::Repeat(ref inner, _) |
Expr_::ExprCast(ref inner, _) | ExprKind::Cast(ref inner, _) |
Expr_::ExprType(ref inner, _) | ExprKind::Type(ref inner, _) |
Expr_::ExprUnary(_, ref inner) | ExprKind::Unary(_, ref inner) |
Expr_::ExprField(ref inner, _) | ExprKind::Field(ref inner, _) |
Expr_::ExprAddrOf(_, ref inner) | ExprKind::AddrOf(_, ref inner) |
Expr_::ExprBox(ref inner) => has_no_effect(cx, inner), ExprKind::Box(ref inner) => has_no_effect(cx, inner),
Expr_::ExprStruct(_, ref fields, ref base) => { ExprKind::Struct(_, ref fields, ref base) => {
!has_drop(cx, expr) && fields.iter().all(|field| has_no_effect(cx, &field.expr)) && match *base { !has_drop(cx, expr) && fields.iter().all(|field| has_no_effect(cx, &field.expr)) && match *base {
Some(ref base) => has_no_effect(cx, base), Some(ref base) => has_no_effect(cx, base),
None => true, None => true,
} }
}, },
Expr_::ExprCall(ref callee, ref args) => if let Expr_::ExprPath(ref qpath) = callee.node { ExprKind::Call(ref callee, ref args) => if let ExprKind::Path(ref qpath) = callee.node {
let def = cx.tables.qpath_def(qpath, callee.hir_id); let def = cx.tables.qpath_def(qpath, callee.hir_id);
match def { match def {
Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..) => { Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..) => {
@ -75,7 +75,7 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
} else { } else {
false false
}, },
Expr_::ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
block.stmts.is_empty() && if let Some(ref expr) = block.expr { block.stmts.is_empty() && if let Some(ref expr) = block.expr {
has_no_effect(cx, expr) has_no_effect(cx, expr)
} else { } else {
@ -97,7 +97,7 @@ impl LintPass for Pass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
if let StmtSemi(ref expr, _) = stmt.node { if let StmtKind::Semi(ref expr, _) = stmt.node {
if has_no_effect(cx, expr) { if has_no_effect(cx, expr) {
span_lint(cx, NO_EFFECT, stmt.span, "statement with no effect"); span_lint(cx, NO_EFFECT, stmt.span, "statement with no effect");
} else if let Some(reduced) = reduce_expression(cx, expr) { } else if let Some(reduced) = reduce_expression(cx, expr) {
@ -132,19 +132,19 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
return None; return None;
} }
match expr.node { match expr.node {
Expr_::ExprIndex(ref a, ref b) => Some(vec![&**a, &**b]), ExprKind::Index(ref a, ref b) => Some(vec![&**a, &**b]),
Expr_::ExprBinary(ref binop, ref a, ref b) if binop.node != BiAnd && binop.node != BiOr => { ExprKind::Binary(ref binop, ref a, ref b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {
Some(vec![&**a, &**b]) Some(vec![&**a, &**b])
}, },
Expr_::ExprArray(ref v) | Expr_::ExprTup(ref v) => Some(v.iter().collect()), ExprKind::Array(ref v) | ExprKind::Tup(ref v) => Some(v.iter().collect()),
Expr_::ExprRepeat(ref inner, _) | ExprKind::Repeat(ref inner, _) |
Expr_::ExprCast(ref inner, _) | ExprKind::Cast(ref inner, _) |
Expr_::ExprType(ref inner, _) | ExprKind::Type(ref inner, _) |
Expr_::ExprUnary(_, ref inner) | ExprKind::Unary(_, ref inner) |
Expr_::ExprField(ref inner, _) | ExprKind::Field(ref inner, _) |
Expr_::ExprAddrOf(_, ref inner) | ExprKind::AddrOf(_, ref inner) |
Expr_::ExprBox(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])), ExprKind::Box(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
Expr_::ExprStruct(_, ref fields, ref base) => if has_drop(cx, expr) { ExprKind::Struct(_, ref fields, ref base) => if has_drop(cx, expr) {
None None
} else { } else {
Some( Some(
@ -156,7 +156,7 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
.collect(), .collect(),
) )
}, },
Expr_::ExprCall(ref callee, ref args) => if let Expr_::ExprPath(ref qpath) = callee.node { ExprKind::Call(ref callee, ref args) => if let ExprKind::Path(ref qpath) = callee.node {
let def = cx.tables.qpath_def(qpath, callee.hir_id); let def = cx.tables.qpath_def(qpath, callee.hir_id);
match def { match def {
Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..) Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..)
@ -169,7 +169,7 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
} else { } else {
None None
}, },
Expr_::ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
if block.stmts.is_empty() { if block.stmts.is_empty() {
block.expr.as_ref().and_then(|e| { block.expr.as_ref().and_then(|e| {
match block.rules { match block.rules {

View File

@ -164,7 +164,7 @@ impl LintPass for NonCopyConst {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx Item) { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx Item) {
if let ItemConst(hir_ty, ..) = &it.node { if let ItemKind::Const(hir_ty, ..) = &it.node {
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = hir_ty_to_ty(cx.tcx, hir_ty);
verify_ty_bound(cx, ty, Source::Item { item: it.span }); verify_ty_bound(cx, ty, Source::Item { item: it.span });
} }
@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
let item_node_id = cx.tcx.hir.get_parent_node(impl_item.id); let item_node_id = cx.tcx.hir.get_parent_node(impl_item.id);
let item = cx.tcx.hir.expect_item(item_node_id); let item = cx.tcx.hir.expect_item(item_node_id);
// ensure the impl is an inherent impl. // ensure the impl is an inherent impl.
if let ItemImpl(_, _, _, _, None, _, _) = item.node { if let ItemKind::Impl(_, _, _, _, None, _, _) = item.node {
let ty = hir_ty_to_ty(cx.tcx, hir_ty); let ty = hir_ty_to_ty(cx.tcx, hir_ty);
verify_ty_bound(cx, ty, Source::Assoc { ty: hir_ty.span, item: impl_item.span }); verify_ty_bound(cx, ty, Source::Assoc { ty: hir_ty.span, item: impl_item.span });
} }
@ -190,7 +190,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
} }
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 ExprPath(qpath) = &expr.node { if let ExprKind::Path(qpath) = &expr.node {
// Only lint if we use the const item inside a function. // Only lint if we use the const item inside a function.
if in_constant(cx, expr.id) { if in_constant(cx, expr.id) {
return; return;
@ -213,22 +213,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
} }
if let Some(map::NodeExpr(parent_expr)) = cx.tcx.hir.find(parent_id) { if let Some(map::NodeExpr(parent_expr)) = cx.tcx.hir.find(parent_id) {
match &parent_expr.node { match &parent_expr.node {
ExprAddrOf(..) => { ExprKind::AddrOf(..) => {
// `&e` => `e` must be referenced // `&e` => `e` must be referenced
needs_check_adjustment = false; needs_check_adjustment = false;
} }
ExprField(..) => { ExprKind::Field(..) => {
dereferenced_expr = parent_expr; dereferenced_expr = parent_expr;
needs_check_adjustment = true; needs_check_adjustment = true;
} }
ExprIndex(e, _) if ptr::eq(&**e, cur_expr) => { ExprKind::Index(e, _) if ptr::eq(&**e, cur_expr) => {
// `e[i]` => desugared to `*Index::index(&e, i)`, // `e[i]` => desugared to `*Index::index(&e, i)`,
// meaning `e` must be referenced. // meaning `e` must be referenced.
// no need to go further up since a method call is involved now. // no need to go further up since a method call is involved now.
needs_check_adjustment = false; needs_check_adjustment = false;
break; break;
} }
ExprUnary(UnDeref, _) => { ExprKind::Unary(UnDeref, _) => {
// `*e` => desugared to `*Deref::deref(&e)`, // `*e` => desugared to `*Deref::deref(&e)`,
// meaning `e` must be referenced. // meaning `e` must be referenced.
// no need to go further up since a method call is involved now. // no need to go further up since a method call is involved now.

View File

@ -44,9 +44,9 @@ 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_chain! { //begin checking variables if_chain! { //begin checking variables
if let ExprMatch(ref op, ref body, ref source) = expr.node; //test if expr is a match if let ExprKind::Match(ref op, ref body, ref source) = expr.node; //test if expr is a match
if let MatchSource::IfLetDesugar { .. } = *source; //test if it is an If Let if let MatchSource::IfLetDesugar { .. } = *source; //test if it is an If Let
if let ExprMethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result<T,E>.ok() if let ExprKind::MethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result<T,E>.ok()
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation
if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized; if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;

View File

@ -1,4 +1,4 @@
use rustc::hir::{Expr, ExprLit, ExprMethodCall}; use rustc::hir::{Expr, ExprKind};
use rustc::lint::*; use rustc::lint::*;
use syntax::ast::LitKind; use syntax::ast::LitKind;
use syntax::codemap::{Span, Spanned}; use syntax::codemap::{Span, Spanned};
@ -33,7 +33,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 path, _, ref arguments) = e.node { if let ExprKind::MethodCall(ref path, _, ref arguments) = e.node {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0]));
if path.ident.name == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { if path.ident.name == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
let mut options = Vec::new(); let mut options = Vec::new();
@ -61,13 +61,13 @@ 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 path, _, ref arguments) = argument.node { if let ExprKind::MethodCall(ref path, _, ref arguments) = argument.node {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); let obj_ty = walk_ptrs_ty(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 {
let argument_option = match arguments[1].node { let argument_option = match arguments[1].node {
ExprLit(ref span) => { ExprKind::Lit(ref span) => {
if let Spanned { if let Spanned {
node: LitKind::Bool(lit), node: LitKind::Bool(lit),
.. ..

View File

@ -33,23 +33,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
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 eq = |l, r| SpanlessEq::new(cx).eq_path_segment(l, r); let eq = |l, r| SpanlessEq::new(cx).eq_path_segment(l, r);
if_chain! { if_chain! {
if let Expr_::ExprBinary(ref op, ref first, ref second) = expr.node; if let ExprKind::Binary(ref op, ref first, ref second) = expr.node;
if let Expr_::ExprBinary(ref op2, ref ident1, ref ident2) = first.node; if let ExprKind::Binary(ref op2, ref ident1, ref ident2) = first.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node; if let ExprKind::Path(QPath::Resolved(_, ref path1)) = ident1.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node; if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = second.node;
if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]);
if cx.tables.expr_ty(ident1).is_integral(); if cx.tables.expr_ty(ident1).is_integral();
if cx.tables.expr_ty(ident2).is_integral(); if cx.tables.expr_ty(ident2).is_integral();
then { then {
if let BinOp_::BiLt = op.node { if let BinOpKind::Lt = op.node {
if let BinOp_::BiAdd = op2.node { if let BinOpKind::Add = op2.node {
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
"You are trying to use classic C overflow conditions that will fail in Rust."); "You are trying to use classic C overflow conditions that will fail in Rust.");
} }
} }
if let BinOp_::BiGt = op.node { if let BinOpKind::Gt = op.node {
if let BinOp_::BiSub = op2.node { if let BinOpKind::Sub = op2.node {
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
"You are trying to use classic C underflow conditions that will fail in Rust."); "You are trying to use classic C underflow conditions that will fail in Rust.");
} }
@ -58,23 +58,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
} }
if_chain! { if_chain! {
if let Expr_::ExprBinary(ref op, ref first, ref second) = expr.node; if let ExprKind::Binary(ref op, ref first, ref second) = expr.node;
if let Expr_::ExprBinary(ref op2, ref ident1, ref ident2) = second.node; if let ExprKind::Binary(ref op2, ref ident1, ref ident2) = second.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node; if let ExprKind::Path(QPath::Resolved(_, ref path1)) = ident1.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node; if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.node;
if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = first.node;
if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]);
if cx.tables.expr_ty(ident1).is_integral(); if cx.tables.expr_ty(ident1).is_integral();
if cx.tables.expr_ty(ident2).is_integral(); if cx.tables.expr_ty(ident2).is_integral();
then { then {
if let BinOp_::BiGt = op.node { if let BinOpKind::Gt = op.node {
if let BinOp_::BiAdd = op2.node { if let BinOpKind::Add = op2.node {
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
"You are trying to use classic C overflow conditions that will fail in Rust."); "You are trying to use classic C overflow conditions that will fail in Rust.");
} }
} }
if let BinOp_::BiLt = op.node { if let BinOpKind::Lt = op.node {
if let BinOp_::BiSub = op2.node { if let BinOpKind::Sub = op2.node {
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
"You are trying to use classic C underflow conditions that will fail in Rust."); "You are trying to use classic C underflow conditions that will fail in Rust.");
} }

View File

@ -52,10 +52,10 @@ 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_chain! { if_chain! {
if let ExprBlock(ref block, _) = expr.node; if let ExprKind::Block(ref block, _) = expr.node;
if let Some(ref ex) = block.expr; if let Some(ref ex) = block.expr;
if let ExprCall(ref fun, ref params) = ex.node; if let ExprKind::Call(ref fun, ref params) = ex.node;
if let ExprPath(ref qpath) = fun.node; if let ExprKind::Path(ref qpath) = fun.node;
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)); if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
if match_def_path(cx.tcx, fun_def_id, &paths::BEGIN_PANIC); if match_def_path(cx.tcx, fun_def_id, &paths::BEGIN_PANIC);
if params.len() == 2; if params.len() == 2;
@ -86,7 +86,7 @@ fn get_outer_span(expr: &Expr) -> Span {
fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext) { fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext) {
if_chain! { if_chain! {
if let ExprLit(ref lit) = params[0].node; if let ExprKind::Lit(ref lit) = params[0].node;
if is_direct_expn_of(expr.span, "panic").is_some(); if is_direct_expn_of(expr.span, "panic").is_some();
if let LitKind::Str(ref string, _) = lit.node; if let LitKind::Str(ref string, _) = lit.node;
let string = string.as_str().replace("{{", "").replace("}}", ""); let string = string.as_str().replace("{{", "").replace("}}", "");

View File

@ -38,7 +38,7 @@ impl LintPass for Pass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
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_chain! { if_chain! {
if let ItemImpl(_, _, _, _, Some(ref trait_ref), _, ref impl_items) = item.node; if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, ref impl_items) = item.node;
if !is_automatically_derived(&*item.attrs); if !is_automatically_derived(&*item.attrs);
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait(); if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
if trait_ref.path.def.def_id() == eq_trait; if trait_ref.path.def.def_id() == eq_trait;

View File

@ -103,7 +103,7 @@ impl LintPass for PointerPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
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 let ItemFn(ref decl, _, _, body_id) = item.node { if let ItemKind::Fn(ref decl, _, _, body_id) = item.node {
check_fn(cx, decl, item.id, Some(body_id)); check_fn(cx, decl, item.id, Some(body_id));
} }
} }
@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
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 let ImplItemKind::Method(ref sig, body_id) = item.node { if let ImplItemKind::Method(ref sig, body_id) = item.node {
if let Some(NodeItem(it)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(item.id)) { if let Some(NodeItem(it)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(item.id)) {
if let ItemImpl(_, _, _, _, Some(_), _, _) = it.node { if let ItemKind::Impl(_, _, _, _, Some(_), _, _) = it.node {
return; // ignore trait impls return; // ignore trait impls
} }
} }
@ -131,8 +131,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
} }
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 ExprBinary(ref op, ref l, ref r) = expr.node { if let ExprKind::Binary(ref op, ref l, ref r) = expr.node {
if (op.node == BiEq || op.node == BiNe) && (is_null_path(l) || is_null_path(r)) { if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(l) || is_null_path(r)) {
span_lint( span_lint(
cx, cx,
CMP_NULL, CMP_NULL,
@ -159,7 +159,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
if match_type(cx, ty, &paths::VEC) { if match_type(cx, ty, &paths::VEC) {
let mut ty_snippet = None; let mut ty_snippet = None;
if_chain! { if_chain! {
if let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node; if let TyKind::Path(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node;
if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last(); if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last();
then { then {
let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg { let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg {
@ -219,8 +219,8 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
} }
} else if match_type(cx, ty, &paths::COW) { } else if match_type(cx, ty, &paths::COW) {
if_chain! { if_chain! {
if let TyRptr(_, MutTy { ref ty, ..} ) = arg.node; if let TyKind::Rptr(_, MutTy { ref ty, ..} ) = arg.node;
if let TyPath(ref path) = ty.node; if let TyKind::Path(ref path) = ty.node;
if let QPath::Resolved(None, ref pp) = *path; if let QPath::Resolved(None, ref pp) = *path;
if let [ref bx] = *pp.segments; if let [ref bx] = *pp.segments;
if let Some(ref params) = bx.args; if let Some(ref params) = bx.args;
@ -273,7 +273,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
} }
fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability, Span)> { fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability, Span)> {
if let Ty_::TyRptr(ref lt, ref m) = ty.node { if let TyKind::Rptr(ref lt, ref m) = ty.node {
Some((lt, m.mutbl, ty.span)) Some((lt, m.mutbl, ty.span))
} else { } else {
None None
@ -281,9 +281,9 @@ fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability, Span)> {
} }
fn is_null_path(expr: &Expr) -> bool { fn is_null_path(expr: &Expr) -> bool {
if let ExprCall(ref pathexp, ref args) = expr.node { if let ExprKind::Call(ref pathexp, ref args) = expr.node {
if args.is_empty() { if args.is_empty() {
if let ExprPath(ref path) = pathexp.node { if let ExprKind::Path(ref path) = pathexp.node {
return match_qpath(path, &paths::PTR_NULL) || match_qpath(path, &paths::PTR_NULL_MUT); return match_qpath(path, &paths::PTR_NULL) || match_qpath(path, &paths::PTR_NULL_MUT);
} }
} }

View File

@ -52,8 +52,8 @@ impl QuestionMarkPass {
/// If it matches, it will suggest to use the question mark operator instead /// If it matches, it will suggest to use the question mark operator instead
fn check_is_none_and_early_return_none(cx: &LateContext, expr: &Expr) { fn check_is_none_and_early_return_none(cx: &LateContext, expr: &Expr) {
if_chain! { if_chain! {
if let ExprIf(ref if_expr, ref body, _) = expr.node; if let ExprKind::If(ref if_expr, ref body, _) = expr.node;
if let ExprMethodCall(ref segment, _, ref args) = if_expr.node; if let ExprKind::MethodCall(ref segment, _, ref args) = if_expr.node;
if segment.ident.name == "is_none"; if segment.ident.name == "is_none";
if Self::expression_returns_none(cx, body); if Self::expression_returns_none(cx, body);
if let Some(subject) = args.get(0); if let Some(subject) = args.get(0);
@ -87,17 +87,17 @@ impl QuestionMarkPass {
fn expression_returns_none(cx: &LateContext, expression: &Expr) -> bool { fn expression_returns_none(cx: &LateContext, expression: &Expr) -> bool {
match expression.node { match expression.node {
ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
if let Some(return_expression) = Self::return_expression(block) { if let Some(return_expression) = Self::return_expression(block) {
return Self::expression_returns_none(cx, &return_expression); return Self::expression_returns_none(cx, &return_expression);
} }
false false
}, },
ExprRet(Some(ref expr)) => { ExprKind::Ret(Some(ref expr)) => {
Self::expression_returns_none(cx, expr) Self::expression_returns_none(cx, expr)
}, },
ExprPath(ref qp) => { ExprKind::Path(ref qp) => {
if let Def::VariantCtor(def_id, _) = cx.tables.qpath_def(qp, expression.hir_id) { if let Def::VariantCtor(def_id, _) = cx.tables.qpath_def(qp, expression.hir_id) {
return match_def_path(cx.tcx, def_id, &OPTION_NONE); return match_def_path(cx.tcx, def_id, &OPTION_NONE);
} }
@ -113,8 +113,8 @@ impl QuestionMarkPass {
if_chain! { if_chain! {
if block.stmts.len() == 1; if block.stmts.len() == 1;
if let Some(expr) = block.stmts.iter().last(); if let Some(expr) = block.stmts.iter().last();
if let StmtSemi(ref expr, _) = expr.node; if let StmtKind::Semi(ref expr, _) = expr.node;
if let ExprRet(ref ret_expr) = expr.node; if let ExprKind::Ret(ref ret_expr) = expr.node;
if let &Some(ref ret_expr) = ret_expr; if let &Some(ref ret_expr) = ret_expr;
then { then {

View File

@ -88,7 +88,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 ExprMethodCall(ref path, _, ref args) = expr.node { if let ExprKind::MethodCall(ref path, _, ref args) = expr.node {
let name = path.ident.as_str(); let name = path.ident.as_str();
// Range with step_by(0). // Range with step_by(0).
@ -107,17 +107,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let zip_arg = &args[1]; let zip_arg = &args[1];
if_chain! { if_chain! {
// .iter() call // .iter() call
if let ExprMethodCall(ref iter_path, _, ref iter_args ) = *iter; if let ExprKind::MethodCall(ref iter_path, _, ref iter_args ) = *iter;
if iter_path.ident.name == "iter"; if iter_path.ident.name == "iter";
// range expression in .zip() call: 0..x.len() // range expression in .zip() call: 0..x.len()
if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg); if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg);
if is_integer_literal(start, 0); if is_integer_literal(start, 0);
// .len() call // .len() call
if let ExprMethodCall(ref len_path, _, ref len_args) = end.node; if let ExprKind::MethodCall(ref len_path, _, ref len_args) = end.node;
if len_path.ident.name == "len" && len_args.len() == 1; if len_path.ident.name == "len" && len_args.len() == 1;
// .iter() and .len() called on same Path // .iter() and .len() called on same Path
if let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node; if let ExprKind::Path(QPath::Resolved(_, ref iter_path)) = iter_args[0].node;
if let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node; if let ExprKind::Path(QPath::Resolved(_, ref len_path)) = len_args[0].node;
if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments); if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments);
then { then {
span_lint(cx, span_lint(cx,
@ -184,7 +184,7 @@ fn has_step_by(cx: &LateContext, expr: &Expr) -> bool {
fn y_plus_one(expr: &Expr) -> Option<&Expr> { fn y_plus_one(expr: &Expr) -> Option<&Expr> {
match expr.node { match expr.node {
ExprBinary(Spanned { node: BiAdd, .. }, ref lhs, ref rhs) => if is_integer_literal(lhs, 1) { ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref lhs, ref rhs) => if is_integer_literal(lhs, 1) {
Some(rhs) Some(rhs)
} else if is_integer_literal(rhs, 1) { } else if is_integer_literal(rhs, 1) {
Some(lhs) Some(lhs)
@ -197,7 +197,7 @@ fn y_plus_one(expr: &Expr) -> Option<&Expr> {
fn y_minus_one(expr: &Expr) -> Option<&Expr> { fn y_minus_one(expr: &Expr) -> Option<&Expr> {
match expr.node { match expr.node {
ExprBinary(Spanned { node: BiSub, .. }, ref lhs, ref rhs) if is_integer_literal(rhs, 1) => Some(lhs), ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) if is_integer_literal(rhs, 1) => Some(lhs),
_ => None, _ => None,
} }
} }

View File

@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
return; return;
} }
if let ExprStruct(_, ref fields, _) = expr.node { if let ExprKind::Struct(_, ref fields, _) = expr.node {
for field in fields { for field in fields {
let name = field.ident.name; let name = field.ident.name;

View File

@ -108,8 +108,8 @@ 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_chain! { if_chain! {
if let ExprCall(ref fun, ref args) = expr.node; if let ExprKind::Call(ref fun, ref args) = expr.node;
if let ExprPath(ref qpath) = fun.node; if let ExprKind::Path(ref qpath) = fun.node;
if args.len() == 1; if args.len() == 1;
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, fun.hir_id)); if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, fun.hir_id));
then { then {
@ -176,8 +176,8 @@ fn is_trivial_regex(s: &regex_syntax::hir::Hir) -> Option<&'static str> {
fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: bool) { fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: bool) {
if_chain! { if_chain! {
if let ExprAddrOf(_, ref expr) = expr.node; if let ExprKind::AddrOf(_, ref expr) = expr.node;
if let ExprArray(ref exprs) = expr.node; if let ExprKind::Array(ref exprs) = expr.node;
then { then {
for expr in exprs { for expr in exprs {
check_regex(cx, expr, utf8); check_regex(cx, expr, utf8);
@ -192,7 +192,7 @@ fn check_regex<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: boo
.allow_invalid_utf8(!utf8) .allow_invalid_utf8(!utf8)
.build(); .build();
if let ExprLit(ref lit) = expr.node { if let ExprKind::Lit(ref lit) = expr.node {
if let LitKind::Str(ref r, style) = lit.node { if let LitKind::Str(ref r, style) = lit.node {
let r = &r.as_str(); let r = &r.as_str();
let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 }; let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 };

View File

@ -37,7 +37,7 @@ impl LintPass for ReplaceConsts {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
if_chain! { if_chain! {
if let hir::ExprPath(ref qp) = expr.node; if let hir::ExprKind::Path(ref qp) = expr.node;
if let Def::Const(def_id) = cx.tables.qpath_def(qp, expr.hir_id); if let Def::Const(def_id) = cx.tables.qpath_def(qp, expr.hir_id);
then { then {
for &(const_path, repl_snip) in REPLACEMENTS { for &(const_path, repl_snip) in REPLACEMENTS {

View File

@ -29,7 +29,7 @@ impl LintPass for Serde {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Serde { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Serde {
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 let ItemImpl(_, _, _, _, Some(ref trait_ref), _, ref items) = item.node { if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, ref items) = item.node {
let did = trait_ref.path.def.def_id(); let did = trait_ref.path.def.def_id();
if let Some(visit_did) = get_trait_def_id(cx, &paths::SERDE_DE_VISITOR) { if let Some(visit_did) = get_trait_def_id(cx, &paths::SERDE_DE_VISITOR) {
if did == visit_did { if did == visit_did {

View File

@ -110,8 +110,8 @@ fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block, binding
let len = bindings.len(); let len = bindings.len();
for stmt in &block.stmts { for stmt in &block.stmts {
match stmt.node { match stmt.node {
StmtDecl(ref decl, _) => check_decl(cx, decl, bindings), StmtKind::Decl(ref decl, _) => check_decl(cx, decl, bindings),
StmtExpr(ref e, _) | StmtSemi(ref e, _) => check_expr(cx, e, bindings), StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => check_expr(cx, e, bindings),
} }
} }
if let Some(ref o) = block.expr { if let Some(ref o) = block.expr {
@ -127,7 +127,7 @@ fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings:
if higher::is_from_for_desugar(decl) { if higher::is_from_for_desugar(decl) {
return; return;
} }
if let DeclLocal(ref local) = decl.node { if let DeclKind::Local(ref local) = decl.node {
let Local { let Local {
ref pat, ref pat,
ref ty, ref ty,
@ -185,7 +185,7 @@ fn check_pat<'a, 'tcx>(
} }
}, },
PatKind::Struct(_, ref pfields, _) => if let Some(init_struct) = init { PatKind::Struct(_, ref pfields, _) => if let Some(init_struct) = init {
if let ExprStruct(_, ref efields, _) = init_struct.node { if let ExprKind::Struct(_, ref efields, _) = init_struct.node {
for field in pfields { for field in pfields {
let name = field.node.ident.name; let name = field.node.ident.name;
let efield = efields let efield = efields
@ -205,7 +205,7 @@ fn check_pat<'a, 'tcx>(
} }
}, },
PatKind::Tuple(ref inner, _) => if let Some(init_tup) = init { PatKind::Tuple(ref inner, _) => if let Some(init_tup) = init {
if let ExprTup(ref tup) = init_tup.node { if let ExprKind::Tup(ref tup) = init_tup.node {
for (i, p) in inner.iter().enumerate() { for (i, p) in inner.iter().enumerate() {
check_pat(cx, p, Some(&tup[i]), p.span, bindings); check_pat(cx, p, Some(&tup[i]), p.span, bindings);
} }
@ -220,7 +220,7 @@ fn check_pat<'a, 'tcx>(
} }
}, },
PatKind::Box(ref inner) => if let Some(initp) = init { PatKind::Box(ref inner) => if let Some(initp) = init {
if let ExprBox(ref inner_init) = initp.node { if let ExprKind::Box(ref inner_init) = initp.node {
check_pat(cx, inner, Some(&**inner_init), span, bindings); check_pat(cx, inner, Some(&**inner_init), span, bindings);
} else { } else {
check_pat(cx, inner, init, span, bindings); check_pat(cx, inner, init, span, bindings);
@ -306,27 +306,27 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings:
return; return;
} }
match expr.node { match expr.node {
ExprUnary(_, ref e) | ExprField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(ref e) => { ExprKind::Unary(_, ref e) | ExprKind::Field(ref e, _) | ExprKind::AddrOf(_, ref e) | ExprKind::Box(ref e) => {
check_expr(cx, e, bindings) check_expr(cx, e, bindings)
}, },
ExprBlock(ref block, _) | ExprLoop(ref block, _, _) => check_block(cx, block, bindings), ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, _, _) => check_block(cx, block, bindings),
// ExprCall // ExprKind::Call
// ExprMethodCall // ExprKind::MethodCall
ExprArray(ref v) | ExprTup(ref v) => for e in v { ExprKind::Array(ref v) | ExprKind::Tup(ref v) => for e in v {
check_expr(cx, e, bindings) check_expr(cx, e, bindings)
}, },
ExprIf(ref cond, ref then, ref otherwise) => { ExprKind::If(ref cond, ref then, ref otherwise) => {
check_expr(cx, cond, bindings); check_expr(cx, cond, bindings);
check_expr(cx, &**then, bindings); check_expr(cx, &**then, bindings);
if let Some(ref o) = *otherwise { if let Some(ref o) = *otherwise {
check_expr(cx, o, bindings); check_expr(cx, o, bindings);
} }
}, },
ExprWhile(ref cond, ref block, _) => { ExprKind::While(ref cond, ref block, _) => {
check_expr(cx, cond, bindings); check_expr(cx, cond, bindings);
check_block(cx, block, bindings); check_block(cx, block, bindings);
}, },
ExprMatch(ref init, ref arms, _) => { ExprKind::Match(ref init, ref arms, _) => {
check_expr(cx, init, bindings); check_expr(cx, init, bindings);
let len = bindings.len(); let len = bindings.len();
for arm in arms { for arm in arms {
@ -347,32 +347,32 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings:
fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty, bindings: &mut Vec<(Name, Span)>) { fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty, bindings: &mut Vec<(Name, Span)>) {
match ty.node { match ty.node {
TySlice(ref sty) => check_ty(cx, sty, bindings), TyKind::Slice(ref sty) => check_ty(cx, sty, bindings),
TyArray(ref fty, ref anon_const) => { TyKind::Array(ref fty, ref anon_const) => {
check_ty(cx, fty, bindings); check_ty(cx, fty, bindings);
check_expr(cx, &cx.tcx.hir.body(anon_const.body).value, bindings); check_expr(cx, &cx.tcx.hir.body(anon_const.body).value, bindings);
}, },
TyPtr(MutTy { ty: ref mty, .. }) | TyRptr(_, MutTy { ty: ref mty, .. }) => check_ty(cx, mty, bindings), TyKind::Ptr(MutTy { ty: ref mty, .. }) | TyKind::Rptr(_, MutTy { ty: ref mty, .. }) => check_ty(cx, mty, bindings),
TyTup(ref tup) => for t in tup { TyKind::Tup(ref tup) => for t in tup {
check_ty(cx, t, bindings) check_ty(cx, t, bindings)
}, },
TyTypeof(ref anon_const) => check_expr(cx, &cx.tcx.hir.body(anon_const.body).value, bindings), TyKind::Typeof(ref anon_const) => check_expr(cx, &cx.tcx.hir.body(anon_const.body).value, bindings),
_ => (), _ => (),
} }
} }
fn is_self_shadow(name: Name, expr: &Expr) -> bool { fn is_self_shadow(name: Name, expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprBox(ref inner) | ExprAddrOf(_, ref inner) => is_self_shadow(name, inner), ExprKind::Box(ref inner) | ExprKind::AddrOf(_, ref inner) => is_self_shadow(name, inner),
ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
block.stmts.is_empty() block.stmts.is_empty()
&& block && block
.expr .expr
.as_ref() .as_ref()
.map_or(false, |e| is_self_shadow(name, e)) .map_or(false, |e| is_self_shadow(name, e))
}, },
ExprUnary(op, ref inner) => (UnDeref == op) && is_self_shadow(name, inner), ExprKind::Unary(op, ref inner) => (UnDeref == op) && is_self_shadow(name, inner),
ExprPath(QPath::Resolved(_, ref path)) => path_eq_name(name, path), ExprKind::Path(QPath::Resolved(_, ref path)) => path_eq_name(name, path),
_ => false, _ => false,
} }
} }

View File

@ -82,12 +82,12 @@ impl LintPass for StringAdd {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
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 ExprBinary(Spanned { node: BiAdd, .. }, ref left, _) = e.node { if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
if is_string(cx, left) { if is_string(cx, left) {
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) { if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
let parent = get_parent_expr(cx, e); let parent = get_parent_expr(cx, e);
if let Some(p) = parent { if let Some(p) = parent {
if let ExprAssign(ref target, _) = p.node { if let ExprKind::Assign(ref target, _) = p.node {
// avoid duplicate matches // avoid duplicate matches
if SpanlessEq::new(cx).eq_expr(target, left) { if SpanlessEq::new(cx).eq_expr(target, left) {
return; return;
@ -102,7 +102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
"you added something to a string. Consider using `String::push_str()` instead", "you added something to a string. Consider using `String::push_str()` instead",
); );
} }
} else if let ExprAssign(ref target, ref src) = e.node { } else if let ExprKind::Assign(ref target, ref src) = e.node {
if is_string(cx, target) && is_add(cx, src, target) { if is_string(cx, target) && is_add(cx, src, target) {
span_lint( span_lint(
cx, cx,
@ -122,8 +122,8 @@ fn is_string(cx: &LateContext, e: &Expr) -> bool {
fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {
match src.node { match src.node {
ExprBinary(Spanned { node: BiAdd, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left), ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
block.stmts.is_empty() block.stmts.is_empty()
&& block && block
.expr .expr
@ -148,9 +148,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
use syntax::ast::LitKind; use syntax::ast::LitKind;
use crate::utils::{in_macro, snippet}; use crate::utils::{in_macro, snippet};
if let ExprMethodCall(ref path, _, ref args) = e.node { if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
if path.ident.name == "as_bytes" { if path.ident.name == "as_bytes" {
if let ExprLit(ref lit) = args[0].node { if let ExprKind::Lit(ref lit) = args[0].node {
if let LitKind::Str(ref lit_content, _) = lit.node { if let LitKind::Str(ref lit_content, _) = lit.node {
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) { if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
span_lint_and_sugg( span_lint_and_sugg(

View File

@ -59,10 +59,15 @@ impl LintPass for SuspiciousImpl {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
use rustc::hir::BinOp_::*; if let hir::ExprKind::Binary(binop, _, _) = expr.node {
if let hir::ExprBinary(binop, _, _) = expr.node {
match binop.node { match binop.node {
BiEq | BiLt | BiLe | BiNe | BiGe | BiGt => return, | hir::BinOpKind::Eq
| hir::BinOpKind::Lt
| hir::BinOpKind::Le
| hir::BinOpKind::Ne
| hir::BinOpKind::Ge
| hir::BinOpKind::Gt
=> return,
_ => {}, _ => {},
} }
// Check if the binary expression is part of another bi/unary expression // Check if the binary expression is part of another bi/unary expression
@ -71,9 +76,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
while parent_expr != ast::CRATE_NODE_ID { while parent_expr != ast::CRATE_NODE_ID {
if let hir::map::Node::NodeExpr(e) = cx.tcx.hir.get(parent_expr) { if let hir::map::Node::NodeExpr(e) = cx.tcx.hir.get(parent_expr) {
match e.node { match e.node {
hir::ExprBinary(..) hir::ExprKind::Binary(..)
| hir::ExprUnary(hir::UnOp::UnNot, _) | hir::ExprKind::Unary(hir::UnOp::UnNot, _)
| hir::ExprUnary(hir::UnOp::UnNeg, _) => return, | hir::ExprKind::Unary(hir::UnOp::UnNeg, _) => return,
_ => {}, _ => {},
} }
} }
@ -94,7 +99,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
expr, expr,
binop.node, binop.node,
&["Add", "Sub", "Mul", "Div"], &["Add", "Sub", "Mul", "Div"],
&[BiAdd, BiSub, BiMul, BiDiv], &[
hir::BinOpKind::Add,
hir::BinOpKind::Sub,
hir::BinOpKind::Mul,
hir::BinOpKind::Div,
],
) { ) {
span_lint( span_lint(
cx, cx,
@ -124,7 +134,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
"ShrAssign", "ShrAssign",
], ],
&[ &[
BiAdd, BiSub, BiMul, BiDiv, BiBitAnd, BiBitOr, BiBitXor, BiRem, BiShl, BiShr hir::BinOpKind::Add,
hir::BinOpKind::Sub,
hir::BinOpKind::Mul,
hir::BinOpKind::Div,
hir::BinOpKind::BitAnd,
hir::BinOpKind::BitOr,
hir::BinOpKind::BitXor,
hir::BinOpKind::Rem,
hir::BinOpKind::Shl,
hir::BinOpKind::Shr,
], ],
) { ) {
span_lint( span_lint(
@ -144,9 +163,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
fn check_binop<'a>( fn check_binop<'a>(
cx: &LateContext, cx: &LateContext,
expr: &hir::Expr, expr: &hir::Expr,
binop: hir::BinOp_, binop: hir::BinOpKind,
traits: &[&'a str], traits: &[&'a str],
expected_ops: &[hir::BinOp_], expected_ops: &[hir::BinOpKind],
) -> Option<&'a str> { ) -> Option<&'a str> {
let mut trait_ids = vec![]; let mut trait_ids = vec![];
let [krate, module] = crate::utils::paths::OPS_MODULE; let [krate, module] = crate::utils::paths::OPS_MODULE;
@ -167,7 +186,7 @@ fn check_binop<'a>(
if_chain! { if_chain! {
if parent_impl != ast::CRATE_NODE_ID; if parent_impl != ast::CRATE_NODE_ID;
if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl); if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl);
if let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node; if let hir::ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node;
if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.def.def_id()); if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.def.def_id());
if binop != expected_ops[idx]; if binop != expected_ops[idx];
then{ then{
@ -185,9 +204,9 @@ struct BinaryExprVisitor {
impl<'a, 'tcx: 'a> Visitor<'tcx> for BinaryExprVisitor { impl<'a, 'tcx: 'a> Visitor<'tcx> for BinaryExprVisitor {
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::ExprBinary(..) hir::ExprKind::Binary(..)
| hir::ExprUnary(hir::UnOp::UnNot, _) | hir::ExprKind::Unary(hir::UnOp::UnNot, _)
| hir::ExprUnary(hir::UnOp::UnNeg, _) => { | hir::ExprKind::Unary(hir::UnOp::UnNeg, _) => {
self.in_binary_expr = true self.in_binary_expr = true
}, },
_ => {}, _ => {},

View File

@ -61,19 +61,19 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
for w in block.stmts.windows(3) { for w in block.stmts.windows(3) {
if_chain! { if_chain! {
// let t = foo(); // let t = foo();
if let StmtDecl(ref tmp, _) = w[0].node; if let StmtKind::Decl(ref tmp, _) = w[0].node;
if let DeclLocal(ref tmp) = tmp.node; if let DeclKind::Local(ref tmp) = tmp.node;
if let Some(ref tmp_init) = tmp.init; if let Some(ref tmp_init) = tmp.init;
if let PatKind::Binding(_, _, ident, None) = tmp.pat.node; if let PatKind::Binding(_, _, ident, None) = tmp.pat.node;
// foo() = bar(); // foo() = bar();
if let StmtSemi(ref first, _) = w[1].node; if let StmtKind::Semi(ref first, _) = w[1].node;
if let ExprAssign(ref lhs1, ref rhs1) = first.node; if let ExprKind::Assign(ref lhs1, ref rhs1) = first.node;
// bar() = t; // bar() = t;
if let StmtSemi(ref second, _) = w[2].node; if let StmtKind::Semi(ref second, _) = w[2].node;
if let ExprAssign(ref lhs2, ref rhs2) = second.node; if let ExprKind::Assign(ref lhs2, ref rhs2) = second.node;
if let ExprPath(QPath::Resolved(None, ref rhs2)) = rhs2.node; if let ExprKind::Path(QPath::Resolved(None, ref rhs2)) = rhs2.node;
if rhs2.segments.len() == 1; if rhs2.segments.len() == 1;
if ident.as_str() == rhs2.segments[0].ident.as_str(); if ident.as_str() == rhs2.segments[0].ident.as_str();
@ -85,8 +85,8 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
lhs1: &'a Expr, lhs1: &'a Expr,
lhs2: &'a Expr, lhs2: &'a Expr,
) -> Option<(&'a Expr, &'a Expr, &'a Expr)> { ) -> Option<(&'a Expr, &'a Expr, &'a Expr)> {
if let ExprIndex(ref lhs1, ref idx1) = lhs1.node { if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.node {
if let ExprIndex(ref lhs2, ref idx2) = lhs2.node { if let ExprKind::Index(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.tables.expr_ty(lhs1)); let ty = walk_ptrs_ty(cx.tables.expr_ty(lhs1));
@ -145,11 +145,11 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
fn check_suspicious_swap(cx: &LateContext, block: &Block) { fn check_suspicious_swap(cx: &LateContext, block: &Block) {
for w in block.stmts.windows(2) { for w in block.stmts.windows(2) {
if_chain! { if_chain! {
if let StmtSemi(ref first, _) = w[0].node; if let StmtKind::Semi(ref first, _) = w[0].node;
if let StmtSemi(ref second, _) = w[1].node; if let StmtKind::Semi(ref second, _) = w[1].node;
if !differing_macro_contexts(first.span, second.span); if !differing_macro_contexts(first.span, second.span);
if let ExprAssign(ref lhs0, ref rhs0) = first.node; if let ExprKind::Assign(ref lhs0, ref rhs0) = first.node;
if let ExprAssign(ref lhs1, ref rhs1) = second.node; if let ExprKind::Assign(ref lhs1, ref rhs1) = second.node;
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs0, rhs1); if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs0, rhs1);
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, rhs0); if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, rhs0);
then { then {

View File

@ -1,5 +1,5 @@
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::hir::{Expr, ExprAssign, ExprField, ExprStruct, ExprTup}; use rustc::hir::{Expr, ExprKind};
use crate::utils::is_adjusted; use crate::utils::is_adjusted;
use crate::utils::span_lint; use crate::utils::span_lint;
@ -23,7 +23,7 @@ declare_clippy_lint! {
fn is_temporary(expr: &Expr) -> bool { fn is_temporary(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprStruct(..) | ExprTup(..) => true, ExprKind::Struct(..) | ExprKind::Tup(..) => true,
_ => false, _ => false,
} }
} }
@ -39,8 +39,8 @@ 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 ExprAssign(ref target, _) = expr.node { if let ExprKind::Assign(ref target, _) = expr.node {
if let ExprField(ref base, _) = target.node { if let ExprKind::Field(ref base, _) = target.node {
if is_temporary(base) && !is_adjusted(cx, base) { if is_temporary(base) && !is_adjusted(cx, base) {
span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary"); span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary");
} }

View File

@ -215,8 +215,8 @@ impl LintPass for Transmute {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { 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 ExprKind::Call(ref path_expr, ref args) = e.node {
if let ExprPath(ref qpath) = path_expr.node { if let ExprKind::Path(ref qpath) = path_expr.node {
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) { if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) {
if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) { if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
let from_ty = cx.tables.expr_ty(&args[0]); let from_ty = cx.tables.expr_ty(&args[0]);
@ -461,7 +461,7 @@ fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String {
GenericArg::Type(ty) => Some(ty), GenericArg::Type(ty) => Some(ty),
GenericArg::Lifetime(_) => None, GenericArg::Lifetime(_) => None,
}).nth(1); }).nth(1);
if let TyRptr(_, ref to_ty) = to_ty.node; if let TyKind::Rptr(_, ref to_ty) = to_ty.node;
then { then {
return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string(); return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string();
} }

View File

@ -100,8 +100,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef {
// Exclude non-inherent impls // Exclude non-inherent impls
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) { if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) | if matches!(item.node, ItemKind::Impl(_, _, _, _, Some(_), _, _) |
ItemTrait(..)) ItemKind::Trait(..))
{ {
return; return;
} }
@ -123,7 +123,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef {
if is_copy(cx, ty); if is_copy(cx, ty);
if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes()); if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes());
if size <= self.limit; if size <= self.limit;
if let Ty_::TyRptr(_, MutTy { ty: ref decl_ty, .. }) = input.node; if let TyKind::Rptr(_, MutTy { ty: ref decl_ty, .. }) = input.node;
then { then {
let value_type = if is_self(arg) { let value_type = if is_self(arg) {
"self".into() "self".into()

View File

@ -139,7 +139,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass {
fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Body, _: Span, id: NodeId) { fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Body, _: Span, id: NodeId) {
// skip trait implementations, see #605 // skip trait implementations, see #605
if let Some(map::NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(id)) { if let Some(map::NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(id)) {
if let ItemImpl(_, _, _, _, Some(..), _, _) = item.node { if let ItemKind::Impl(_, _, _, _, Some(..), _, _) = item.node {
return; return;
} }
} }
@ -186,7 +186,7 @@ fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool
GenericArg::Type(ty) => Some(ty), GenericArg::Type(ty) => Some(ty),
GenericArg::Lifetime(_) => None, GenericArg::Lifetime(_) => None,
}); });
if let TyPath(ref qpath) = ty.node; if let TyKind::Path(ref qpath) = ty.node;
if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(ty.id))); if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(ty.id)));
if match_def_path(cx.tcx, did, path); if match_def_path(cx.tcx, did, path);
then { then {
@ -206,7 +206,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
return; return;
} }
match ast_ty.node { match ast_ty.node {
TyPath(ref qpath) if !is_local => { TyKind::Path(ref qpath) if !is_local => {
let hir_id = cx.tcx.hir.node_to_hir_id(ast_ty.id); let hir_id = cx.tcx.hir.node_to_hir_id(ast_ty.id);
let def = cx.tables.qpath_def(qpath, hir_id); let def = cx.tables.qpath_def(qpath, hir_id);
if let Some(def_id) = opt_def_id(def) { if let Some(def_id) = opt_def_id(def) {
@ -282,10 +282,10 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
}, },
} }
}, },
TyRptr(ref lt, ref mut_ty) => check_ty_rptr(cx, ast_ty, is_local, lt, mut_ty), TyKind::Rptr(ref lt, ref mut_ty) => check_ty_rptr(cx, ast_ty, is_local, lt, mut_ty),
// recurse // recurse
TySlice(ref ty) | TyArray(ref ty, _) | TyPtr(MutTy { ref ty, .. }) => check_ty(cx, ty, is_local), TyKind::Slice(ref ty) | TyKind::Array(ref ty, _) | TyKind::Ptr(MutTy { ref ty, .. }) => check_ty(cx, ty, is_local),
TyTup(ref tys) => for ty in tys { TyKind::Tup(ref tys) => for ty in tys {
check_ty(cx, ty, is_local); check_ty(cx, ty, is_local);
}, },
_ => {}, _ => {},
@ -294,7 +294,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifetime, mut_ty: &MutTy) { fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifetime, mut_ty: &MutTy) {
match mut_ty.ty.node { match mut_ty.ty.node {
TyPath(ref qpath) => { TyKind::Path(ref qpath) => {
let hir_id = cx.tcx.hir.node_to_hir_id(mut_ty.ty.id); let hir_id = cx.tcx.hir.node_to_hir_id(mut_ty.ty.id);
let def = cx.tables.qpath_def(qpath, hir_id); let def = cx.tables.qpath_def(qpath, hir_id);
if_chain! { if_chain! {
@ -343,7 +343,7 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti
// Returns true if given type is `Any` trait. // Returns true if given type is `Any` trait.
fn is_any_trait(t: &hir::Ty) -> bool { fn is_any_trait(t: &hir::Ty) -> bool {
if_chain! { if_chain! {
if let TyTraitObject(ref traits, _) = t.node; if let TyKind::TraitObject(ref traits, _) = t.node;
if traits.len() >= 1; if traits.len() >= 1;
// Only Send/Sync can be used as additional traits, so it is enough to // Only Send/Sync can be used as additional traits, so it is enough to
// check only the first trait. // check only the first trait.
@ -377,7 +377,7 @@ declare_clippy_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 DeclKind::Local(ref local) = decl.node {
if is_unit(cx.tables.pat_ty(&local.pat)) { if is_unit(cx.tables.pat_ty(&local.pat)) {
if in_external_macro(cx, decl.span) || in_macro(local.pat.span) { if in_external_macro(cx, decl.span) || in_macro(local.pat.span) {
return; return;
@ -446,11 +446,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
if in_macro(expr.span) { if in_macro(expr.span) {
return; return;
} }
if let ExprBinary(ref cmp, ref left, _) = expr.node { if let ExprKind::Binary(ref cmp, ref left, _) = expr.node {
let op = cmp.node; let op = cmp.node;
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) { if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) {
let result = match op { let result = match op {
BiEq | BiLe | BiGe => "true", BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => "true",
_ => "false", _ => "false",
}; };
span_lint( span_lint(
@ -501,7 +501,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
return; return;
} }
match expr.node { match expr.node {
ExprCall(_, ref args) | ExprMethodCall(_, _, ref args) => { ExprKind::Call(_, ref args) | ExprKind::MethodCall(_, _, ref args) => {
for arg in args { for arg in args {
if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) { if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) {
let map = &cx.tcx.hir; let map = &cx.tcx.hir;
@ -539,7 +539,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
fn is_questionmark_desugar_marked_call(expr: &Expr) -> bool { fn is_questionmark_desugar_marked_call(expr: &Expr) -> bool {
use syntax_pos::hygiene::CompilerDesugaringKind; use syntax_pos::hygiene::CompilerDesugaringKind;
if let ExprCall(ref callee, _) = expr.node { if let ExprKind::Call(ref callee, _) = expr.node {
callee.span.is_compiler_desugaring(CompilerDesugaringKind::QuestionMark) callee.span.is_compiler_desugaring(CompilerDesugaringKind::QuestionMark)
} else { } else {
false false
@ -555,7 +555,7 @@ fn is_unit(ty: Ty) -> bool {
fn is_unit_literal(expr: &Expr) -> bool { fn is_unit_literal(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprTup(ref slice) if slice.is_empty() => true, ExprKind::Tup(ref slice) if slice.is_empty() => true,
_ => false, _ => false,
} }
} }
@ -812,7 +812,7 @@ fn span_precision_loss_lint(cx: &LateContext, expr: &Expr, cast_from: Ty, cast_t
} }
fn should_strip_parens(op: &Expr, snip: &str) -> bool { fn should_strip_parens(op: &Expr, snip: &str) -> bool {
if let ExprBinary(_, _, _) = op.node { if let ExprKind::Binary(_, _, _) = op.node {
if snip.starts_with('(') && snip.ends_with(')') { if snip.starts_with('(') && snip.ends_with(')') {
return true; return true;
} }
@ -951,9 +951,9 @@ 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 ExprKind::Cast(ref ex, _) = expr.node {
let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr)); let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr));
if let ExprLit(ref lit) = ex.node { if let ExprKind::Lit(ref lit) = ex.node {
use syntax::ast::{LitIntType, LitKind}; use syntax::ast::{LitIntType, LitKind};
match lit.node { match lit.node {
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::FloatUnsuffixed(_) => {}, LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::FloatUnsuffixed(_) => {},
@ -1141,7 +1141,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexityPass {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
match item.node { match item.node {
ItemStatic(ref ty, _, _) | ItemConst(ref ty, _) => self.check_type(cx, ty), ItemKind::Static(ref ty, _, _) | ItemKind::Const(ref ty, _) => self.check_type(cx, ty),
// functions, enums, structs, impls and traits are covered // functions, enums, structs, impls and traits are covered
_ => (), _ => (),
} }
@ -1214,15 +1214,15 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
fn visit_ty(&mut self, ty: &'tcx hir::Ty) { fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
let (add_score, sub_nest) = match ty.node { let (add_score, sub_nest) = match ty.node {
// _, &x and *x have only small overhead; don't mess with nesting level // _, &x and *x have only small overhead; don't mess with nesting level
TyInfer | TyPtr(..) | TyRptr(..) => (1, 0), TyKind::Infer | TyKind::Ptr(..) | TyKind::Rptr(..) => (1, 0),
// the "normal" components of a type: named types, arrays/tuples // the "normal" components of a type: named types, arrays/tuples
TyPath(..) | TySlice(..) | TyTup(..) | TyArray(..) => (10 * self.nest, 1), TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1),
// function types bring a lot of overhead // function types bring a lot of overhead
TyBareFn(..) => (50 * self.nest, 1), TyKind::BareFn(..) => (50 * self.nest, 1),
TyTraitObject(ref param_bounds, _) => { TyKind::TraitObject(ref param_bounds, _) => {
let has_lifetime_parameters = param_bounds let has_lifetime_parameters = param_bounds
.iter() .iter()
.any(|bound| bound.bound_generic_params.iter().any(|gen| match gen.kind { .any(|bound| bound.bound_generic_params.iter().any(|gen| match gen.kind {
@ -1289,8 +1289,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
use syntax::ast::{LitKind, UintTy}; use syntax::ast::{LitKind, UintTy};
if let ExprCast(ref e, _) = expr.node { if let ExprKind::Cast(ref e, _) = expr.node {
if let ExprLit(ref l) = e.node { if let ExprKind::Lit(ref l) = e.node {
if let LitKind::Char(_) = l.node { if let LitKind::Char(_) = l.node {
if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(expr.span) { if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(expr.span) {
let msg = "casting character literal to u8. `char`s \ let msg = "casting character literal to u8. `char`s \
@ -1362,7 +1362,7 @@ fn is_cast_between_fixed_and_target<'a, 'tcx>(
expr: &'tcx Expr expr: &'tcx Expr
) -> bool { ) -> bool {
if let ExprCast(ref cast_exp, _) = expr.node { if let ExprKind::Cast(ref cast_exp, _) = expr.node {
let precast_ty = cx.tables.expr_ty(cast_exp); let precast_ty = cx.tables.expr_ty(cast_exp);
let cast_ty = cx.tables.expr_ty(expr); let cast_ty = cx.tables.expr_ty(expr);
@ -1374,7 +1374,7 @@ fn is_cast_between_fixed_and_target<'a, 'tcx>(
fn detect_absurd_comparison<'a, 'tcx>( fn detect_absurd_comparison<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>, cx: &LateContext<'a, 'tcx>,
op: BinOp_, op: BinOpKind,
lhs: &'tcx Expr, lhs: &'tcx Expr,
rhs: &'tcx Expr, rhs: &'tcx Expr,
) -> Option<(ExtremeExpr<'tcx>, AbsurdComparisonResult)> { ) -> Option<(ExtremeExpr<'tcx>, AbsurdComparisonResult)> {
@ -1453,7 +1453,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons {
use crate::types::ExtremeType::*; use crate::types::ExtremeType::*;
use crate::types::AbsurdComparisonResult::*; use crate::types::AbsurdComparisonResult::*;
if let ExprBinary(ref cmp, ref lhs, ref rhs) = expr.node { if let ExprKind::Binary(ref cmp, ref lhs, ref rhs) = expr.node {
if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) { if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) {
if !in_macro(expr.span) { if !in_macro(expr.span) {
let msg = "this comparison involving the minimum or maximum element for this \ let msg = "this comparison involving the minimum or maximum element for this \
@ -1564,7 +1564,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
use syntax::ast::{IntTy, UintTy}; use syntax::ast::{IntTy, UintTy};
use std::*; use std::*;
if let ExprCast(ref cast_exp, _) = expr.node { if let ExprKind::Cast(ref cast_exp, _) = expr.node {
let pre_cast_ty = cx.tables.expr_ty(cast_exp); let pre_cast_ty = cx.tables.expr_ty(cast_exp);
let cast_ty = cx.tables.expr_ty(expr); let cast_ty = cx.tables.expr_ty(expr);
// if it's a cast from i32 to u32 wrapping will invalidate all these checks // if it's a cast from i32 to u32 wrapping will invalidate all these checks
@ -1627,7 +1627,7 @@ fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr)
} }
fn err_upcast_comparison(cx: &LateContext, span: Span, expr: &Expr, always: bool) { fn err_upcast_comparison(cx: &LateContext, span: Span, expr: &Expr, always: bool) {
if let ExprCast(ref cast_val, _) = expr.node { if let ExprKind::Cast(ref cast_val, _) = expr.node {
span_lint( span_lint(
cx, cx,
INVALID_UPCAST_COMPARISONS, INVALID_UPCAST_COMPARISONS,
@ -1693,7 +1693,7 @@ fn upcast_comparison_bounds_err<'a, 'tcx>(
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidUpcastComparisons { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidUpcastComparisons {
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 ExprBinary(ref cmp, ref lhs, ref rhs) = expr.node { if let ExprKind::Binary(ref cmp, ref lhs, ref rhs) = expr.node {
let normalized = comparisons::normalize_comparison(cmp.node, lhs, rhs); let normalized = comparisons::normalize_comparison(cmp.node, lhs, rhs);
let (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized { let (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized {
val val
@ -1797,7 +1797,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher {
} }
match item.node { match item.node {
ItemImpl(_, _, _, ref generics, _, ref ty, ref items) => { ItemKind::Impl(_, _, _, ref generics, _, ref ty, ref items) => {
let mut vis = ImplicitHasherTypeVisitor::new(cx); let mut vis = ImplicitHasherTypeVisitor::new(cx);
vis.visit_ty(ty); vis.visit_ty(ty);
@ -1829,7 +1829,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher {
); );
} }
}, },
ItemFn(ref decl, .., ref generics, body_id) => { ItemKind::Fn(ref decl, .., ref generics, body_id) => {
let body = cx.tcx.hir.body(body_id); let body = cx.tcx.hir.body(body_id);
for ty in &decl.inputs { for ty in &decl.inputs {
@ -1878,7 +1878,7 @@ enum ImplicitHasherType<'tcx> {
impl<'tcx> ImplicitHasherType<'tcx> { impl<'tcx> ImplicitHasherType<'tcx> {
/// Checks that `ty` is a target type without a BuildHasher. /// Checks that `ty` is a target type without a BuildHasher.
fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option<Self> { fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option<Self> {
if let TyPath(QPath::Resolved(None, ref path)) = hir_ty.node { if let TyKind::Path(QPath::Resolved(None, ref path)) = hir_ty.node {
let params: Vec<_> = path.segments.last().as_ref()?.args.as_ref()? let params: Vec<_> = path.segments.last().as_ref()?.args.as_ref()?
.args.iter().filter_map(|arg| match arg { .args.iter().filter_map(|arg| match arg {
GenericArg::Type(ty) => Some(ty), GenericArg::Type(ty) => Some(ty),
@ -1984,9 +1984,9 @@ impl<'a, 'b, 'tcx: 'a + 'b> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'
fn visit_expr(&mut self, e: &'tcx Expr) { fn visit_expr(&mut self, e: &'tcx Expr) {
if_chain! { if_chain! {
if let ExprCall(ref fun, ref args) = e.node; if let ExprKind::Call(ref fun, ref args) = e.node;
if let ExprPath(QPath::TypeRelative(ref ty, ref method)) = fun.node; if let ExprKind::Path(QPath::TypeRelative(ref ty, ref method)) = fun.node;
if let TyPath(QPath::Resolved(None, ref ty_path)) = ty.node; if let TyKind::Path(QPath::Resolved(None, ref ty_path)) = ty.node;
then { then {
if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) { if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) {
return; return;

View File

@ -71,7 +71,7 @@ impl LintPass for Unicode {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unicode { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unicode {
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 ExprLit(ref lit) = expr.node { if let ExprKind::Lit(ref lit) = expr.node {
if let LitKind::Str(_, _) = lit.node { if let LitKind::Str(_, _) = lit.node {
check_str(cx, lit.span, expr.id) check_str(cx, lit.span, expr.id)
} }

View File

@ -40,14 +40,14 @@ impl LintPass for UnusedIoAmount {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
let expr = match s.node { let expr = match s.node {
hir::StmtSemi(ref expr, _) | hir::StmtExpr(ref expr, _) => &**expr, hir::StmtKind::Semi(ref expr, _) | hir::StmtKind::Expr(ref expr, _) => &**expr,
_ => return, _ => return,
}; };
match expr.node { match expr.node {
hir::ExprMatch(ref res, _, _) if is_try(expr).is_some() => { hir::ExprKind::Match(ref res, _, _) if is_try(expr).is_some() => {
if let hir::ExprCall(ref func, ref args) = res.node { if let hir::ExprKind::Call(ref func, ref args) = res.node {
if let hir::ExprPath(ref path) = func.node { if let hir::ExprKind::Path(ref path) = func.node {
if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 { if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 {
check_method_call(cx, &args[0], expr); check_method_call(cx, &args[0], expr);
} }
@ -57,7 +57,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
} }
}, },
hir::ExprMethodCall(ref path, _, ref args) => match &*path.ident.as_str() { hir::ExprKind::MethodCall(ref path, _, ref args) => match &*path.ident.as_str() {
"expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => { "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
check_method_call(cx, &args[0], expr); check_method_call(cx, &args[0], expr);
}, },
@ -70,7 +70,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
} }
fn check_method_call(cx: &LateContext, call: &hir::Expr, expr: &hir::Expr) { fn check_method_call(cx: &LateContext, call: &hir::Expr, expr: &hir::Expr) {
if let hir::ExprMethodCall(ref path, _, _) = call.node { if let hir::ExprKind::MethodCall(ref path, _, _) = call.node {
let symbol = &*path.ident.as_str(); let symbol = &*path.ident.as_str();
if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" { if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" {
span_lint( span_lint(

View File

@ -69,10 +69,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel {
impl<'a, 'tcx: 'a> Visitor<'tcx> for UnusedLabelVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> Visitor<'tcx> for UnusedLabelVisitor<'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::ExprBreak(destination, _) | hir::ExprContinue(destination) => if let Some(label) = destination.label { hir::ExprKind::Break(destination, _) | hir::ExprKind::Continue(destination) => if let Some(label) = destination.label {
self.labels.remove(&label.ident.as_str()); self.labels.remove(&label.ident.as_str());
}, },
hir::ExprLoop(_, Some(label), _) | hir::ExprWhile(_, _, Some(label)) => { hir::ExprKind::Loop(_, Some(label), _) | hir::ExprKind::While(_, _, Some(label)) => {
self.labels.insert(label.ident.as_str(), expr.span); self.labels.insert(label.ident.as_str(), expr.span);
}, },
_ => (), _ => (),

View File

@ -78,21 +78,21 @@ fn collect_unwrap_info<'a, 'tcx: 'a>(
expr: &'tcx Expr, expr: &'tcx Expr,
invert: bool, invert: bool,
) -> Vec<UnwrapInfo<'tcx>> { ) -> Vec<UnwrapInfo<'tcx>> {
if let Expr_::ExprBinary(op, left, right) = &expr.node { if let ExprKind::Binary(op, left, right) = &expr.node {
match (invert, op.node) { match (invert, op.node) {
(false, BinOp_::BiAnd) | (false, BinOp_::BiBitAnd) | (true, BinOp_::BiOr) | (true, BinOp_::BiBitOr) => { (false, BinOpKind::And) | (false, BinOpKind::BitAnd) | (true, BinOpKind::Or) | (true, BinOpKind::BitOr) => {
let mut unwrap_info = collect_unwrap_info(cx, left, invert); let mut unwrap_info = collect_unwrap_info(cx, left, invert);
unwrap_info.append(&mut collect_unwrap_info(cx, right, invert)); unwrap_info.append(&mut collect_unwrap_info(cx, right, invert));
return unwrap_info; return unwrap_info;
}, },
_ => (), _ => (),
} }
} else if let Expr_::ExprUnary(UnNot, expr) = &expr.node { } else if let ExprKind::Unary(UnNot, expr) = &expr.node {
return collect_unwrap_info(cx, expr, !invert); return collect_unwrap_info(cx, expr, !invert);
} else { } else {
if_chain! { if_chain! {
if let Expr_::ExprMethodCall(method_name, _, args) = &expr.node; if let ExprKind::MethodCall(method_name, _, args) = &expr.node;
if let Expr_::ExprPath(QPath::Resolved(None, path)) = &args[0].node; if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].node;
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables.expr_ty(&args[0]);
if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT); if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
let name = method_name.ident.as_str(); let name = method_name.ident.as_str();
@ -131,7 +131,7 @@ impl<'a, 'tcx: 'a> UnwrappableVariablesVisitor<'a, 'tcx> {
impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr) { fn visit_expr(&mut self, expr: &'tcx Expr) {
if let Expr_::ExprIf(cond, then, els) = &expr.node { if let ExprKind::If(cond, then, els) = &expr.node {
walk_expr(self, cond); walk_expr(self, cond);
self.visit_branch(cond, then, false); self.visit_branch(cond, then, false);
if let Some(els) = els { if let Some(els) = els {
@ -140,8 +140,8 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
} else { } else {
// find `unwrap[_err]()` calls: // find `unwrap[_err]()` calls:
if_chain! { if_chain! {
if let Expr_::ExprMethodCall(ref method_name, _, ref args) = expr.node; if let ExprKind::MethodCall(ref method_name, _, ref args) = expr.node;
if let Expr_::ExprPath(QPath::Resolved(None, ref path)) = args[0].node; if let ExprKind::Path(QPath::Resolved(None, ref path)) = args[0].node;
if ["unwrap", "unwrap_err"].contains(&&*method_name.ident.as_str()); if ["unwrap", "unwrap_err"].contains(&&*method_name.ident.as_str());
let call_to_unwrap = method_name.ident.name == "unwrap"; let call_to_unwrap = method_name.ident.name == "unwrap";
if let Some(unwrappable) = self.unwrappables.iter() if let Some(unwrappable) = self.unwrappables.iter()

View File

@ -55,8 +55,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
return; return;
} }
if_chain! { if_chain! {
if let ItemImpl(.., ref item_type, ref refs) = item.node; if let ItemKind::Impl(.., ref item_type, ref refs) = item.node;
if let Ty_::TyPath(QPath::Resolved(_, ref item_path)) = item_type.node; if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.node;
then { then {
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
let should_check = if let Some(ref params) = *parameters { let should_check = if let Some(ref params) = *parameters {

View File

@ -5,7 +5,7 @@
use rustc::lint::*; use rustc::lint::*;
use rustc::hir; use rustc::hir;
use rustc::hir::{Expr, Expr_, QPath, Ty_, Pat, PatKind, BindingAnnotation, StmtSemi, StmtExpr, StmtDecl, Decl_, Stmt}; use rustc::hir::{Expr, ExprKind, QPath, TyKind, Pat, PatKind, BindingAnnotation, StmtKind, DeclKind, Stmt};
use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
use syntax::ast::{Attribute, LitKind, DUMMY_NODE_ID}; use syntax::ast::{Attribute, LitKind, DUMMY_NODE_ID};
use std::collections::HashMap; use std::collections::HashMap;
@ -32,10 +32,10 @@ use crate::utils::get_attr;
/// ```rust /// ```rust
/// // ./tests/ui/new_lint.stdout /// // ./tests/ui/new_lint.stdout
/// if_chain!{ /// if_chain!{
/// if let Expr_::ExprIf(ref cond, ref then, None) = item.node, /// if let ExprKind::If(ref cond, ref then, None) = item.node,
/// if let Expr_::ExprBinary(BinOp::Eq, ref left, ref right) = cond.node, /// if let ExprKind::Binary(BinOp::Eq, ref left, ref right) = cond.node,
/// if let Expr_::ExprPath(ref path) = left.node, /// if let ExprKind::Path(ref path) = left.node,
/// if let Expr_::ExprLit(ref lit) = right.node, /// if let ExprKind::Lit(ref lit) = right.node,
/// if let LitKind::Int(42, _) = lit.node, /// if let LitKind::Int(42, _) = lit.node,
/// then { /// then {
/// // report your lint here /// // report your lint here
@ -192,16 +192,16 @@ struct PrintVisitor {
impl<'tcx> Visitor<'tcx> for PrintVisitor { impl<'tcx> Visitor<'tcx> for PrintVisitor {
fn visit_expr(&mut self, expr: &Expr) { fn visit_expr(&mut self, expr: &Expr) {
print!(" if let Expr_::Expr"); print!(" if let ExprKind::");
let current = format!("{}.node", self.current); let current = format!("{}.node", self.current);
match expr.node { match expr.node {
Expr_::ExprBox(ref inner) => { ExprKind::Box(ref inner) => {
let inner_pat = self.next("inner"); let inner_pat = self.next("inner");
println!("Box(ref {}) = {};", inner_pat, current); println!("Box(ref {}) = {};", inner_pat, current);
self.current = inner_pat; self.current = inner_pat;
self.visit_expr(inner); self.visit_expr(inner);
}, },
Expr_::ExprArray(ref elements) => { ExprKind::Array(ref elements) => {
let elements_pat = self.next("elements"); let elements_pat = self.next("elements");
println!("Array(ref {}) = {};", elements_pat, current); println!("Array(ref {}) = {};", elements_pat, current);
println!(" if {}.len() == {};", elements_pat, elements.len()); println!(" if {}.len() == {};", elements_pat, elements.len());
@ -210,7 +210,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.visit_expr(element); self.visit_expr(element);
} }
}, },
Expr_::ExprCall(ref func, ref args) => { ExprKind::Call(ref func, ref args) => {
let func_pat = self.next("func"); let func_pat = self.next("func");
let args_pat = self.next("args"); let args_pat = self.next("args");
println!("Call(ref {}, ref {}) = {};", func_pat, args_pat, current); println!("Call(ref {}, ref {}) = {};", func_pat, args_pat, current);
@ -222,11 +222,11 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.visit_expr(arg); self.visit_expr(arg);
} }
}, },
Expr_::ExprMethodCall(ref _method_name, ref _generics, ref _args) => { ExprKind::MethodCall(ref _method_name, ref _generics, ref _args) => {
println!("MethodCall(ref method_name, ref generics, ref args) = {};", current); println!("MethodCall(ref method_name, ref generics, ref args) = {};", current);
println!(" // unimplemented: `ExprMethodCall` is not further destructured at the moment"); println!(" // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment");
}, },
Expr_::ExprTup(ref elements) => { ExprKind::Tup(ref elements) => {
let elements_pat = self.next("elements"); let elements_pat = self.next("elements");
println!("Tup(ref {}) = {};", elements_pat, current); println!("Tup(ref {}) = {};", elements_pat, current);
println!(" if {}.len() == {};", elements_pat, elements.len()); println!(" if {}.len() == {};", elements_pat, elements.len());
@ -235,24 +235,24 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.visit_expr(element); self.visit_expr(element);
} }
}, },
Expr_::ExprBinary(ref op, ref left, ref right) => { ExprKind::Binary(ref op, ref left, ref right) => {
let op_pat = self.next("op"); let op_pat = self.next("op");
let left_pat = self.next("left"); let left_pat = self.next("left");
let right_pat = self.next("right"); let right_pat = self.next("right");
println!("Binary(ref {}, ref {}, ref {}) = {};", op_pat, left_pat, right_pat, current); println!("Binary(ref {}, ref {}, ref {}) = {};", op_pat, left_pat, right_pat, current);
println!(" if BinOp_::{:?} == {}.node;", op.node, op_pat); println!(" if BinOpKind::{:?} == {}.node;", op.node, op_pat);
self.current = left_pat; self.current = left_pat;
self.visit_expr(left); self.visit_expr(left);
self.current = right_pat; self.current = right_pat;
self.visit_expr(right); self.visit_expr(right);
}, },
Expr_::ExprUnary(ref op, ref inner) => { ExprKind::Unary(ref op, ref inner) => {
let inner_pat = self.next("inner"); let inner_pat = self.next("inner");
println!("Unary(UnOp::{:?}, ref {}) = {};", op, inner_pat, current); println!("Unary(UnOp::{:?}, ref {}) = {};", op, inner_pat, current);
self.current = inner_pat; self.current = inner_pat;
self.visit_expr(inner); self.visit_expr(inner);
}, },
Expr_::ExprLit(ref lit) => { ExprKind::Lit(ref lit) => {
let lit_pat = self.next("lit"); let lit_pat = self.next("lit");
println!("Lit(ref {}) = {};", lit_pat, current); println!("Lit(ref {}) = {};", lit_pat, current);
match lit.node { match lit.node {
@ -277,27 +277,27 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
}, },
} }
}, },
Expr_::ExprCast(ref expr, ref ty) => { ExprKind::Cast(ref expr, ref ty) => {
let cast_pat = self.next("expr"); let cast_pat = self.next("expr");
let cast_ty = self.next("cast_ty"); let cast_ty = self.next("cast_ty");
let qp_label = self.next("qp"); let qp_label = self.next("qp");
println!("Cast(ref {}, ref {}) = {};", cast_pat, cast_ty, current); println!("Cast(ref {}, ref {}) = {};", cast_pat, cast_ty, current);
if let Ty_::TyPath(ref qp) = ty.node { if let TyKind::Path(ref qp) = ty.node {
println!(" if let Ty_::TyPath(ref {}) = {}.node;", qp_label, cast_ty); println!(" if let TyKind::Path(ref {}) = {}.node;", qp_label, cast_ty);
self.current = qp_label; self.current = qp_label;
self.print_qpath(qp); self.print_qpath(qp);
} }
self.current = cast_pat; self.current = cast_pat;
self.visit_expr(expr); self.visit_expr(expr);
}, },
Expr_::ExprType(ref expr, ref _ty) => { ExprKind::Type(ref expr, ref _ty) => {
let cast_pat = self.next("expr"); let cast_pat = self.next("expr");
println!("Type(ref {}, _) = {};", cast_pat, current); println!("Type(ref {}, _) = {};", cast_pat, current);
self.current = cast_pat; self.current = cast_pat;
self.visit_expr(expr); self.visit_expr(expr);
}, },
Expr_::ExprIf(ref cond, ref then, ref opt_else) => { ExprKind::If(ref cond, ref then, ref opt_else) => {
let cond_pat = self.next("cond"); let cond_pat = self.next("cond");
let then_pat = self.next("then"); let then_pat = self.next("then");
if let Some(ref else_) = *opt_else { if let Some(ref else_) = *opt_else {
@ -313,7 +313,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = then_pat; self.current = then_pat;
self.visit_expr(then); self.visit_expr(then);
}, },
Expr_::ExprWhile(ref cond, ref body, _) => { ExprKind::While(ref cond, ref body, _) => {
let cond_pat = self.next("cond"); let cond_pat = self.next("cond");
let body_pat = self.next("body"); let body_pat = self.next("body");
let label_pat = self.next("label"); let label_pat = self.next("label");
@ -323,7 +323,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = body_pat; self.current = body_pat;
self.visit_block(body); self.visit_block(body);
}, },
Expr_::ExprLoop(ref body, _, desugaring) => { ExprKind::Loop(ref body, _, desugaring) => {
let body_pat = self.next("body"); let body_pat = self.next("body");
let des = loop_desugaring_name(desugaring); let des = loop_desugaring_name(desugaring);
let label_pat = self.next("label"); let label_pat = self.next("label");
@ -331,7 +331,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = body_pat; self.current = body_pat;
self.visit_block(body); self.visit_block(body);
}, },
Expr_::ExprMatch(ref expr, ref arms, desugaring) => { ExprKind::Match(ref expr, ref arms, desugaring) => {
let des = desugaring_name(desugaring); let des = desugaring_name(desugaring);
let expr_pat = self.next("expr"); let expr_pat = self.next("expr");
let arms_pat = self.next("arms"); let arms_pat = self.next("arms");
@ -355,23 +355,23 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
} }
} }
}, },
Expr_::ExprClosure(ref _capture_clause, ref _func, _, _, _) => { ExprKind::Closure(ref _capture_clause, ref _func, _, _, _) => {
println!("Closure(ref capture_clause, ref func, _, _, _) = {};", current); println!("Closure(ref capture_clause, ref func, _, _, _) = {};", current);
println!(" // unimplemented: `ExprClosure` is not further destructured at the moment"); println!(" // unimplemented: `ExprKind::Closure` is not further destructured at the moment");
}, },
Expr_::ExprYield(ref sub) => { ExprKind::Yield(ref sub) => {
let sub_pat = self.next("sub"); let sub_pat = self.next("sub");
println!("Yield(ref sub) = {};", current); println!("Yield(ref sub) = {};", current);
self.current = sub_pat; self.current = sub_pat;
self.visit_expr(sub); self.visit_expr(sub);
}, },
Expr_::ExprBlock(ref block, _) => { ExprKind::Block(ref block, _) => {
let block_pat = self.next("block"); let block_pat = self.next("block");
println!("Block(ref {}) = {};", block_pat, current); println!("Block(ref {}) = {};", block_pat, current);
self.current = block_pat; self.current = block_pat;
self.visit_block(block); self.visit_block(block);
}, },
Expr_::ExprAssign(ref target, ref value) => { ExprKind::Assign(ref target, ref value) => {
let target_pat = self.next("target"); let target_pat = self.next("target");
let value_pat = self.next("value"); let value_pat = self.next("value");
println!("Assign(ref {}, ref {}) = {};", target_pat, value_pat, current); println!("Assign(ref {}, ref {}) = {};", target_pat, value_pat, current);
@ -380,18 +380,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = value_pat; self.current = value_pat;
self.visit_expr(value); self.visit_expr(value);
}, },
Expr_::ExprAssignOp(ref op, ref target, ref value) => { ExprKind::AssignOp(ref op, ref target, ref value) => {
let op_pat = self.next("op"); let op_pat = self.next("op");
let target_pat = self.next("target"); let target_pat = self.next("target");
let value_pat = self.next("value"); let value_pat = self.next("value");
println!("AssignOp(ref {}, ref {}, ref {}) = {};", op_pat, target_pat, value_pat, current); println!("AssignOp(ref {}, ref {}, ref {}) = {};", op_pat, target_pat, value_pat, current);
println!(" if BinOp_::{:?} == {}.node;", op.node, op_pat); println!(" if BinOpKind::{:?} == {}.node;", op.node, op_pat);
self.current = target_pat; self.current = target_pat;
self.visit_expr(target); self.visit_expr(target);
self.current = value_pat; self.current = value_pat;
self.visit_expr(value); self.visit_expr(value);
}, },
Expr_::ExprField(ref object, ref field_ident) => { ExprKind::Field(ref object, ref field_ident) => {
let obj_pat = self.next("object"); let obj_pat = self.next("object");
let field_name_pat = self.next("field_name"); let field_name_pat = self.next("field_name");
println!("Field(ref {}, ref {}) = {};", obj_pat, field_name_pat, current); println!("Field(ref {}, ref {}) = {};", obj_pat, field_name_pat, current);
@ -399,7 +399,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = obj_pat; self.current = obj_pat;
self.visit_expr(object); self.visit_expr(object);
}, },
Expr_::ExprIndex(ref object, ref index) => { ExprKind::Index(ref object, ref index) => {
let object_pat = self.next("object"); let object_pat = self.next("object");
let index_pat = self.next("index"); let index_pat = self.next("index");
println!("Index(ref {}, ref {}) = {};", object_pat, index_pat, current); println!("Index(ref {}, ref {}) = {};", object_pat, index_pat, current);
@ -408,19 +408,19 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = index_pat; self.current = index_pat;
self.visit_expr(index); self.visit_expr(index);
}, },
Expr_::ExprPath(ref path) => { ExprKind::Path(ref path) => {
let path_pat = self.next("path"); let path_pat = self.next("path");
println!("Path(ref {}) = {};", path_pat, current); println!("Path(ref {}) = {};", path_pat, current);
self.current = path_pat; self.current = path_pat;
self.print_qpath(path); self.print_qpath(path);
}, },
Expr_::ExprAddrOf(mutability, ref inner) => { ExprKind::AddrOf(mutability, ref inner) => {
let inner_pat = self.next("inner"); let inner_pat = self.next("inner");
println!("AddrOf({:?}, ref {}) = {};", mutability, inner_pat, current); println!("AddrOf({:?}, ref {}) = {};", mutability, inner_pat, current);
self.current = inner_pat; self.current = inner_pat;
self.visit_expr(inner); self.visit_expr(inner);
}, },
Expr_::ExprBreak(ref _destination, ref opt_value) => { ExprKind::Break(ref _destination, ref opt_value) => {
let destination_pat = self.next("destination"); let destination_pat = self.next("destination");
if let Some(ref value) = *opt_value { if let Some(ref value) = *opt_value {
let value_pat = self.next("value"); let value_pat = self.next("value");
@ -432,12 +432,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
} }
// FIXME: implement label printing // FIXME: implement label printing
}, },
Expr_::ExprContinue(ref _destination) => { ExprKind::Continue(ref _destination) => {
let destination_pat = self.next("destination"); let destination_pat = self.next("destination");
println!("Again(ref {}) = {};", destination_pat, current); println!("Again(ref {}) = {};", destination_pat, current);
// FIXME: implement label printing // FIXME: implement label printing
}, },
Expr_::ExprRet(ref opt_value) => if let Some(ref value) = *opt_value { ExprKind::Ret(ref opt_value) => if let Some(ref value) = *opt_value {
let value_pat = self.next("value"); let value_pat = self.next("value");
println!("Ret(Some(ref {})) = {};", value_pat, current); println!("Ret(Some(ref {})) = {};", value_pat, current);
self.current = value_pat; self.current = value_pat;
@ -445,11 +445,11 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
} else { } else {
println!("Ret(None) = {};", current); println!("Ret(None) = {};", current);
}, },
Expr_::ExprInlineAsm(_, ref _input, ref _output) => { ExprKind::InlineAsm(_, ref _input, ref _output) => {
println!("InlineAsm(_, ref input, ref output) = {};", current); println!("InlineAsm(_, ref input, ref output) = {};", current);
println!(" // unimplemented: `ExprInlineAsm` is not further destructured at the moment"); println!(" // unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment");
}, },
Expr_::ExprStruct(ref path, ref fields, ref opt_base) => { ExprKind::Struct(ref path, ref fields, ref opt_base) => {
let path_pat = self.next("path"); let path_pat = self.next("path");
let fields_pat = self.next("fields"); let fields_pat = self.next("fields");
if let Some(ref base) = *opt_base { if let Some(ref base) = *opt_base {
@ -472,7 +472,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
println!(" // unimplemented: field checks"); println!(" // unimplemented: field checks");
}, },
// FIXME: compute length (needs type info) // FIXME: compute length (needs type info)
Expr_::ExprRepeat(ref value, _) => { ExprKind::Repeat(ref value, _) => {
let value_pat = self.next("value"); let value_pat = self.next("value");
println!("Repeat(ref {}, _) = {};", value_pat, current); println!("Repeat(ref {}, _) = {};", value_pat, current);
println!("// unimplemented: repeat count check"); println!("// unimplemented: repeat count check");
@ -588,20 +588,20 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
} }
fn visit_stmt(&mut self, s: &Stmt) { fn visit_stmt(&mut self, s: &Stmt) {
print!(" if let Stmt_::"); print!(" if let StmtKind::");
let current = format!("{}.node", self.current); let current = format!("{}.node", self.current);
match s.node { match s.node {
// Could be an item or a local (let) binding: // Could be an item or a local (let) binding:
StmtDecl(ref decl, _) => { StmtKind::Decl(ref decl, _) => {
let decl_pat = self.next("decl"); let decl_pat = self.next("decl");
println!("StmtDecl(ref {}, _) = {}", decl_pat, current); println!("Decl(ref {}, _) = {}", decl_pat, current);
print!(" if let Decl_::"); print!(" if let DeclKind::");
let current = format!("{}.node", decl_pat); let current = format!("{}.node", decl_pat);
match decl.node { match decl.node {
// A local (let) binding: // A local (let) binding:
Decl_::DeclLocal(ref local) => { DeclKind::Local(ref local) => {
let local_pat = self.next("local"); let local_pat = self.next("local");
println!("DeclLocal(ref {}) = {};", local_pat, current); println!("Local(ref {}) = {};", local_pat, current);
if let Some(ref init) = local.init { if let Some(ref init) = local.init {
let init_pat = self.next("init"); let init_pat = self.next("init");
println!(" if let Some(ref {}) = {}.init", init_pat, local_pat); println!(" if let Some(ref {}) = {}.init", init_pat, local_pat);
@ -612,24 +612,24 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.visit_pat(&local.pat); self.visit_pat(&local.pat);
}, },
// An item binding: // An item binding:
Decl_::DeclItem(_) => { DeclKind::Item(_) => {
println!("DeclItem(item_id) = {};", current); println!("Item(item_id) = {};", current);
}, },
} }
} }
// Expr without trailing semi-colon (must have unit type): // Expr without trailing semi-colon (must have unit type):
StmtExpr(ref e, _) => { StmtKind::Expr(ref e, _) => {
let e_pat = self.next("e"); let e_pat = self.next("e");
println!("StmtExpr(ref {}, _) = {}", e_pat, current); println!("Expr(ref {}, _) = {}", e_pat, current);
self.current = e_pat; self.current = e_pat;
self.visit_expr(e); self.visit_expr(e);
}, },
// Expr with trailing semi-colon (may have any type): // Expr with trailing semi-colon (may have any type):
StmtSemi(ref e, _) => { StmtKind::Semi(ref e, _) => {
let e_pat = self.next("e"); let e_pat = self.next("e");
println!("StmtSemi(ref {}, _) = {}", e_pat, current); println!("Semi(ref {}, _) = {}", e_pat, current);
self.current = e_pat; self.current = e_pat;
self.visit_expr(e); self.visit_expr(e);
}, },
@ -674,7 +674,7 @@ fn print_path(path: &QPath, first: &mut bool) {
print!("{:?}", segment.ident.as_str()); print!("{:?}", segment.ident.as_str());
}, },
QPath::TypeRelative(ref ty, ref segment) => match ty.node { QPath::TypeRelative(ref ty, ref segment) => match ty.node {
hir::Ty_::TyPath(ref inner_path) => { hir::TyKind::Path(ref inner_path) => {
print_path(inner_path, first); print_path(inner_path, first);
if *first { if *first {
*first = false; *first = false;

View File

@ -2,7 +2,7 @@
#![deny(missing_docs_in_private_items)] #![deny(missing_docs_in_private_items)]
use rustc::hir::{BinOp_, Expr}; use rustc::hir::{BinOpKind, Expr};
#[derive(PartialEq, Eq, Debug, Copy, Clone)] #[derive(PartialEq, Eq, Debug, Copy, Clone)]
/// Represent a normalized comparison operator. /// Represent a normalized comparison operator.
@ -19,14 +19,14 @@ pub enum Rel {
/// Put the expression in the form `lhs < rhs`, `lhs <= rhs`, `lhs == rhs` or /// Put the expression in the form `lhs < rhs`, `lhs <= rhs`, `lhs == rhs` or
/// `lhs != rhs`. /// `lhs != rhs`.
pub fn normalize_comparison<'a>(op: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(Rel, &'a Expr, &'a Expr)> { pub fn normalize_comparison<'a>(op: BinOpKind, lhs: &'a Expr, rhs: &'a Expr) -> Option<(Rel, &'a Expr, &'a Expr)> {
match op { match op {
BinOp_::BiLt => Some((Rel::Lt, lhs, rhs)), BinOpKind::Lt => Some((Rel::Lt, lhs, rhs)),
BinOp_::BiLe => Some((Rel::Le, lhs, rhs)), BinOpKind::Le => Some((Rel::Le, lhs, rhs)),
BinOp_::BiGt => Some((Rel::Lt, rhs, lhs)), BinOpKind::Gt => Some((Rel::Lt, rhs, lhs)),
BinOp_::BiGe => Some((Rel::Le, rhs, lhs)), BinOpKind::Ge => Some((Rel::Le, rhs, lhs)),
BinOp_::BiEq => Some((Rel::Eq, rhs, lhs)), BinOpKind::Eq => Some((Rel::Eq, rhs, lhs)),
BinOp_::BiNe => Some((Rel::Ne, rhs, lhs)), BinOpKind::Ne => Some((Rel::Ne, rhs, lhs)),
_ => None, _ => None,
} }
} }

View File

@ -9,26 +9,26 @@ use syntax::ast;
use crate::utils::{is_expn_of, match_def_path, match_qpath, opt_def_id, paths, resolve_node}; use crate::utils::{is_expn_of, match_def_path, match_qpath, opt_def_id, paths, resolve_node};
/// Convert a hir binary operator to the corresponding `ast` type. /// Convert a hir binary operator to the corresponding `ast` type.
pub fn binop(op: hir::BinOp_) -> ast::BinOpKind { pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
match op { match op {
hir::BiEq => ast::BinOpKind::Eq, hir::BinOpKind::Eq => ast::BinOpKind::Eq,
hir::BiGe => ast::BinOpKind::Ge, hir::BinOpKind::Ge => ast::BinOpKind::Ge,
hir::BiGt => ast::BinOpKind::Gt, hir::BinOpKind::Gt => ast::BinOpKind::Gt,
hir::BiLe => ast::BinOpKind::Le, hir::BinOpKind::Le => ast::BinOpKind::Le,
hir::BiLt => ast::BinOpKind::Lt, hir::BinOpKind::Lt => ast::BinOpKind::Lt,
hir::BiNe => ast::BinOpKind::Ne, hir::BinOpKind::Ne => ast::BinOpKind::Ne,
hir::BiOr => ast::BinOpKind::Or, hir::BinOpKind::Or => ast::BinOpKind::Or,
hir::BiAdd => ast::BinOpKind::Add, hir::BinOpKind::Add => ast::BinOpKind::Add,
hir::BiAnd => ast::BinOpKind::And, hir::BinOpKind::And => ast::BinOpKind::And,
hir::BiBitAnd => ast::BinOpKind::BitAnd, hir::BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
hir::BiBitOr => ast::BinOpKind::BitOr, hir::BinOpKind::BitOr => ast::BinOpKind::BitOr,
hir::BiBitXor => ast::BinOpKind::BitXor, hir::BinOpKind::BitXor => ast::BinOpKind::BitXor,
hir::BiDiv => ast::BinOpKind::Div, hir::BinOpKind::Div => ast::BinOpKind::Div,
hir::BiMul => ast::BinOpKind::Mul, hir::BinOpKind::Mul => ast::BinOpKind::Mul,
hir::BiRem => ast::BinOpKind::Rem, hir::BinOpKind::Rem => ast::BinOpKind::Rem,
hir::BiShl => ast::BinOpKind::Shl, hir::BinOpKind::Shl => ast::BinOpKind::Shl,
hir::BiShr => ast::BinOpKind::Shr, hir::BinOpKind::Shr => ast::BinOpKind::Shr,
hir::BiSub => ast::BinOpKind::Sub, hir::BinOpKind::Sub => ast::BinOpKind::Sub,
} }
} }
@ -87,7 +87,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
// `#[no_std]`. Testing both instead of resolving the paths. // `#[no_std]`. Testing both instead of resolving the paths.
match expr.node { match expr.node {
hir::ExprPath(ref path) => { hir::ExprKind::Path(ref path) => {
if match_qpath(path, &paths::RANGE_FULL_STD) || match_qpath(path, &paths::RANGE_FULL) { if match_qpath(path, &paths::RANGE_FULL_STD) || match_qpath(path, &paths::RANGE_FULL) {
Some(Range { Some(Range {
start: None, start: None,
@ -98,7 +98,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
None None
} }
}, },
hir::ExprCall(ref path, ref args) => if let hir::ExprPath(ref path) = path.node { hir::ExprKind::Call(ref path, ref args) => if let hir::ExprKind::Path(ref path) = path.node {
if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW) { if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW) {
Some(Range { Some(Range {
start: Some(&args[0]), start: Some(&args[0]),
@ -111,7 +111,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
} else { } else {
None None
}, },
hir::ExprStruct(ref path, ref fields, None) => if match_qpath(path, &paths::RANGE_FROM_STD) hir::ExprKind::Struct(ref path, ref fields, None) => if match_qpath(path, &paths::RANGE_FROM_STD)
|| match_qpath(path, &paths::RANGE_FROM) || match_qpath(path, &paths::RANGE_FROM)
{ {
Some(Range { Some(Range {
@ -154,9 +154,9 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
// } // }
// ``` // ```
if_chain! { if_chain! {
if let hir::DeclLocal(ref loc) = decl.node; if let hir::DeclKind::Local(ref loc) = decl.node;
if let Some(ref expr) = loc.init; if let Some(ref expr) = loc.init;
if let hir::ExprMatch(_, _, hir::MatchSource::ForLoopDesugar) = expr.node; if let hir::ExprKind::Match(_, _, hir::MatchSource::ForLoopDesugar) = expr.node;
then { then {
return true; return true;
} }
@ -171,7 +171,7 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
// } // }
// ``` // ```
if_chain! { if_chain! {
if let hir::DeclLocal(ref loc) = decl.node; if let hir::DeclKind::Local(ref loc) = decl.node;
if let hir::LocalSource::ForLoopDesugar = loc.source; if let hir::LocalSource::ForLoopDesugar = loc.source;
then { then {
return true; return true;
@ -185,15 +185,15 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
/// `for pat in arg { body }` becomes `(pat, arg, body)`. /// `for pat in arg { body }` becomes `(pat, arg, body)`.
pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> { pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> {
if_chain! { if_chain! {
if let hir::ExprMatch(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node; if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node;
if let hir::ExprCall(_, ref iterargs) = iterexpr.node; if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.node;
if iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none(); if iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none();
if let hir::ExprLoop(ref block, _, _) = arms[0].body.node; if let hir::ExprKind::Loop(ref block, _, _) = arms[0].body.node;
if block.expr.is_none(); if block.expr.is_none();
if let [ _, _, ref let_stmt, ref body ] = *block.stmts; if let [ _, _, ref let_stmt, ref body ] = *block.stmts;
if let hir::StmtDecl(ref decl, _) = let_stmt.node; if let hir::StmtKind::Decl(ref decl, _) = let_stmt.node;
if let hir::DeclLocal(ref decl) = decl.node; if let hir::DeclKind::Local(ref decl) = decl.node;
if let hir::StmtExpr(ref expr, _) = body.node; if let hir::StmtKind::Expr(ref expr, _) = body.node;
then { then {
return Some((&*decl.pat, &iterargs[0], expr)); return Some((&*decl.pat, &iterargs[0], expr));
} }
@ -213,8 +213,8 @@ pub enum VecArgs<'a> {
/// from `vec!`. /// from `vec!`.
pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e>> { pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e>> {
if_chain! { if_chain! {
if let hir::ExprCall(ref fun, ref args) = expr.node; if let hir::ExprKind::Call(ref fun, ref args) = expr.node;
if let hir::ExprPath(ref path) = fun.node; if let hir::ExprKind::Path(ref path) = fun.node;
if is_expn_of(fun.span, "vec").is_some(); if is_expn_of(fun.span, "vec").is_some();
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, path, fun.hir_id)); if let Some(fun_def_id) = opt_def_id(resolve_node(cx, path, fun.hir_id));
then { then {
@ -225,8 +225,8 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e
else if match_def_path(cx.tcx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 { else if match_def_path(cx.tcx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
// `vec![a, b, c]` case // `vec![a, b, c]` case
if_chain! { if_chain! {
if let hir::ExprBox(ref boxed) = args[0].node; if let hir::ExprKind::Box(ref boxed) = args[0].node;
if let hir::ExprArray(ref args) = boxed.node; if let hir::ExprKind::Array(ref args) = boxed.node;
then { then {
return Some(VecArgs::Vec(&*args)); return Some(VecArgs::Vec(&*args));
} }

View File

@ -43,14 +43,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
/// Check whether two statements are the same. /// Check whether two statements are the same.
pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool { pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool {
match (&left.node, &right.node) { match (&left.node, &right.node) {
(&StmtDecl(ref l, _), &StmtDecl(ref r, _)) => { (&StmtKind::Decl(ref l, _), &StmtKind::Decl(ref r, _)) => {
if let (&DeclLocal(ref l), &DeclLocal(ref r)) = (&l.node, &r.node) { if let (&DeclKind::Local(ref l), &DeclKind::Local(ref r)) = (&l.node, &r.node) {
both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
} else { } else {
false false
} }
}, },
(&StmtExpr(ref l, _), &StmtExpr(ref r, _)) | (&StmtSemi(ref l, _), &StmtSemi(ref r, _)) => { (&StmtKind::Expr(ref l, _), &StmtKind::Expr(ref r, _)) | (&StmtKind::Semi(ref l, _), &StmtKind::Semi(ref r, _)) => {
self.eq_expr(l, r) self.eq_expr(l, r)
}, },
_ => false, _ => false,
@ -75,52 +75,52 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
} }
match (&left.node, &right.node) { match (&left.node, &right.node) {
(&ExprAddrOf(l_mut, ref le), &ExprAddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re), (&ExprKind::AddrOf(l_mut, ref le), &ExprKind::AddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re),
(&ExprContinue(li), &ExprContinue(ri)) => { (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str()) both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str())
}, },
(&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr), (&ExprKind::Assign(ref ll, ref lr), &ExprKind::Assign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr),
(&ExprAssignOp(ref lo, ref ll, ref lr), &ExprAssignOp(ref ro, ref rl, ref rr)) => { (&ExprKind::AssignOp(ref lo, ref ll, ref lr), &ExprKind::AssignOp(ref ro, ref rl, ref rr)) => {
lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
}, },
(&ExprBlock(ref l, _), &ExprBlock(ref r, _)) => self.eq_block(l, r), (&ExprKind::Block(ref l, _), &ExprKind::Block(ref r, _)) => self.eq_block(l, r),
(&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => { (&ExprKind::Binary(l_op, ref ll, ref lr), &ExprKind::Binary(r_op, ref rl, ref rr)) => {
l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
|| swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| { || swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| {
l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
}) })
}, },
(&ExprBreak(li, ref le), &ExprBreak(ri, ref re)) => { (&ExprKind::Break(li, ref le), &ExprKind::Break(ri, ref re)) => {
both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str()) both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str())
&& both(le, re, |l, r| self.eq_expr(l, r)) && both(le, re, |l, r| self.eq_expr(l, r))
}, },
(&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r), (&ExprKind::Box(ref l), &ExprKind::Box(ref r)) => self.eq_expr(l, r),
(&ExprCall(ref l_fun, ref l_args), &ExprCall(ref r_fun, ref r_args)) => { (&ExprKind::Call(ref l_fun, ref l_args), &ExprKind::Call(ref r_fun, ref r_args)) => {
!self.ignore_fn && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args) !self.ignore_fn && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
}, },
(&ExprCast(ref lx, ref lt), &ExprCast(ref rx, ref rt)) | (&ExprKind::Cast(ref lx, ref lt), &ExprKind::Cast(ref rx, ref rt)) |
(&ExprType(ref lx, ref lt), &ExprType(ref rx, ref rt)) => self.eq_expr(lx, rx) && self.eq_ty(lt, rt), (&ExprKind::Type(ref lx, ref lt), &ExprKind::Type(ref rx, ref rt)) => self.eq_expr(lx, rx) && self.eq_ty(lt, rt),
(&ExprField(ref l_f_exp, ref l_f_ident), &ExprField(ref r_f_exp, ref r_f_ident)) => { (&ExprKind::Field(ref l_f_exp, ref l_f_ident), &ExprKind::Field(ref r_f_exp, ref r_f_ident)) => {
l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp) l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp)
}, },
(&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri), (&ExprKind::Index(ref la, ref li), &ExprKind::Index(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
(&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => { (&ExprKind::If(ref lc, ref lt, ref le), &ExprKind::If(ref rc, ref rt, ref re)) => {
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r)) self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
}, },
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node, (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
(&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => { (&ExprKind::Loop(ref lb, ref ll, ref lls), &ExprKind::Loop(ref rb, ref rl, ref rls)) => {
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str()) lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
}, },
(&ExprMatch(ref le, ref la, ref ls), &ExprMatch(ref re, ref ra, ref rs)) => { (&ExprKind::Match(ref le, ref la, ref ls), &ExprKind::Match(ref re, ref ra, ref rs)) => {
ls == rs && self.eq_expr(le, re) && over(la, ra, |l, r| { ls == rs && self.eq_expr(le, re) && over(la, ra, |l, r| {
self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r))
&& over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) && over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r))
}) })
}, },
(&ExprMethodCall(ref l_path, _, ref l_args), &ExprMethodCall(ref r_path, _, ref r_args)) => { (&ExprKind::MethodCall(ref l_path, _, ref l_args), &ExprKind::MethodCall(ref r_path, _, ref r_args)) => {
!self.ignore_fn && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args) !self.ignore_fn && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args)
}, },
(&ExprRepeat(ref le, ref ll_id), &ExprRepeat(ref re, ref rl_id)) => { (&ExprKind::Repeat(ref le, ref ll_id), &ExprKind::Repeat(ref re, ref rl_id)) => {
let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body));
let ll = celcx.expr(&self.cx.tcx.hir.body(ll_id.body).value); let ll = celcx.expr(&self.cx.tcx.hir.body(ll_id.body).value);
let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(rl_id.body)); let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(rl_id.body));
@ -128,16 +128,16 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
self.eq_expr(le, re) && ll == rl self.eq_expr(le, re) && ll == rl
}, },
(&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)), (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
(&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r), (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
(&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => { (&ExprKind::Struct(ref l_path, ref lf, ref lo), &ExprKind::Struct(ref r_path, ref rf, ref ro)) => {
self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r))
&& over(lf, rf, |l, r| self.eq_field(l, r)) && over(lf, rf, |l, r| self.eq_field(l, r))
}, },
(&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup), (&ExprKind::Tup(ref l_tup), &ExprKind::Tup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
(&ExprUnary(l_op, ref le), &ExprUnary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Unary(l_op, ref le), &ExprKind::Unary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re),
(&ExprArray(ref l), &ExprArray(ref r)) => self.eq_exprs(l, r), (&ExprKind::Array(ref l), &ExprKind::Array(ref r)) => self.eq_exprs(l, r),
(&ExprWhile(ref lc, ref lb, ref ll), &ExprWhile(ref rc, ref rb, ref rl)) => { (&ExprKind::While(ref lc, ref lb, ref ll), &ExprKind::While(ref rc, ref rb, ref rl)) => {
self.eq_expr(lc, rc) && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str()) self.eq_expr(lc, rc) && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
}, },
_ => false, _ => false,
@ -246,10 +246,10 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
self.eq_ty_kind(&left.node, &right.node) self.eq_ty_kind(&left.node, &right.node)
} }
pub fn eq_ty_kind(&mut self, left: &Ty_, right: &Ty_) -> bool { pub fn eq_ty_kind(&mut self, left: &TyKind, right: &TyKind) -> bool {
match (left, right) { match (left, right) {
(&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec), (&TyKind::Slice(ref l_vec), &TyKind::Slice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
(&TyArray(ref lt, ref ll_id), &TyArray(ref rt, ref rl_id)) => { (&TyKind::Array(ref lt, ref ll_id), &TyKind::Array(ref rt, ref rl_id)) => {
let full_table = self.tables; let full_table = self.tables;
let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body));
@ -264,13 +264,13 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
self.tables = full_table; self.tables = full_table;
eq_ty && ll == rl eq_ty && ll == rl
}, },
(&TyPtr(ref l_mut), &TyPtr(ref r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty), (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty),
(&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => { (&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => {
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(&*l_rmut.ty, &*r_rmut.ty) l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(&*l_rmut.ty, &*r_rmut.ty)
}, },
(&TyPath(ref l), &TyPath(ref r)) => self.eq_qpath(l, r), (&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r),
(&TyTup(ref l), &TyTup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)), (&TyKind::Tup(ref l), &TyKind::Tup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)),
(&TyInfer, &TyInfer) => true, (&TyKind::Infer, &TyKind::Infer) => true,
_ => false, _ => false,
} }
} }
@ -280,14 +280,26 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
} }
} }
fn swap_binop<'a>(binop: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOp_, &'a Expr, &'a Expr)> { fn swap_binop<'a>(binop: BinOpKind, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOpKind, &'a Expr, &'a Expr)> {
match binop { match binop {
BiAdd | BiMul | BiBitXor | BiBitAnd | BiEq | BiNe | BiBitOr => Some((binop, rhs, lhs)), BinOpKind::Add |
BiLt => Some((BiGt, rhs, lhs)), BinOpKind::Mul |
BiLe => Some((BiGe, rhs, lhs)), BinOpKind::Eq |
BiGe => Some((BiLe, rhs, lhs)), BinOpKind::Ne |
BiGt => Some((BiLt, rhs, lhs)), BinOpKind::BitAnd |
BiShl | BiShr | BiRem | BiSub | BiDiv | BiAnd | BiOr => None, BinOpKind::BitXor |
BinOpKind::BitOr => Some((binop, rhs, lhs)),
BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)),
BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)),
BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)),
BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)),
BinOpKind::Shl |
BinOpKind::Shr |
BinOpKind::Rem |
BinOpKind::Sub |
BinOpKind::Div |
BinOpKind::And |
BinOpKind::Or => None,
} }
} }
@ -359,51 +371,51 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
} }
match e.node { match e.node {
ExprAddrOf(m, ref e) => { ExprKind::AddrOf(m, ref e) => {
let c: fn(_, _) -> _ = ExprAddrOf; let c: fn(_, _) -> _ = ExprKind::AddrOf;
c.hash(&mut self.s); c.hash(&mut self.s);
m.hash(&mut self.s); m.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
}, },
ExprContinue(i) => { ExprKind::Continue(i) => {
let c: fn(_) -> _ = ExprContinue; let c: fn(_) -> _ = ExprKind::Continue;
c.hash(&mut self.s); c.hash(&mut self.s);
if let Some(i) = i.label { if let Some(i) = i.label {
self.hash_name(i.ident.name); self.hash_name(i.ident.name);
} }
}, },
ExprYield(ref e) => { ExprKind::Yield(ref e) => {
let c: fn(_) -> _ = ExprYield; let c: fn(_) -> _ = ExprKind::Yield;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
}, },
ExprAssign(ref l, ref r) => { ExprKind::Assign(ref l, ref r) => {
let c: fn(_, _) -> _ = ExprAssign; let c: fn(_, _) -> _ = ExprKind::Assign;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(l); self.hash_expr(l);
self.hash_expr(r); self.hash_expr(r);
}, },
ExprAssignOp(ref o, ref l, ref r) => { ExprKind::AssignOp(ref o, ref l, ref r) => {
let c: fn(_, _, _) -> _ = ExprAssignOp; let c: fn(_, _, _) -> _ = ExprKind::AssignOp;
c.hash(&mut self.s); c.hash(&mut self.s);
o.hash(&mut self.s); o.hash(&mut self.s);
self.hash_expr(l); self.hash_expr(l);
self.hash_expr(r); self.hash_expr(r);
}, },
ExprBlock(ref b, _) => { ExprKind::Block(ref b, _) => {
let c: fn(_, _) -> _ = ExprBlock; let c: fn(_, _) -> _ = ExprKind::Block;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_block(b); self.hash_block(b);
}, },
ExprBinary(op, ref l, ref r) => { ExprKind::Binary(op, ref l, ref r) => {
let c: fn(_, _, _) -> _ = ExprBinary; let c: fn(_, _, _) -> _ = ExprKind::Binary;
c.hash(&mut self.s); c.hash(&mut self.s);
op.node.hash(&mut self.s); op.node.hash(&mut self.s);
self.hash_expr(l); self.hash_expr(l);
self.hash_expr(r); self.hash_expr(r);
}, },
ExprBreak(i, ref j) => { ExprKind::Break(i, ref j) => {
let c: fn(_, _) -> _ = ExprBreak; let c: fn(_, _) -> _ = ExprKind::Break;
c.hash(&mut self.s); c.hash(&mut self.s);
if let Some(i) = i.label { if let Some(i) = i.label {
self.hash_name(i.ident.name); self.hash_name(i.ident.name);
@ -412,25 +424,25 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
self.hash_expr(&*j); self.hash_expr(&*j);
} }
}, },
ExprBox(ref e) => { ExprKind::Box(ref e) => {
let c: fn(_) -> _ = ExprBox; let c: fn(_) -> _ = ExprKind::Box;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
}, },
ExprCall(ref fun, ref args) => { ExprKind::Call(ref fun, ref args) => {
let c: fn(_, _) -> _ = ExprCall; let c: fn(_, _) -> _ = ExprKind::Call;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(fun); self.hash_expr(fun);
self.hash_exprs(args); self.hash_exprs(args);
}, },
ExprCast(ref e, ref _ty) => { ExprKind::Cast(ref e, ref _ty) => {
let c: fn(_, _) -> _ = ExprCast; let c: fn(_, _) -> _ = ExprKind::Cast;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
// TODO: _ty // TODO: _ty
}, },
ExprClosure(cap, _, eid, _, _) => { ExprKind::Closure(cap, _, eid, _, _) => {
let c: fn(_, _, _, _, _) -> _ = ExprClosure; let c: fn(_, _, _, _, _) -> _ = ExprKind::Closure;
c.hash(&mut self.s); c.hash(&mut self.s);
match cap { match cap {
CaptureClause::CaptureByValue => 0, CaptureClause::CaptureByValue => 0,
@ -438,24 +450,24 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
}.hash(&mut self.s); }.hash(&mut self.s);
self.hash_expr(&self.cx.tcx.hir.body(eid).value); self.hash_expr(&self.cx.tcx.hir.body(eid).value);
}, },
ExprField(ref e, ref f) => { ExprKind::Field(ref e, ref f) => {
let c: fn(_, _) -> _ = ExprField; let c: fn(_, _) -> _ = ExprKind::Field;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
self.hash_name(f.name); self.hash_name(f.name);
}, },
ExprIndex(ref a, ref i) => { ExprKind::Index(ref a, ref i) => {
let c: fn(_, _) -> _ = ExprIndex; let c: fn(_, _) -> _ = ExprKind::Index;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(a); self.hash_expr(a);
self.hash_expr(i); self.hash_expr(i);
}, },
ExprInlineAsm(..) => { ExprKind::InlineAsm(..) => {
let c: fn(_, _, _) -> _ = ExprInlineAsm; let c: fn(_, _, _) -> _ = ExprKind::InlineAsm;
c.hash(&mut self.s); c.hash(&mut self.s);
}, },
ExprIf(ref cond, ref t, ref e) => { ExprKind::If(ref cond, ref t, ref e) => {
let c: fn(_, _, _) -> _ = ExprIf; let c: fn(_, _, _) -> _ = ExprKind::If;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(cond); self.hash_expr(cond);
self.hash_expr(&**t); self.hash_expr(&**t);
@ -463,21 +475,21 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
self.hash_expr(e); self.hash_expr(e);
} }
}, },
ExprLit(ref l) => { ExprKind::Lit(ref l) => {
let c: fn(_) -> _ = ExprLit; let c: fn(_) -> _ = ExprKind::Lit;
c.hash(&mut self.s); c.hash(&mut self.s);
l.hash(&mut self.s); l.hash(&mut self.s);
}, },
ExprLoop(ref b, ref i, _) => { ExprKind::Loop(ref b, ref i, _) => {
let c: fn(_, _, _) -> _ = ExprLoop; let c: fn(_, _, _) -> _ = ExprKind::Loop;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_block(b); self.hash_block(b);
if let Some(i) = *i { if let Some(i) = *i {
self.hash_name(i.ident.name); self.hash_name(i.ident.name);
} }
}, },
ExprMatch(ref e, ref arms, ref s) => { ExprKind::Match(ref e, ref arms, ref s) => {
let c: fn(_, _, _) -> _ = ExprMatch; let c: fn(_, _, _) -> _ = ExprKind::Match;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
@ -491,14 +503,14 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
s.hash(&mut self.s); s.hash(&mut self.s);
}, },
ExprMethodCall(ref path, ref _tys, ref args) => { ExprKind::MethodCall(ref path, ref _tys, ref args) => {
let c: fn(_, _, _) -> _ = ExprMethodCall; let c: fn(_, _, _) -> _ = ExprKind::MethodCall;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_name(path.ident.name); self.hash_name(path.ident.name);
self.hash_exprs(args); self.hash_exprs(args);
}, },
ExprRepeat(ref e, ref l_id) => { ExprKind::Repeat(ref e, ref l_id) => {
let c: fn(_, _) -> _ = ExprRepeat; let c: fn(_, _) -> _ = ExprKind::Repeat;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
let full_table = self.tables; let full_table = self.tables;
@ -506,20 +518,20 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
self.hash_expr(&self.cx.tcx.hir.body(l_id.body).value); self.hash_expr(&self.cx.tcx.hir.body(l_id.body).value);
self.tables = full_table; self.tables = full_table;
}, },
ExprRet(ref e) => { ExprKind::Ret(ref e) => {
let c: fn(_) -> _ = ExprRet; let c: fn(_) -> _ = ExprKind::Ret;
c.hash(&mut self.s); c.hash(&mut self.s);
if let Some(ref e) = *e { if let Some(ref e) = *e {
self.hash_expr(e); self.hash_expr(e);
} }
}, },
ExprPath(ref qpath) => { ExprKind::Path(ref qpath) => {
let c: fn(_) -> _ = ExprPath; let c: fn(_) -> _ = ExprKind::Path;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_qpath(qpath); self.hash_qpath(qpath);
}, },
ExprStruct(ref path, ref fields, ref expr) => { ExprKind::Struct(ref path, ref fields, ref expr) => {
let c: fn(_, _, _) -> _ = ExprStruct; let c: fn(_, _, _) -> _ = ExprKind::Struct;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_qpath(path); self.hash_qpath(path);
@ -533,32 +545,32 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
self.hash_expr(e); self.hash_expr(e);
} }
}, },
ExprTup(ref tup) => { ExprKind::Tup(ref tup) => {
let c: fn(_) -> _ = ExprTup; let c: fn(_) -> _ = ExprKind::Tup;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_exprs(tup); self.hash_exprs(tup);
}, },
ExprType(ref e, ref _ty) => { ExprKind::Type(ref e, ref _ty) => {
let c: fn(_, _) -> _ = ExprType; let c: fn(_, _) -> _ = ExprKind::Type;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(e); self.hash_expr(e);
// TODO: _ty // TODO: _ty
}, },
ExprUnary(lop, ref le) => { ExprKind::Unary(lop, ref le) => {
let c: fn(_, _) -> _ = ExprUnary; let c: fn(_, _) -> _ = ExprKind::Unary;
c.hash(&mut self.s); c.hash(&mut self.s);
lop.hash(&mut self.s); lop.hash(&mut self.s);
self.hash_expr(le); self.hash_expr(le);
}, },
ExprArray(ref v) => { ExprKind::Array(ref v) => {
let c: fn(_) -> _ = ExprArray; let c: fn(_) -> _ = ExprKind::Array;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_exprs(v); self.hash_exprs(v);
}, },
ExprWhile(ref cond, ref b, l) => { ExprKind::While(ref cond, ref b, l) => {
let c: fn(_, _, _) -> _ = ExprWhile; let c: fn(_, _, _) -> _ = ExprKind::While;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(cond); self.hash_expr(cond);
@ -601,23 +613,23 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
pub fn hash_stmt(&mut self, b: &Stmt) { pub fn hash_stmt(&mut self, b: &Stmt) {
match b.node { match b.node {
StmtDecl(ref decl, _) => { StmtKind::Decl(ref decl, _) => {
let c: fn(_, _) -> _ = StmtDecl; let c: fn(_, _) -> _ = StmtKind::Decl;
c.hash(&mut self.s); c.hash(&mut self.s);
if let DeclLocal(ref local) = decl.node { if let DeclKind::Local(ref local) = decl.node {
if let Some(ref init) = local.init { if let Some(ref init) = local.init {
self.hash_expr(init); self.hash_expr(init);
} }
} }
}, },
StmtExpr(ref expr, _) => { StmtKind::Expr(ref expr, _) => {
let c: fn(_, _) -> _ = StmtExpr; let c: fn(_, _) -> _ = StmtKind::Expr;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(expr); self.hash_expr(expr);
}, },
StmtSemi(ref expr, _) => { StmtKind::Semi(ref expr, _) => {
let c: fn(_, _) -> _ = StmtSemi; let c: fn(_, _) -> _ = StmtKind::Semi;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_expr(expr); self.hash_expr(expr);
}, },

View File

@ -122,8 +122,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
return; return;
} }
match stmt.node { match stmt.node {
hir::StmtDecl(ref decl, _) => print_decl(cx, decl), hir::StmtKind::Decl(ref decl, _) => print_decl(cx, decl),
hir::StmtExpr(ref e, _) | hir::StmtSemi(ref e, _) => print_expr(cx, e, 0), hir::StmtKind::Expr(ref e, _) | hir::StmtKind::Semi(ref e, _) => print_expr(cx, e, 0),
} }
} }
// fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx // fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx
@ -141,7 +141,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::DeclKind::Local(ref local) => {
println!("local variable of type {}", cx.tables.node_id_to_type(local.hir_id)); println!("local variable of type {}", cx.tables.node_id_to_type(local.hir_id));
println!("pattern:"); println!("pattern:");
print_pat(cx, &local.pat, 0); print_pat(cx, &local.pat, 0);
@ -150,7 +150,7 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) {
print_expr(cx, e, 0); print_expr(cx, e, 0);
} }
}, },
hir::DeclItem(_) => println!("item decl"), hir::DeclKind::Item(_) => println!("item decl"),
} }
} }
@ -160,17 +160,17 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
println!("{}ty: {}", ind, cx.tables.expr_ty(expr)); println!("{}ty: {}", ind, cx.tables.expr_ty(expr));
println!("{}adjustments: {:?}", ind, cx.tables.adjustments().get(expr.hir_id)); println!("{}adjustments: {:?}", ind, cx.tables.adjustments().get(expr.hir_id));
match expr.node { match expr.node {
hir::ExprBox(ref e) => { hir::ExprKind::Box(ref e) => {
println!("{}Box", ind); println!("{}Box", ind);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
}, },
hir::ExprArray(ref v) => { hir::ExprKind::Array(ref v) => {
println!("{}Array", ind); println!("{}Array", ind);
for e in v { for e in v {
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
} }
}, },
hir::ExprCall(ref func, ref args) => { hir::ExprKind::Call(ref func, ref args) => {
println!("{}Call", ind); println!("{}Call", ind);
println!("{}function:", ind); println!("{}function:", ind);
print_expr(cx, func, indent + 1); print_expr(cx, func, indent + 1);
@ -179,20 +179,20 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
print_expr(cx, arg, indent + 1); print_expr(cx, arg, indent + 1);
} }
}, },
hir::ExprMethodCall(ref path, _, ref args) => { hir::ExprKind::MethodCall(ref path, _, ref args) => {
println!("{}MethodCall", ind); println!("{}MethodCall", ind);
println!("{}method name: {}", ind, path.ident.name); println!("{}method name: {}", ind, path.ident.name);
for arg in args { for arg in args {
print_expr(cx, arg, indent + 1); print_expr(cx, arg, indent + 1);
} }
}, },
hir::ExprTup(ref v) => { hir::ExprKind::Tup(ref v) => {
println!("{}Tup", ind); println!("{}Tup", ind);
for e in v { for e in v {
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
} }
}, },
hir::ExprBinary(op, ref lhs, ref rhs) => { hir::ExprKind::Binary(op, ref lhs, ref rhs) => {
println!("{}Binary", ind); println!("{}Binary", ind);
println!("{}op: {:?}", ind, op.node); println!("{}op: {:?}", ind, op.node);
println!("{}lhs:", ind); println!("{}lhs:", ind);
@ -200,26 +200,26 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
println!("{}rhs:", ind); println!("{}rhs:", ind);
print_expr(cx, rhs, indent + 1); print_expr(cx, rhs, indent + 1);
}, },
hir::ExprUnary(op, ref inner) => { hir::ExprKind::Unary(op, ref inner) => {
println!("{}Unary", ind); println!("{}Unary", ind);
println!("{}op: {:?}", ind, op); println!("{}op: {:?}", ind, op);
print_expr(cx, inner, indent + 1); print_expr(cx, inner, indent + 1);
}, },
hir::ExprLit(ref lit) => { hir::ExprKind::Lit(ref lit) => {
println!("{}Lit", ind); println!("{}Lit", ind);
println!("{}{:?}", ind, lit); println!("{}{:?}", ind, lit);
}, },
hir::ExprCast(ref e, ref target) => { hir::ExprKind::Cast(ref e, ref target) => {
println!("{}Cast", ind); println!("{}Cast", ind);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
println!("{}target type: {:?}", ind, target); println!("{}target type: {:?}", ind, target);
}, },
hir::ExprType(ref e, ref target) => { hir::ExprKind::Type(ref e, ref target) => {
println!("{}Type", ind); println!("{}Type", ind);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
println!("{}target type: {:?}", ind, target); println!("{}target type: {:?}", ind, target);
}, },
hir::ExprIf(ref e, _, ref els) => { hir::ExprKind::If(ref e, _, ref els) => {
println!("{}If", ind); println!("{}If", ind);
println!("{}condition:", ind); println!("{}condition:", ind);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
@ -228,39 +228,39 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
print_expr(cx, els, indent + 1); print_expr(cx, els, indent + 1);
} }
}, },
hir::ExprWhile(ref cond, _, _) => { hir::ExprKind::While(ref cond, _, _) => {
println!("{}While", ind); println!("{}While", ind);
println!("{}condition:", ind); println!("{}condition:", ind);
print_expr(cx, cond, indent + 1); print_expr(cx, cond, indent + 1);
}, },
hir::ExprLoop(..) => { hir::ExprKind::Loop(..) => {
println!("{}Loop", ind); println!("{}Loop", ind);
}, },
hir::ExprMatch(ref cond, _, ref source) => { hir::ExprKind::Match(ref cond, _, ref source) => {
println!("{}Match", ind); println!("{}Match", ind);
println!("{}condition:", ind); println!("{}condition:", ind);
print_expr(cx, cond, indent + 1); print_expr(cx, cond, indent + 1);
println!("{}source: {:?}", ind, source); println!("{}source: {:?}", ind, source);
}, },
hir::ExprClosure(ref clause, _, _, _, _) => { hir::ExprKind::Closure(ref clause, _, _, _, _) => {
println!("{}Closure", ind); println!("{}Closure", ind);
println!("{}clause: {:?}", ind, clause); println!("{}clause: {:?}", ind, clause);
}, },
hir::ExprYield(ref sub) => { hir::ExprKind::Yield(ref sub) => {
println!("{}Yield", ind); println!("{}Yield", ind);
print_expr(cx, sub, indent + 1); print_expr(cx, sub, indent + 1);
}, },
hir::ExprBlock(_, _) => { hir::ExprKind::Block(_, _) => {
println!("{}Block", ind); println!("{}Block", ind);
}, },
hir::ExprAssign(ref lhs, ref rhs) => { hir::ExprKind::Assign(ref lhs, ref rhs) => {
println!("{}Assign", ind); println!("{}Assign", ind);
println!("{}lhs:", ind); println!("{}lhs:", ind);
print_expr(cx, lhs, indent + 1); print_expr(cx, lhs, indent + 1);
println!("{}rhs:", ind); println!("{}rhs:", ind);
print_expr(cx, rhs, indent + 1); print_expr(cx, rhs, indent + 1);
}, },
hir::ExprAssignOp(ref binop, ref lhs, ref rhs) => { hir::ExprKind::AssignOp(ref binop, ref lhs, ref rhs) => {
println!("{}AssignOp", ind); println!("{}AssignOp", ind);
println!("{}op: {:?}", ind, binop.node); println!("{}op: {:?}", ind, binop.node);
println!("{}lhs:", ind); println!("{}lhs:", ind);
@ -268,46 +268,46 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
println!("{}rhs:", ind); println!("{}rhs:", ind);
print_expr(cx, rhs, indent + 1); print_expr(cx, rhs, indent + 1);
}, },
hir::ExprField(ref e, ident) => { hir::ExprKind::Field(ref e, ident) => {
println!("{}Field", ind); println!("{}Field", ind);
println!("{}field name: {}", ind, ident.name); println!("{}field name: {}", ind, ident.name);
println!("{}struct expr:", ind); println!("{}struct expr:", ind);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
}, },
hir::ExprIndex(ref arr, ref idx) => { hir::ExprKind::Index(ref arr, ref idx) => {
println!("{}Index", ind); println!("{}Index", ind);
println!("{}array expr:", ind); println!("{}array expr:", ind);
print_expr(cx, arr, indent + 1); print_expr(cx, arr, indent + 1);
println!("{}index expr:", ind); println!("{}index expr:", ind);
print_expr(cx, idx, indent + 1); print_expr(cx, idx, indent + 1);
}, },
hir::ExprPath(hir::QPath::Resolved(ref ty, ref path)) => { hir::ExprKind::Path(hir::QPath::Resolved(ref ty, ref path)) => {
println!("{}Resolved Path, {:?}", ind, ty); println!("{}Resolved Path, {:?}", ind, ty);
println!("{}path: {:?}", ind, path); println!("{}path: {:?}", ind, path);
}, },
hir::ExprPath(hir::QPath::TypeRelative(ref ty, ref seg)) => { hir::ExprKind::Path(hir::QPath::TypeRelative(ref ty, ref seg)) => {
println!("{}Relative Path, {:?}", ind, ty); println!("{}Relative Path, {:?}", ind, ty);
println!("{}seg: {:?}", ind, seg); println!("{}seg: {:?}", ind, seg);
}, },
hir::ExprAddrOf(ref muta, ref e) => { hir::ExprKind::AddrOf(ref muta, ref e) => {
println!("{}AddrOf", ind); println!("{}AddrOf", ind);
println!("mutability: {:?}", muta); println!("mutability: {:?}", muta);
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
}, },
hir::ExprBreak(_, ref e) => { hir::ExprKind::Break(_, ref e) => {
println!("{}Break", ind); println!("{}Break", ind);
if let Some(ref e) = *e { if let Some(ref e) = *e {
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
} }
}, },
hir::ExprContinue(_) => println!("{}Again", ind), hir::ExprKind::Continue(_) => println!("{}Again", ind),
hir::ExprRet(ref e) => { hir::ExprKind::Ret(ref e) => {
println!("{}Ret", ind); println!("{}Ret", ind);
if let Some(ref e) = *e { if let Some(ref e) = *e {
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
} }
}, },
hir::ExprInlineAsm(_, ref input, ref output) => { hir::ExprKind::InlineAsm(_, ref input, ref output) => {
println!("{}InlineAsm", ind); println!("{}InlineAsm", ind);
println!("{}inputs:", ind); println!("{}inputs:", ind);
for e in input { for e in input {
@ -318,7 +318,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
print_expr(cx, e, indent + 1); print_expr(cx, e, indent + 1);
} }
}, },
hir::ExprStruct(ref path, ref fields, ref base) => { hir::ExprKind::Struct(ref path, ref fields, ref base) => {
println!("{}Struct", ind); println!("{}Struct", ind);
println!("{}path: {:?}", ind, path); println!("{}path: {:?}", ind, path);
for field in fields { for field in fields {
@ -330,7 +330,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
print_expr(cx, base, indent + 1); print_expr(cx, base, indent + 1);
} }
}, },
hir::ExprRepeat(ref val, ref anon_const) => { hir::ExprKind::Repeat(ref val, ref anon_const) => {
println!("{}Repeat", ind); println!("{}Repeat", ind);
println!("{}value:", ind); println!("{}value:", ind);
print_expr(cx, val, indent + 1); print_expr(cx, val, indent + 1);
@ -353,7 +353,7 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"),
} }
match item.node { match item.node {
hir::ItemExternCrate(ref _renamed_from) => { hir::ItemKind::ExternCrate(ref _renamed_from) => {
let def_id = cx.tcx.hir.local_def_id(item.id); let def_id = cx.tcx.hir.local_def_id(item.id);
if let Some(crate_id) = cx.tcx.extern_mod_stmt_cnum(def_id) { if let Some(crate_id) = cx.tcx.extern_mod_stmt_cnum(def_id) {
let source = cx.tcx.used_crate_source(crate_id); let source = cx.tcx.used_crate_source(crate_id);
@ -367,32 +367,32 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
println!("weird extern crate without a crate id"); println!("weird extern crate without a crate id");
} }
}, },
hir::ItemUse(ref path, ref kind) => println!("{:?}, {:?}", path, kind), hir::ItemKind::Use(ref path, ref kind) => println!("{:?}, {:?}", path, kind),
hir::ItemStatic(..) => println!("static item of type {:#?}", cx.tcx.type_of(did)), hir::ItemKind::Static(..) => println!("static item of type {:#?}", cx.tcx.type_of(did)),
hir::ItemConst(..) => println!("const item of type {:#?}", cx.tcx.type_of(did)), hir::ItemKind::Const(..) => println!("const item of type {:#?}", cx.tcx.type_of(did)),
hir::ItemFn(..) => { hir::ItemKind::Fn(..) => {
let item_ty = cx.tcx.type_of(did); let item_ty = cx.tcx.type_of(did);
println!("function of type {:#?}", item_ty); println!("function of type {:#?}", item_ty);
}, },
hir::ItemMod(..) => println!("module"), hir::ItemKind::Mod(..) => println!("module"),
hir::ItemForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi), hir::ItemKind::ForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi),
hir::ItemGlobalAsm(ref asm) => println!("global asm: {:?}", asm), hir::ItemKind::GlobalAsm(ref asm) => println!("global asm: {:?}", asm),
hir::ItemTy(..) => { hir::ItemKind::Ty(..) => {
println!("type alias for {:?}", cx.tcx.type_of(did)); println!("type alias for {:?}", cx.tcx.type_of(did));
}, },
hir::ItemExistential(..) => { hir::ItemKind::Existential(..) => {
println!("existential type with real type {:?}", cx.tcx.type_of(did)); println!("existential type with real type {:?}", cx.tcx.type_of(did));
}, },
hir::ItemEnum(..) => { hir::ItemKind::Enum(..) => {
println!("enum definition of type {:?}", cx.tcx.type_of(did)); println!("enum definition of type {:?}", cx.tcx.type_of(did));
}, },
hir::ItemStruct(..) => { hir::ItemKind::Struct(..) => {
println!("struct definition of type {:?}", cx.tcx.type_of(did)); println!("struct definition of type {:?}", cx.tcx.type_of(did));
}, },
hir::ItemUnion(..) => { hir::ItemKind::Union(..) => {
println!("union definition of type {:?}", cx.tcx.type_of(did)); println!("union definition of type {:?}", cx.tcx.type_of(did));
}, },
hir::ItemTrait(..) => { hir::ItemKind::Trait(..) => {
println!("trait decl"); println!("trait decl");
if cx.tcx.trait_is_auto(did) { if cx.tcx.trait_is_auto(did) {
println!("trait is auto"); println!("trait is auto");
@ -400,13 +400,13 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
println!("trait is not auto"); println!("trait is not auto");
} }
}, },
hir::ItemTraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
println!("trait alias"); println!("trait alias");
} }
hir::ItemImpl(_, _, _, _, Some(ref _trait_ref), _, _) => { hir::ItemKind::Impl(_, _, _, _, Some(ref _trait_ref), _, _) => {
println!("trait impl"); println!("trait impl");
}, },
hir::ItemImpl(_, _, _, _, None, _, _) => { hir::ItemKind::Impl(_, _, _, _, None, _, _) => {
println!("impl"); println!("impl");
}, },
} }

View File

@ -1,5 +1,6 @@
use rustc::lint::*; use rustc::lint::*;
use rustc::hir::*; use rustc::hir::*;
use rustc::hir;
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
use crate::utils::{match_qpath, paths, span_lint}; use crate::utils::{match_qpath, paths, span_lint};
use syntax::symbol::LocalInternedString; use syntax::symbol::LocalInternedString;
@ -117,7 +118,7 @@ impl LintPass for LintWithoutLintPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
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 let ItemStatic(ref ty, MutImmutable, body_id) = item.node { if let hir::ItemKind::Static(ref ty, MutImmutable, body_id) = item.node {
if is_lint_ref_type(ty) { if is_lint_ref_type(ty) {
self.declared_lints.insert(item.name, item.span); self.declared_lints.insert(item.name, item.span);
} else if is_lint_array_type(ty) && item.name == "ARRAY" { } else if is_lint_array_type(ty) && item.name == "ARRAY" {
@ -162,7 +163,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
fn is_lint_ref_type(ty: &Ty) -> bool { fn is_lint_ref_type(ty: &Ty) -> bool {
if let TyRptr( if let TyKind::Rptr(
_, _,
MutTy { MutTy {
ty: ref inner, ty: ref inner,
@ -170,7 +171,7 @@ fn is_lint_ref_type(ty: &Ty) -> bool {
}, },
) = ty.node ) = ty.node
{ {
if let TyPath(ref path) = inner.node { if let TyKind::Path(ref path) = inner.node {
return match_qpath(path, &paths::LINT); return match_qpath(path, &paths::LINT);
} }
} }
@ -179,7 +180,7 @@ fn is_lint_ref_type(ty: &Ty) -> bool {
fn is_lint_array_type(ty: &Ty) -> bool { fn is_lint_array_type(ty: &Ty) -> bool {
if let TyPath(ref path) = ty.node { if let TyKind::Path(ref path) = ty.node {
match_qpath(path, &paths::LINT_ARRAY) match_qpath(path, &paths::LINT_ARRAY)
} else { } else {
false false

View File

@ -174,7 +174,7 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool
/// Check if an expression references a variable of the given name. /// Check if an expression references a variable of the given name.
pub fn match_var(expr: &Expr, var: Name) -> bool { pub fn match_var(expr: &Expr, var: Name) -> bool {
if let ExprPath(QPath::Resolved(None, ref path)) = expr.node { if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.node {
if path.segments.len() == 1 && path.segments[0].ident.name == var { if path.segments.len() == 1 && path.segments[0].ident.name == var {
return true; return true;
} }
@ -210,7 +210,7 @@ pub fn match_qpath(path: &QPath, segments: &[&str]) -> bool {
match *path { match *path {
QPath::Resolved(_, ref path) => match_path(path, segments), QPath::Resolved(_, ref path) => match_path(path, segments),
QPath::TypeRelative(ref ty, ref segment) => match ty.node { QPath::TypeRelative(ref ty, ref segment) => match ty.node {
TyPath(ref inner_path) => { TyKind::Path(ref inner_path) => {
!segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)]) !segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)])
&& segment.ident.name == segments[segments.len() - 1] && segment.ident.name == segments[segments.len() - 1]
}, },
@ -330,7 +330,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a
let mut matched = Vec::with_capacity(methods.len()); let mut matched = Vec::with_capacity(methods.len());
for method_name in methods.iter().rev() { for method_name in methods.iter().rev() {
// method chains are stored last -> first // method chains are stored last -> first
if let ExprMethodCall(ref path, _, ref args) = current.node { if let ExprKind::MethodCall(ref path, _, ref args) = current.node {
if path.ident.name == *method_name { if path.ident.name == *method_name {
if args.iter().any(|e| in_macro(e.span)) { if args.iter().any(|e| in_macro(e.span)) {
return None; return None;
@ -435,7 +435,7 @@ pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span {
Span::new(*line_start, span.hi(), span.ctxt()) Span::new(*line_start, span.hi(), span.ctxt())
} }
/// Like `snippet_block`, but add braces if the expr is not an `ExprBlock`. /// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
/// Also takes an `Option<String>` which can be put inside the braces. /// Also takes an `Option<String>` which can be put inside the braces.
pub fn expr_block<'a, 'b, T: LintContext<'b>>( pub fn expr_block<'a, 'b, T: LintContext<'b>>(
cx: &T, cx: &T,
@ -445,7 +445,7 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>(
) -> Cow<'a, str> { ) -> Cow<'a, str> {
let code = snippet_block(cx, expr.span, default); let code = snippet_block(cx, expr.span, default);
let string = option.unwrap_or_default(); let string = option.unwrap_or_default();
if let ExprBlock(_, _) = expr.node { if let ExprKind::Block(_, _) = expr.node {
Cow::Owned(format!("{}{}", code, string)) Cow::Owned(format!("{}{}", code, string))
} else if string.is_empty() { } else if string.is_empty() {
Cow::Owned(format!("{{ {} }}", code)) Cow::Owned(format!("{{ {} }}", code))
@ -524,13 +524,13 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI
match node { match node {
Node::NodeBlock(block) => Some(block), Node::NodeBlock(block) => Some(block),
Node::NodeItem(&Item { Node::NodeItem(&Item {
node: ItemFn(_, _, _, eid), node: ItemKind::Fn(_, _, _, eid),
.. ..
}) | Node::NodeImplItem(&ImplItem { }) | Node::NodeImplItem(&ImplItem {
node: ImplItemKind::Method(_, eid), node: ImplItemKind::Method(_, eid),
.. ..
}) => match cx.tcx.hir.body(eid).value.node { }) => match cx.tcx.hir.body(eid).value.node {
ExprBlock(ref block, _) => Some(block), ExprKind::Block(ref block, _) => Some(block),
_ => None, _ => None,
}, },
_ => None, _ => None,
@ -667,7 +667,7 @@ where
/// Return the base type for HIR references and pointers. /// Return the base type for HIR references and pointers.
pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty { pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
match ty.node { match ty.node {
TyPtr(ref mut_ty) | TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty), TyKind::Ptr(ref mut_ty) | TyKind::Rptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
_ => ty, _ => ty,
} }
} }
@ -695,7 +695,7 @@ pub fn walk_ptrs_ty_depth(ty: Ty) -> (Ty, usize) {
/// Check whether the given expression is a constant literal of the given value. /// Check whether the given expression is a constant literal of the given value.
pub fn is_integer_literal(expr: &Expr, value: u128) -> bool { pub fn is_integer_literal(expr: &Expr, value: u128) -> bool {
// FIXME: use constant folding // FIXME: use constant folding
if let ExprLit(ref spanned) = expr.node { if let ExprKind::Lit(ref spanned) = expr.node {
if let LitKind::Int(v, _) = spanned.node { if let LitKind::Int(v, _) = spanned.node {
return v == value; return v == value;
} }
@ -945,7 +945,7 @@ pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return /// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return
/// themselves. /// themselves.
pub fn remove_blocks(expr: &Expr) -> &Expr { pub fn remove_blocks(expr: &Expr) -> &Expr {
if let ExprBlock(ref block, _) = expr.node { if let ExprKind::Block(ref block, _) = expr.node {
if block.stmts.is_empty() { if block.stmts.is_empty() {
if let Some(ref expr) = block.expr { if let Some(ref expr) = block.expr {
remove_blocks(expr) remove_blocks(expr)
@ -998,7 +998,7 @@ pub fn is_self(slf: &Arg) -> bool {
pub fn is_self_ty(slf: &hir::Ty) -> bool { pub fn is_self_ty(slf: &hir::Ty) -> bool {
if_chain! { if_chain! {
if let TyPath(ref qp) = slf.node; if let TyKind::Path(ref qp) = slf.node;
if let QPath::Resolved(None, ref path) = *qp; if let QPath::Resolved(None, ref path) = *qp;
if let Def::SelfTy(..) = path.def; if let Def::SelfTy(..) = path.def;
then { then {
@ -1020,7 +1020,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pats[0].node; if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pats[0].node;
if match_qpath(path, &paths::RESULT_OK[1..]); if match_qpath(path, &paths::RESULT_OK[1..]);
if let PatKind::Binding(_, defid, _, None) = pat[0].node; if let PatKind::Binding(_, defid, _, None) = pat[0].node;
if let ExprPath(QPath::Resolved(None, ref path)) = arm.body.node; if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.node;
if let Def::Local(lid) = path.def; if let Def::Local(lid) = path.def;
if lid == defid; if lid == defid;
then { then {
@ -1038,7 +1038,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
} }
} }
if let ExprMatch(_, ref arms, ref source) = expr.node { if let ExprKind::Match(_, ref arms, ref source) = expr.node {
// desugared from a `?` operator // desugared from a `?` operator
if let MatchSource::TryDesugar = *source { if let MatchSource::TryDesugar = *source {
return Some(expr); return Some(expr);

View File

@ -54,7 +54,7 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
if self.abort { if self.abort {
return; return;
} }
if let ExprMethodCall(ref seg, _, ref args) = expr.node { if let ExprKind::MethodCall(ref seg, _, ref args) = expr.node {
if args.len() == 1 && match_var(&args[0], self.name) { if args.len() == 1 && match_var(&args[0], self.name) {
if seg.ident.name == "capacity" { if seg.ident.name == "capacity" {
self.abort = true; self.abort = true;

View File

@ -46,35 +46,35 @@ impl<'a> Sugg<'a> {
snippet_opt(cx, expr.span).map(|snippet| { snippet_opt(cx, expr.span).map(|snippet| {
let snippet = Cow::Owned(snippet); let snippet = Cow::Owned(snippet);
match expr.node { match expr.node {
hir::ExprAddrOf(..) | hir::ExprKind::AddrOf(..) |
hir::ExprBox(..) | hir::ExprKind::Box(..) |
hir::ExprClosure(.., _) | hir::ExprKind::Closure(.., _) |
hir::ExprIf(..) | hir::ExprKind::If(..) |
hir::ExprUnary(..) | hir::ExprKind::Unary(..) |
hir::ExprMatch(..) => Sugg::MaybeParen(snippet), hir::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
hir::ExprContinue(..) | hir::ExprKind::Continue(..) |
hir::ExprYield(..) | hir::ExprKind::Yield(..) |
hir::ExprArray(..) | hir::ExprKind::Array(..) |
hir::ExprBlock(..) | hir::ExprKind::Block(..) |
hir::ExprBreak(..) | hir::ExprKind::Break(..) |
hir::ExprCall(..) | hir::ExprKind::Call(..) |
hir::ExprField(..) | hir::ExprKind::Field(..) |
hir::ExprIndex(..) | hir::ExprKind::Index(..) |
hir::ExprInlineAsm(..) | hir::ExprKind::InlineAsm(..) |
hir::ExprLit(..) | hir::ExprKind::Lit(..) |
hir::ExprLoop(..) | hir::ExprKind::Loop(..) |
hir::ExprMethodCall(..) | hir::ExprKind::MethodCall(..) |
hir::ExprPath(..) | hir::ExprKind::Path(..) |
hir::ExprRepeat(..) | hir::ExprKind::Repeat(..) |
hir::ExprRet(..) | hir::ExprKind::Ret(..) |
hir::ExprStruct(..) | hir::ExprKind::Struct(..) |
hir::ExprTup(..) | hir::ExprKind::Tup(..) |
hir::ExprWhile(..) => Sugg::NonParen(snippet), hir::ExprKind::While(..) => Sugg::NonParen(snippet),
hir::ExprAssign(..) => Sugg::BinOp(AssocOp::Assign, snippet), hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
hir::ExprAssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet), hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),
hir::ExprBinary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet), hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet),
hir::ExprCast(..) => Sugg::BinOp(AssocOp::As, snippet), hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
hir::ExprType(..) => Sugg::BinOp(AssocOp::Colon, snippet), hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
} }
}) })
} }
@ -382,21 +382,29 @@ fn associativity(op: &AssocOp) -> Associativity {
/// Convert a `hir::BinOp` to the corresponding assigning binary operator. /// Convert a `hir::BinOp` to the corresponding assigning binary operator.
fn hirbinop2assignop(op: hir::BinOp) -> AssocOp { fn hirbinop2assignop(op: hir::BinOp) -> AssocOp {
use rustc::hir::BinOp_::*;
use syntax::parse::token::BinOpToken::*; use syntax::parse::token::BinOpToken::*;
AssocOp::AssignOp(match op.node { AssocOp::AssignOp(match op.node {
BiAdd => Plus, hir::BinOpKind::Add => Plus,
BiBitAnd => And, hir::BinOpKind::BitAnd => And,
BiBitOr => Or, hir::BinOpKind::BitOr => Or,
BiBitXor => Caret, hir::BinOpKind::BitXor => Caret,
BiDiv => Slash, hir::BinOpKind::Div => Slash,
BiMul => Star, hir::BinOpKind::Mul => Star,
BiRem => Percent, hir::BinOpKind::Rem => Percent,
BiShl => Shl, hir::BinOpKind::Shl => Shl,
BiShr => Shr, hir::BinOpKind::Shr => Shr,
BiSub => Minus, hir::BinOpKind::Sub => Minus,
BiAnd | BiEq | BiGe | BiGt | BiLe | BiLt | BiNe | BiOr => panic!("This operator does not exist"),
| hir::BinOpKind::And
| hir::BinOpKind::Eq
| hir::BinOpKind::Ge
| hir::BinOpKind::Gt
| hir::BinOpKind::Le
| hir::BinOpKind::Lt
| hir::BinOpKind::Ne
| hir::BinOpKind::Or
=> panic!("This operator does not exist"),
}) })
} }

View File

@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if_chain! { if_chain! {
if let ty::TyRef(_, ty, _) = cx.tables.expr_ty_adjusted(expr).sty; if let ty::TyRef(_, ty, _) = cx.tables.expr_ty_adjusted(expr).sty;
if let ty::TySlice(..) = ty.sty; if let ty::TySlice(..) = ty.sty;
if let ExprAddrOf(_, ref addressee) = expr.node; if let ExprKind::AddrOf(_, ref addressee) = expr.node;
if let Some(vec_args) = higher::vec_macro(cx, addressee); if let Some(vec_args) = higher::vec_macro(cx, addressee);
then { then {
check_vec_macro(cx, &vec_args, expr.span); check_vec_macro(cx, &vec_args, expr.span);

View File

@ -175,9 +175,9 @@ 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) {
match expr.node { match expr.node {
// print!() // print!()
ExprCall(ref fun, ref args) => { ExprKind::Call(ref fun, ref args) => {
if_chain! { if_chain! {
if let ExprPath(ref qpath) = fun.node; if let ExprKind::Path(ref qpath) = fun.node;
if let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)); if let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
then { then {
check_print_variants(cx, expr, fun_id, args); check_print_variants(cx, expr, fun_id, args);
@ -185,7 +185,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
}, },
// write!() // write!()
ExprMethodCall(ref fun, _, ref args) => { ExprKind::MethodCall(ref fun, _, ref args) => {
if fun.ident.name == "write_fmt" { if fun.ident.name == "write_fmt" {
check_write_variants(cx, expr, args); check_write_variants(cx, expr, args);
} }
@ -206,8 +206,8 @@ fn check_write_variants<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
if_chain! { if_chain! {
// ensure we're calling Arguments::new_v1 or Arguments::new_v1_formatted // ensure we're calling Arguments::new_v1 or Arguments::new_v1_formatted
if write_args.len() == 2; if write_args.len() == 2;
if let ExprCall(ref args_fun, ref args_args) = write_args[1].node; if let ExprKind::Call(ref args_fun, ref args_args) = write_args[1].node;
if let ExprPath(ref qpath) = args_fun.node; if let ExprKind::Path(ref qpath) = args_fun.node;
if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id));
if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1) || if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1) ||
match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED); match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED);
@ -219,9 +219,9 @@ fn check_write_variants<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
if_chain! { if_chain! {
if args_args.len() >= 2; if args_args.len() >= 2;
if let ExprAddrOf(_, ref match_expr) = args_args[1].node; if let ExprKind::AddrOf(_, ref match_expr) = args_args[1].node;
if let ExprMatch(ref args, _, _) = match_expr.node; if let ExprKind::Match(ref args, _, _) = match_expr.node;
if let ExprTup(ref args) = args.node; if let ExprKind::Tup(ref args) = args.node;
if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]);
then { then {
match name { match name {
@ -269,7 +269,7 @@ fn check_print_variants<'a, 'tcx>(
if_chain! { if_chain! {
// ensure we're calling Arguments::new_v1 // ensure we're calling Arguments::new_v1
if args.len() == 1; if args.len() == 1;
if let ExprCall(ref args_fun, ref args_args) = args[0].node; if let ExprKind::Call(ref args_fun, ref args_args) = args[0].node;
then { then {
// Check for literals in the print!/println! args // Check for literals in the print!/println! args
check_fmt_args_for_literal(cx, args_args, |span| { check_fmt_args_for_literal(cx, args_args, |span| {
@ -277,13 +277,13 @@ fn check_print_variants<'a, 'tcx>(
}); });
if_chain! { if_chain! {
if let ExprPath(ref qpath) = args_fun.node; if let ExprKind::Path(ref qpath) = args_fun.node;
if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id));
if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1); if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1);
if args_args.len() == 2; if args_args.len() == 2;
if let ExprAddrOf(_, ref match_expr) = args_args[1].node; if let ExprKind::AddrOf(_, ref match_expr) = args_args[1].node;
if let ExprMatch(ref args, _, _) = match_expr.node; if let ExprKind::Match(ref args, _, _) = match_expr.node;
if let ExprTup(ref args) = args.node; if let ExprKind::Tup(ref args) = args.node;
if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]);
then { then {
match name { match name {
@ -315,7 +315,7 @@ fn check_print_variants<'a, 'tcx>(
// 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.tcx, 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 ExprKind::Path(ref qpath) = args[1].node {
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, args[1].hir_id)) { if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, args[1].hir_id)) {
if match_def_path(cx.tcx, 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(expr.span, "panic").is_none() && is_expn_of(expr.span, "panic").is_none()
@ -341,25 +341,25 @@ where
if args.len() >= 2; if args.len() >= 2;
// the match statement // the match statement
if let ExprAddrOf(_, ref match_expr) = args[1].node; if let ExprKind::AddrOf(_, ref match_expr) = args[1].node;
if let ExprMatch(ref matchee, ref arms, _) = match_expr.node; if let ExprKind::Match(ref matchee, ref arms, _) = match_expr.node;
if let ExprTup(ref tup) = matchee.node; if let ExprKind::Tup(ref tup) = matchee.node;
if arms.len() == 1; if arms.len() == 1;
if let ExprArray(ref arm_body_exprs) = arms[0].body.node; if let ExprKind::Array(ref arm_body_exprs) = arms[0].body.node;
then { then {
// it doesn't matter how many args there are in the `write!`/`writeln!`, // it doesn't matter how many args there are in the `write!`/`writeln!`,
// if there's one literal, we should warn the user // if there's one literal, we should warn the user
for (idx, tup_arg) in tup.iter().enumerate() { for (idx, tup_arg) in tup.iter().enumerate() {
if_chain! { if_chain! {
// first, make sure we're dealing with a literal (i.e., an ExprLit) // first, make sure we're dealing with a literal (i.e., an ExprKind::Lit)
if let ExprAddrOf(_, ref tup_val) = tup_arg.node; if let ExprKind::AddrOf(_, ref tup_val) = tup_arg.node;
if let ExprLit(_) = tup_val.node; if let ExprKind::Lit(_) = tup_val.node;
// next, check the corresponding match arm body to ensure // next, check the corresponding match arm body to ensure
// this is DISPLAY_FMT_METHOD // this is DISPLAY_FMT_METHOD
if let ExprCall(_, ref body_args) = arm_body_exprs[idx].node; if let ExprKind::Call(_, ref body_args) = arm_body_exprs[idx].node;
if body_args.len() == 2; if body_args.len() == 2;
if let ExprPath(ref body_qpath) = body_args[1].node; if let ExprKind::Path(ref body_qpath) = body_args[1].node;
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, body_qpath, body_args[1].hir_id)); if let Some(fun_def_id) = opt_def_id(resolve_node(cx, body_qpath, body_args[1].hir_id));
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD); if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
then { then {
@ -371,10 +371,10 @@ where
// and is just "{}" // and is just "{}"
if_chain! { if_chain! {
if args.len() == 3; if args.len() == 3;
if let ExprAddrOf(_, ref format_expr) = args[2].node; if let ExprKind::AddrOf(_, ref format_expr) = args[2].node;
if let ExprArray(ref format_exprs) = format_expr.node; if let ExprKind::Array(ref format_exprs) = format_expr.node;
if format_exprs.len() >= 1; if format_exprs.len() >= 1;
if let ExprStruct(_, ref fields, _) = format_exprs[idx].node; if let ExprKind::Struct(_, ref fields, _) = format_exprs[idx].node;
if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format"); if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format");
if check_unformatted(&format_field.expr); if check_unformatted(&format_field.expr);
then { then {
@ -429,10 +429,10 @@ fn has_empty_arg<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, fmtstr: Local
/// Returns the slice of format string parts in an `Arguments::new_v1` call. /// Returns the slice of format string parts in an `Arguments::new_v1` call.
fn get_argument_fmtstr_parts(expr: &Expr) -> Option<(LocalInternedString, usize)> { fn get_argument_fmtstr_parts(expr: &Expr) -> Option<(LocalInternedString, usize)> {
if_chain! { if_chain! {
if let ExprAddrOf(_, ref expr) = expr.node; // &["…", "…", …] if let ExprKind::AddrOf(_, ref expr) = expr.node; // &["…", "…", …]
if let ExprArray(ref exprs) = expr.node; if let ExprKind::Array(ref exprs) = expr.node;
if let Some(expr) = exprs.last(); if let Some(expr) = exprs.last();
if let ExprLit(ref lit) = expr.node; if let ExprKind::Lit(ref lit) = expr.node;
if let LitKind::Str(ref lit, _) = lit.node; if let LitKind::Str(ref lit, _) = lit.node;
then { then {
return Some((lit.as_str(), exprs.len())); return Some((lit.as_str(), exprs.len()));
@ -448,7 +448,7 @@ fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool {
if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) { if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) {
// `Debug` impl // `Debug` impl
if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) { if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) {
if let ItemImpl(_, _, _, _, Some(ref tr), _, _) = item.node { if let ItemKind::Impl(_, _, _, _, Some(ref tr), _, _) = item.node {
return match_path(&tr.path, &["Debug"]); return match_path(&tr.path, &["Debug"]);
} }
} }
@ -468,15 +468,15 @@ fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool {
/// ``` /// ```
pub fn check_unformatted(format_field: &Expr) -> bool { pub fn check_unformatted(format_field: &Expr) -> bool {
if_chain! { if_chain! {
if let ExprStruct(_, ref fields, _) = format_field.node; if let ExprKind::Struct(_, ref fields, _) = format_field.node;
if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width"); if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width");
if let ExprPath(ref qpath) = width_field.expr.node; if let ExprKind::Path(ref qpath) = width_field.expr.node;
if last_path_segment(qpath).ident.name == "Implied"; if last_path_segment(qpath).ident.name == "Implied";
if let Some(align_field) = fields.iter().find(|f| f.ident.name == "align"); if let Some(align_field) = fields.iter().find(|f| f.ident.name == "align");
if let ExprPath(ref qpath) = align_field.expr.node; if let ExprKind::Path(ref qpath) = align_field.expr.node;
if last_path_segment(qpath).ident.name == "Unknown"; if last_path_segment(qpath).ident.name == "Unknown";
if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision"); if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision");
if let ExprPath(ref qpath_precision) = precision_field.expr.node; if let ExprKind::Path(ref qpath_precision) = precision_field.expr.node;
if last_path_segment(qpath_precision).ident.name == "Implied"; if last_path_segment(qpath_precision).ident.name == "Implied";
then { then {
return true; return true;

Some files were not shown because too many files have changed in this diff Show More