mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Merge pull request #2923 from rust-lang-nursery/kind
Rustup to 1ecf6929dc
This commit is contained in:
commit
f27aaacb9b
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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, "^"),
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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");
|
||||||
|
@ -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 = ¶ms[0];
|
let map = ¶ms[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, ¶ms[0]);
|
if get_item_name(self.cx, self.map) == get_item_name(self.cx, ¶ms[0]);
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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"]) {
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
},
|
},
|
||||||
|
@ -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 => {
|
||||||
|
@ -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[..]
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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()));
|
||||||
|
@ -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));
|
||||||
|
@ -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");
|
||||||
|
@ -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" {
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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]);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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(..) => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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() {
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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),
|
||||||
..
|
..
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
@ -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("}}", "");
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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: ®ex_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 };
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
|
@ -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 {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -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()
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
},
|
},
|
||||||
|
@ -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");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user