mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 13:13:34 +00:00
Merge branch 'master' into issue2894
This commit is contained in:
commit
847e4dcc0d
114 changed files with 1423 additions and 1347 deletions
|
@ -93,9 +93,9 @@ a `.stdout` file with the generated code:
|
|||
// ./tests/ui/my_lint.stdout
|
||||
|
||||
if_chain! {
|
||||
if let Expr_::ExprArray(ref elements) = stmt.node;
|
||||
if let ExprKind::Array(ref elements) = stmt.node;
|
||||
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;
|
||||
then {
|
||||
// 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].
|
||||
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.
|
||||
|
||||
```rust
|
||||
|
|
52
README.md
52
README.md
|
@ -35,43 +35,45 @@ Table of contents:
|
|||
Since this is a tool for helping the developer of a library or application
|
||||
write better code, it is recommended not to include Clippy as a hard dependency.
|
||||
Options include using it as an optional dependency, as a cargo subcommand, or
|
||||
as an included feature during build. All of these options are detailed below.
|
||||
as an included feature during build. These options are detailed below.
|
||||
|
||||
As a general rule Clippy will only work with the *latest* Rust nightly for now.
|
||||
### As a cargo subcommand (`cargo clippy`)
|
||||
|
||||
To install Rust nightly, the recommended way is to use [rustup](https://rustup.rs/):
|
||||
One way to use Clippy is by installing Clippy through rustup as a cargo
|
||||
subcommand.
|
||||
|
||||
#### Step 1: Install rustup
|
||||
|
||||
You can install [rustup](http://rustup.rs/) on supported platforms. This will help
|
||||
us install clippy and its dependencies.
|
||||
|
||||
If you already have rustup installed, update to ensure you have the latest
|
||||
rustup and compiler:
|
||||
|
||||
```terminal
|
||||
rustup update
|
||||
```
|
||||
|
||||
#### Step 2: Install nightly toolchain
|
||||
|
||||
Rustup integration is still new, you will need a relatively new nightly (2018-07-15 or later).
|
||||
|
||||
To install Rust nightly with [rustup](https://rustup.rs/):
|
||||
|
||||
```terminal
|
||||
rustup install nightly
|
||||
```
|
||||
|
||||
### As a cargo subcommand (`cargo clippy`)
|
||||
#### Step 3: Install clippy
|
||||
|
||||
One way to use Clippy is by installing Clippy through cargo as a cargo
|
||||
subcommand.
|
||||
Once you have rustup and the nightly toolchain installed, run the following command:
|
||||
|
||||
```terminal
|
||||
cargo +nightly install clippy
|
||||
rustup component add clippy-preview --toolchain=nightly
|
||||
```
|
||||
|
||||
(The `+nightly` is not necessary if your default `rustup` install is nightly)
|
||||
|
||||
Now you can run Clippy by invoking `cargo +nightly clippy`.
|
||||
|
||||
To update the subcommand together with the latest nightly use the [rust-update](rust-update) script or run:
|
||||
|
||||
```terminal
|
||||
rustup update nightly
|
||||
cargo +nightly install --force clippy
|
||||
```
|
||||
|
||||
In case you are not using rustup, you need to set the environment flag
|
||||
`SYSROOT` during installation so Clippy knows where to find `librustc` and
|
||||
similar crates.
|
||||
|
||||
```terminal
|
||||
SYSROOT=/path/to/rustc/sysroot cargo install clippy
|
||||
```
|
||||
Now you can run Clippy by invoking `cargo +nightly clippy`. If nightly is your
|
||||
default toolchain in rustup, `cargo clippy` will work fine.
|
||||
|
||||
### Running Clippy from the command line without installing it
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ cargo test --features debugging
|
|||
mkdir -p ~/rust/cargo/bin
|
||||
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
|
||||
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
|
||||
rm ~/.cargo/bin/cargo-clippy
|
||||
PATH=$PATH:~/rust/cargo/bin cargo clippy --all -- -D clippy
|
||||
cd clippy_workspace_tests && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ..
|
||||
cd clippy_workspace_tests/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ../..
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
set -x
|
||||
rm ~/.cargo/bin/cargo-clippy
|
||||
cargo install --force --path .
|
||||
|
||||
echo "Running integration test for crate ${INTEGRATION}"
|
||||
|
|
|
@ -63,7 +63,7 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,21 +55,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
|
|||
return;
|
||||
}
|
||||
match expr.node {
|
||||
hir::ExprBinary(ref op, ref l, ref r) => {
|
||||
hir::ExprKind::Binary(ref op, ref l, ref r) => {
|
||||
match op.node {
|
||||
hir::BiAnd
|
||||
| hir::BiOr
|
||||
| hir::BiBitAnd
|
||||
| hir::BiBitOr
|
||||
| hir::BiBitXor
|
||||
| hir::BiShl
|
||||
| hir::BiShr
|
||||
| hir::BiEq
|
||||
| hir::BiLt
|
||||
| hir::BiLe
|
||||
| hir::BiNe
|
||||
| hir::BiGe
|
||||
| hir::BiGt => return,
|
||||
hir::BinOpKind::And
|
||||
| hir::BinOpKind::Or
|
||||
| hir::BinOpKind::BitAnd
|
||||
| hir::BinOpKind::BitOr
|
||||
| hir::BinOpKind::BitXor
|
||||
| hir::BinOpKind::Shl
|
||||
| hir::BinOpKind::Shr
|
||||
| hir::BinOpKind::Eq
|
||||
| hir::BinOpKind::Lt
|
||||
| hir::BinOpKind::Le
|
||||
| hir::BinOpKind::Ne
|
||||
| hir::BinOpKind::Ge
|
||||
| hir::BinOpKind::Gt => return,
|
||||
_ => (),
|
||||
}
|
||||
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);
|
||||
}
|
||||
},
|
||||
hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
|
||||
hir::ExprKind::Unary(hir::UnOp::UnNeg, ref arg) => {
|
||||
let ty = cx.tables.expr_ty(arg);
|
||||
if ty.is_integral() {
|
||||
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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
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| {
|
||||
let lhs = &sugg::Sugg::hir(cx, lhs, "..");
|
||||
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)),
|
||||
);
|
||||
});
|
||||
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 {
|
||||
let lint = |assignee: &hir::Expr, rhs_other: &hir::Expr| {
|
||||
span_lint_and_then(
|
||||
|
@ -131,8 +131,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
}
|
||||
}
|
||||
},
|
||||
hir::ExprAssign(ref assignee, ref e) => {
|
||||
if let hir::ExprBinary(op, ref l, ref r) = e.node {
|
||||
hir::ExprKind::Assign(ref assignee, ref e) => {
|
||||
if let hir::ExprKind::Binary(op, ref l, ref r) = e.node {
|
||||
#[allow(cyclomatic_complexity)]
|
||||
let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
|
||||
let ty = cx.tables.expr_ty(assignee);
|
||||
|
@ -142,9 +142,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
$cx:expr,
|
||||
$ty:expr,
|
||||
$rty:expr,
|
||||
$($trait_name:ident:$full_trait_name:ident),+) => {
|
||||
$($trait_name:ident),+) => {
|
||||
match $op {
|
||||
$(hir::$full_trait_name => {
|
||||
$(hir::BinOpKind::$trait_name => {
|
||||
let [krate, module] = crate::utils::paths::OPS_MODULE;
|
||||
let path = [krate, module, concat!(stringify!($trait_name), "Assign")];
|
||||
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 parent_impl != ast::CRATE_NODE_ID;
|
||||
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;
|
||||
if trait_ref.path.def.def_id() == trait_id;
|
||||
then { return; }
|
||||
|
@ -175,18 +175,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
cx,
|
||||
ty,
|
||||
rty.into(),
|
||||
Add: BiAdd,
|
||||
Sub: BiSub,
|
||||
Mul: BiMul,
|
||||
Div: BiDiv,
|
||||
Rem: BiRem,
|
||||
And: BiAnd,
|
||||
Or: BiOr,
|
||||
BitAnd: BiBitAnd,
|
||||
BitOr: BiBitOr,
|
||||
BitXor: BiBitXor,
|
||||
Shr: BiShr,
|
||||
Shl: BiShl
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Rem,
|
||||
And,
|
||||
Or,
|
||||
BitAnd,
|
||||
BitOr,
|
||||
BitXor,
|
||||
Shr,
|
||||
Shl
|
||||
) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -224,13 +224,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
// a = b commutative_op a
|
||||
if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) {
|
||||
match op.node {
|
||||
hir::BiAdd
|
||||
| hir::BiMul
|
||||
| hir::BiAnd
|
||||
| hir::BiOr
|
||||
| hir::BiBitXor
|
||||
| hir::BiBitAnd
|
||||
| hir::BiBitOr => {
|
||||
hir::BinOpKind::Add
|
||||
| hir::BinOpKind::Mul
|
||||
| hir::BinOpKind::And
|
||||
| hir::BinOpKind::Or
|
||||
| hir::BinOpKind::BitXor
|
||||
| hir::BinOpKind::BitAnd
|
||||
| hir::BinOpKind::BitOr => {
|
||||
lint(assignee, l);
|
||||
},
|
||||
_ => {},
|
||||
|
@ -244,11 +244,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_commutative(op: hir::BinOp_) -> bool {
|
||||
use rustc::hir::BinOp_::*;
|
||||
fn is_commutative(op: hir::BinOpKind) -> bool {
|
||||
use rustc::hir::BinOpKind::*;
|
||||
match op {
|
||||
BiAdd | BiMul | BiAnd | BiOr | BiBitXor | BiBitAnd | BiBitOr | BiEq | BiNe => true,
|
||||
BiSub | BiDiv | BiRem | BiShl | BiShr | BiLt | BiLe | BiGe | BiGt => false,
|
||||
Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true,
|
||||
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)
|
||||
}
|
||||
match item.node {
|
||||
ItemExternCrate(_) | ItemUse(_, _) => {
|
||||
ItemKind::ExternCrate(_) | ItemKind::Use(_, _) => {
|
||||
for attr in &item.attrs {
|
||||
if let Some(ref lint_list) = attr.meta_item_list() {
|
||||
match &*attr.name().as_str() {
|
||||
|
@ -162,7 +162,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
|
|||
// whitelist `unused_imports` and `deprecated`
|
||||
for lint in lint_list {
|
||||
if is_word(lint, "unused_imports") || is_word(lint, "deprecated") {
|
||||
if let ItemUse(_, _) = item.node {
|
||||
if let ItemKind::Use(_, _) = item.node {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
|
|||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
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 {
|
||||
if let Some(stmt) = block.stmts.first() {
|
||||
match stmt.node {
|
||||
StmtDecl(_, _) => true,
|
||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => is_relevant_expr(tcx, tables, expr),
|
||||
StmtKind::Decl(_, _) => true,
|
||||
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => is_relevant_expr(tcx, tables, expr),
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
match expr.node {
|
||||
ExprBlock(ref block, _) => is_relevant_block(tcx, tables, block),
|
||||
ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e),
|
||||
ExprRet(None) | ExprBreak(_, None) => false,
|
||||
ExprCall(ref path_expr, _) => if let ExprPath(ref qpath) = path_expr.node {
|
||||
ExprKind::Block(ref block, _) => is_relevant_block(tcx, tables, block),
|
||||
ExprKind::Ret(Some(ref e)) => is_relevant_expr(tcx, tables, e),
|
||||
ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
|
||||
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)) {
|
||||
!match_def_path(tcx, fun_id, &paths::BEGIN_PANIC)
|
||||
} else {
|
||||
|
|
|
@ -109,7 +109,7 @@ impl LintPass for BitMask {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
|
||||
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 let Some(cmp_opt) = fetch_int_literal(cx, right) {
|
||||
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 let Expr_::ExprBinary(ref op, ref left, ref right) = e.node;
|
||||
if BinOp_::BiEq == op.node;
|
||||
if let Expr_::ExprBinary(ref op1, ref left1, ref right1) = left.node;
|
||||
if BinOp_::BiBitAnd == op1.node;
|
||||
if let Expr_::ExprLit(ref lit) = right1.node;
|
||||
if let ExprKind::Binary(ref op, ref left, ref right) = e.node;
|
||||
if BinOpKind::Eq == op.node;
|
||||
if let ExprKind::Binary(ref op1, ref left1, ref right1) = left.node;
|
||||
if BinOpKind::BitAnd == op1.node;
|
||||
if let ExprKind::Lit(ref lit) = right1.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 n.leading_zeros() == n.count_zeros();
|
||||
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 {
|
||||
BiEq => BiEq,
|
||||
BiNe => BiNe,
|
||||
BiLt => BiGt,
|
||||
BiGt => BiLt,
|
||||
BiLe => BiGe,
|
||||
BiGe => BiLe,
|
||||
_ => BiOr, // Dummy
|
||||
BinOpKind::Eq => BinOpKind::Eq,
|
||||
BinOpKind::Ne => BinOpKind::Ne,
|
||||
BinOpKind::Lt => BinOpKind::Gt,
|
||||
BinOpKind::Gt => BinOpKind::Lt,
|
||||
BinOpKind::Le => BinOpKind::Ge,
|
||||
BinOpKind::Ge => BinOpKind::Le,
|
||||
_ => BinOpKind::Or, // Dummy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u128, span: Span) {
|
||||
if let ExprBinary(ref op, ref left, ref right) = bit_op.node {
|
||||
if op.node != BiBitAnd && op.node != BiBitOr {
|
||||
fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOpKind, cmp_value: u128, span: Span) {
|
||||
if let ExprKind::Binary(ref op, ref left, ref right) = bit_op.node {
|
||||
if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr {
|
||||
return;
|
||||
}
|
||||
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 {
|
||||
BiEq | BiNe => match bit_op {
|
||||
BiBitAnd => if mask_value & cmp_value != cmp_value {
|
||||
BinOpKind::Eq | BinOpKind::Ne => match bit_op {
|
||||
BinOpKind::BitAnd => if mask_value & cmp_value != cmp_value {
|
||||
if cmp_value != 0 {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -186,7 +186,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
|
|||
} else if mask_value == 0 {
|
||||
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(
|
||||
cx,
|
||||
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 {
|
||||
BiBitAnd => if mask_value < cmp_value {
|
||||
BinOpKind::Lt | BinOpKind::Ge => match bit_op {
|
||||
BinOpKind::BitAnd => if mask_value < cmp_value {
|
||||
span_lint(
|
||||
cx,
|
||||
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 {
|
||||
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(
|
||||
cx,
|
||||
BAD_BIT_MASK,
|
||||
|
@ -229,11 +229,11 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
|
|||
} else {
|
||||
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 {
|
||||
BiBitAnd => if mask_value <= cmp_value {
|
||||
BinOpKind::Le | BinOpKind::Gt => match bit_op {
|
||||
BinOpKind::BitAnd => if mask_value <= cmp_value {
|
||||
span_lint(
|
||||
cx,
|
||||
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 {
|
||||
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(
|
||||
cx,
|
||||
BAD_BIT_MASK,
|
||||
|
@ -261,7 +261,7 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
|
|||
} else {
|
||||
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> {
|
||||
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 ex = &body.value;
|
||||
if matches!(ex.node, ExprBlock(_, _)) {
|
||||
if matches!(ex.node, ExprKind::Block(_, _)) {
|
||||
self.found_block = Some(ex);
|
||||
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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if let ExprIf(ref check, ref then, _) = expr.node {
|
||||
if let ExprBlock(ref block, _) = check.node {
|
||||
if let ExprKind::If(ref check, ref then, _) = expr.node {
|
||||
if let ExprKind::Block(ref block, _) = check.node {
|
||||
if block.rules == DefaultBlock {
|
||||
if block.stmts.is_empty() {
|
||||
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> {
|
||||
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 {
|
||||
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 {
|
||||
v = self.extract(op, &[lhs, rhs], v)?;
|
||||
continue;
|
||||
|
@ -101,13 +101,13 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
|||
// prevent folding of `cfg!` macros and the like
|
||||
if !in_macro(e.span) {
|
||||
match e.node {
|
||||
ExprUnary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)),
|
||||
ExprBinary(binop, ref lhs, ref rhs) => match binop.node {
|
||||
BiOr => return Ok(Bool::Or(self.extract(BiOr, &[lhs, rhs], Vec::new())?)),
|
||||
BiAnd => return Ok(Bool::And(self.extract(BiAnd, &[lhs, rhs], Vec::new())?)),
|
||||
ExprKind::Unary(UnNot, ref inner) => return Ok(Bool::Not(box self.run(inner)?)),
|
||||
ExprKind::Binary(binop, ref lhs, ref rhs) => match binop.node {
|
||||
BinOpKind::Or => return Ok(Bool::Or(self.extract(BinOpKind::Or, &[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(false) => return Ok(Bool::False),
|
||||
_ => (),
|
||||
|
@ -121,8 +121,8 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
|||
return Ok(Bool::Term(n as u8));
|
||||
}
|
||||
let negated = match e.node {
|
||||
ExprBinary(binop, ref lhs, ref rhs) => {
|
||||
|
||||
ExprKind::Binary(binop, ref lhs, ref rhs) => {
|
||||
|
||||
if !implements_ord(self.cx, lhs) {
|
||||
continue;
|
||||
}
|
||||
|
@ -133,16 +133,16 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
|||
hir_id: DUMMY_HIR_ID,
|
||||
span: DUMMY_SP,
|
||||
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 {
|
||||
BiEq => mk_expr(BiNe),
|
||||
BiNe => mk_expr(BiEq),
|
||||
BiGt => mk_expr(BiLe),
|
||||
BiGe => mk_expr(BiLt),
|
||||
BiLt => mk_expr(BiGe),
|
||||
BiLe => mk_expr(BiGt),
|
||||
BinOpKind::Eq => mk_expr(BinOpKind::Ne),
|
||||
BinOpKind::Ne => mk_expr(BinOpKind::Eq),
|
||||
BinOpKind::Gt => mk_expr(BinOpKind::Le),
|
||||
BinOpKind::Ge => mk_expr(BinOpKind::Lt),
|
||||
BinOpKind::Lt => mk_expr(BinOpKind::Ge),
|
||||
BinOpKind::Le => mk_expr(BinOpKind::Gt),
|
||||
_ => continue,
|
||||
}
|
||||
},
|
||||
|
@ -178,23 +178,23 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
|
|||
|
||||
fn simplify_not(&self, expr: &Expr) -> Option<String> {
|
||||
match expr.node {
|
||||
ExprBinary(binop, ref lhs, ref rhs) => {
|
||||
ExprKind::Binary(binop, ref lhs, ref rhs) => {
|
||||
|
||||
if !implements_ord(self.cx, lhs) {
|
||||
return None;
|
||||
}
|
||||
|
||||
match binop.node {
|
||||
BiEq => Some(" != "),
|
||||
BiNe => Some(" == "),
|
||||
BiLt => Some(" >= "),
|
||||
BiGt => Some(" <= "),
|
||||
BiLe => Some(" > "),
|
||||
BiGe => Some(" < "),
|
||||
BinOpKind::Eq => Some(" != "),
|
||||
BinOpKind::Ne => Some(" == "),
|
||||
BinOpKind::Lt => Some(" >= "),
|
||||
BinOpKind::Gt => Some(" <= "),
|
||||
BinOpKind::Le => Some(" > "),
|
||||
BinOpKind::Ge => Some(" < "),
|
||||
_ => None,
|
||||
}.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]);
|
||||
if !match_type(self.cx, type_of_receiver, &paths::OPTION) &&
|
||||
!match_type(self.cx, type_of_receiver, &paths::RESULT) {
|
||||
|
@ -441,8 +441,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
match e.node {
|
||||
ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
|
||||
ExprUnary(UnNot, ref inner) => if self.cx.tables.node_types()[inner.hir_id].is_bool() {
|
||||
ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => self.bool_expr(e),
|
||||
ExprKind::Unary(UnNot, ref inner) => if self.cx.tables.node_types()[inner.hir_id].is_bool() {
|
||||
self.bool_expr(e);
|
||||
} else {
|
||||
walk_expr(self, e);
|
||||
|
|
|
@ -38,20 +38,20 @@ impl LintPass for ByteCount {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
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_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_args.len() == 2;
|
||||
if let ExprClosure(_, _, body_id, _, _) = filter_args[1].node;
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = filter_args[1].node;
|
||||
then {
|
||||
let body = cx.tcx.hir.body(body_id);
|
||||
if_chain! {
|
||||
if body.arguments.len() == 1;
|
||||
if let Some(argname) = get_pat_name(&body.arguments[0].pat);
|
||||
if let ExprBinary(ref op, ref l, ref r) = body.value.node;
|
||||
if op.node == BiEq;
|
||||
if let ExprKind::Binary(ref op, ref l, ref r) = body.value.node;
|
||||
if op.node == BinOpKind::Eq;
|
||||
if match_type(cx,
|
||||
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])),
|
||||
&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 {
|
||||
return;
|
||||
}
|
||||
let haystack = if let ExprMethodCall(ref path, _, ref args) =
|
||||
let haystack = if let ExprKind::MethodCall(ref path, _, ref args) =
|
||||
filter_args[0].node {
|
||||
let p = path.ident.name;
|
||||
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> {
|
||||
match expr.node {
|
||||
ExprBox(ref e) | ExprAddrOf(_, ref e) | ExprUnary(UnOp::UnDeref, ref e) => get_path_name(e),
|
||||
ExprBlock(ref b, _) => if b.stmts.is_empty() {
|
||||
ExprKind::Box(ref e) | ExprKind::AddrOf(_, ref e) | ExprKind::Unary(UnOp::UnDeref, ref e) => get_path_name(e),
|
||||
ExprKind::Block(ref b, _) => if b.stmts.is_empty() {
|
||||
b.expr.as_ref().and_then(|p| get_path_name(p))
|
||||
} else {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,25 +211,25 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
/// simple constant folding: Insert an expression, get a constant or none.
|
||||
pub fn expr(&mut self, e: &Expr) -> Option<Constant> {
|
||||
match e.node {
|
||||
ExprPath(ref qpath) => self.fetch_path(qpath, e.hir_id),
|
||||
ExprBlock(ref block, _) => self.block(block),
|
||||
ExprIf(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))),
|
||||
ExprArray(ref vec) => self.multi(vec).map(Constant::Vec),
|
||||
ExprTup(ref tup) => self.multi(tup).map(Constant::Tuple),
|
||||
ExprRepeat(ref value, _) => {
|
||||
ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
|
||||
ExprKind::Block(ref block, _) => self.block(block),
|
||||
ExprKind::If(ref cond, ref then, ref otherwise) => self.ifthenelse(cond, then, otherwise),
|
||||
ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))),
|
||||
ExprKind::Array(ref vec) => self.multi(vec).map(Constant::Vec),
|
||||
ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
|
||||
ExprKind::Repeat(ref value, _) => {
|
||||
let n = match self.tables.expr_ty(e).sty {
|
||||
ty::TyArray(_, n) => n.assert_usize(self.tcx).expect("array length"),
|
||||
_ => span_bug!(e.span, "typeck error"),
|
||||
};
|
||||
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)),
|
||||
UnNeg => self.constant_negate(&o, self.tables.expr_ty(e)),
|
||||
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
|
||||
_ => None,
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
.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> {
|
||||
let def = self.tables.qpath_def(qpath, id);
|
||||
match def {
|
||||
|
@ -340,43 +340,43 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
let r = sext(self.tcx, r, ity);
|
||||
let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));
|
||||
match op.node {
|
||||
BiAdd => l.checked_add(r).map(zext),
|
||||
BiSub => l.checked_sub(r).map(zext),
|
||||
BiMul => l.checked_mul(r).map(zext),
|
||||
BiDiv if r != 0 => l.checked_div(r).map(zext),
|
||||
BiRem if r != 0 => l.checked_rem(r).map(zext),
|
||||
BiShr => l.checked_shr(r as u128 as u32).map(zext),
|
||||
BiShl => l.checked_shl(r as u128 as u32).map(zext),
|
||||
BiBitXor => Some(zext(l ^ r)),
|
||||
BiBitOr => Some(zext(l | r)),
|
||||
BiBitAnd => Some(zext(l & r)),
|
||||
BiEq => Some(Constant::Bool(l == r)),
|
||||
BiNe => Some(Constant::Bool(l != r)),
|
||||
BiLt => Some(Constant::Bool(l < r)),
|
||||
BiLe => Some(Constant::Bool(l <= r)),
|
||||
BiGe => Some(Constant::Bool(l >= r)),
|
||||
BiGt => Some(Constant::Bool(l > r)),
|
||||
BinOpKind::Add => l.checked_add(r).map(zext),
|
||||
BinOpKind::Sub => l.checked_sub(r).map(zext),
|
||||
BinOpKind::Mul => l.checked_mul(r).map(zext),
|
||||
BinOpKind::Div if r != 0 => l.checked_div(r).map(zext),
|
||||
BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext),
|
||||
BinOpKind::Shr => l.checked_shr(r as u128 as u32).map(zext),
|
||||
BinOpKind::Shl => l.checked_shl(r as u128 as u32).map(zext),
|
||||
BinOpKind::BitXor => Some(zext(l ^ r)),
|
||||
BinOpKind::BitOr => Some(zext(l | r)),
|
||||
BinOpKind::BitAnd => Some(zext(l & r)),
|
||||
BinOpKind::Eq => Some(Constant::Bool(l == r)),
|
||||
BinOpKind::Ne => Some(Constant::Bool(l != r)),
|
||||
BinOpKind::Lt => Some(Constant::Bool(l < r)),
|
||||
BinOpKind::Le => Some(Constant::Bool(l <= r)),
|
||||
BinOpKind::Ge => Some(Constant::Bool(l >= r)),
|
||||
BinOpKind::Gt => Some(Constant::Bool(l > r)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
ty::TyUint(_) => {
|
||||
match op.node {
|
||||
BiAdd => l.checked_add(r).map(Constant::Int),
|
||||
BiSub => l.checked_sub(r).map(Constant::Int),
|
||||
BiMul => l.checked_mul(r).map(Constant::Int),
|
||||
BiDiv => l.checked_div(r).map(Constant::Int),
|
||||
BiRem => l.checked_rem(r).map(Constant::Int),
|
||||
BiShr => l.checked_shr(r as u32).map(Constant::Int),
|
||||
BiShl => l.checked_shl(r as u32).map(Constant::Int),
|
||||
BiBitXor => Some(Constant::Int(l ^ r)),
|
||||
BiBitOr => Some(Constant::Int(l | r)),
|
||||
BiBitAnd => Some(Constant::Int(l & r)),
|
||||
BiEq => Some(Constant::Bool(l == r)),
|
||||
BiNe => Some(Constant::Bool(l != r)),
|
||||
BiLt => Some(Constant::Bool(l < r)),
|
||||
BiLe => Some(Constant::Bool(l <= r)),
|
||||
BiGe => Some(Constant::Bool(l >= r)),
|
||||
BiGt => Some(Constant::Bool(l > r)),
|
||||
BinOpKind::Add => l.checked_add(r).map(Constant::Int),
|
||||
BinOpKind::Sub => l.checked_sub(r).map(Constant::Int),
|
||||
BinOpKind::Mul => l.checked_mul(r).map(Constant::Int),
|
||||
BinOpKind::Div => l.checked_div(r).map(Constant::Int),
|
||||
BinOpKind::Rem => l.checked_rem(r).map(Constant::Int),
|
||||
BinOpKind::Shr => l.checked_shr(r as u32).map(Constant::Int),
|
||||
BinOpKind::Shl => l.checked_shl(r as u32).map(Constant::Int),
|
||||
BinOpKind::BitXor => Some(Constant::Int(l ^ r)),
|
||||
BinOpKind::BitOr => Some(Constant::Int(l | r)),
|
||||
BinOpKind::BitAnd => Some(Constant::Int(l & r)),
|
||||
BinOpKind::Eq => Some(Constant::Bool(l == r)),
|
||||
BinOpKind::Ne => Some(Constant::Bool(l != r)),
|
||||
BinOpKind::Lt => Some(Constant::Bool(l < r)),
|
||||
BinOpKind::Le => Some(Constant::Bool(l <= r)),
|
||||
BinOpKind::Ge => Some(Constant::Bool(l >= r)),
|
||||
BinOpKind::Gt => Some(Constant::Bool(l > r)),
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
|
@ -384,40 +384,40 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
}
|
||||
},
|
||||
(Constant::F32(l), Some(Constant::F32(r))) => match op.node {
|
||||
BiAdd => Some(Constant::F32(l + r)),
|
||||
BiSub => Some(Constant::F32(l - r)),
|
||||
BiMul => Some(Constant::F32(l * r)),
|
||||
BiDiv => Some(Constant::F32(l / r)),
|
||||
BiRem => Some(Constant::F32(l % r)),
|
||||
BiEq => Some(Constant::Bool(l == r)),
|
||||
BiNe => Some(Constant::Bool(l != r)),
|
||||
BiLt => Some(Constant::Bool(l < r)),
|
||||
BiLe => Some(Constant::Bool(l <= r)),
|
||||
BiGe => Some(Constant::Bool(l >= r)),
|
||||
BiGt => Some(Constant::Bool(l > r)),
|
||||
BinOpKind::Add => Some(Constant::F32(l + r)),
|
||||
BinOpKind::Sub => Some(Constant::F32(l - r)),
|
||||
BinOpKind::Mul => Some(Constant::F32(l * r)),
|
||||
BinOpKind::Div => Some(Constant::F32(l / r)),
|
||||
BinOpKind::Rem => Some(Constant::F32(l % r)),
|
||||
BinOpKind::Eq => Some(Constant::Bool(l == r)),
|
||||
BinOpKind::Ne => Some(Constant::Bool(l != r)),
|
||||
BinOpKind::Lt => Some(Constant::Bool(l < r)),
|
||||
BinOpKind::Le => Some(Constant::Bool(l <= r)),
|
||||
BinOpKind::Ge => Some(Constant::Bool(l >= r)),
|
||||
BinOpKind::Gt => Some(Constant::Bool(l > r)),
|
||||
_ => None,
|
||||
},
|
||||
(Constant::F64(l), Some(Constant::F64(r))) => match op.node {
|
||||
BiAdd => Some(Constant::F64(l + r)),
|
||||
BiSub => Some(Constant::F64(l - r)),
|
||||
BiMul => Some(Constant::F64(l * r)),
|
||||
BiDiv => Some(Constant::F64(l / r)),
|
||||
BiRem => Some(Constant::F64(l % r)),
|
||||
BiEq => Some(Constant::Bool(l == r)),
|
||||
BiNe => Some(Constant::Bool(l != r)),
|
||||
BiLt => Some(Constant::Bool(l < r)),
|
||||
BiLe => Some(Constant::Bool(l <= r)),
|
||||
BiGe => Some(Constant::Bool(l >= r)),
|
||||
BiGt => Some(Constant::Bool(l > r)),
|
||||
BinOpKind::Add => Some(Constant::F64(l + r)),
|
||||
BinOpKind::Sub => Some(Constant::F64(l - r)),
|
||||
BinOpKind::Mul => Some(Constant::F64(l * r)),
|
||||
BinOpKind::Div => Some(Constant::F64(l / r)),
|
||||
BinOpKind::Rem => Some(Constant::F64(l % r)),
|
||||
BinOpKind::Eq => Some(Constant::Bool(l == r)),
|
||||
BinOpKind::Ne => Some(Constant::Bool(l != r)),
|
||||
BinOpKind::Lt => Some(Constant::Bool(l < r)),
|
||||
BinOpKind::Le => Some(Constant::Bool(l <= r)),
|
||||
BinOpKind::Ge => Some(Constant::Bool(l >= r)),
|
||||
BinOpKind::Gt => Some(Constant::Bool(l > r)),
|
||||
_ => None,
|
||||
},
|
||||
(l, r) => match (op.node, l, r) {
|
||||
(BiAnd, Constant::Bool(false), _) => Some(Constant::Bool(false)),
|
||||
(BiOr, Constant::Bool(true), _) => Some(Constant::Bool(true)),
|
||||
(BiAnd, Constant::Bool(true), Some(r)) | (BiOr, Constant::Bool(false), Some(r)) => Some(r),
|
||||
(BiBitXor, 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)),
|
||||
(BiBitOr, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l | r)),
|
||||
(BinOpKind::And, Constant::Bool(false), _) => Some(Constant::Bool(false)),
|
||||
(BinOpKind::Or, Constant::Bool(true), _) => Some(Constant::Bool(true)),
|
||||
(BinOpKind::And, Constant::Bool(true), Some(r)) | (BinOpKind::Or, Constant::Bool(false), Some(r)) => Some(r),
|
||||
(BinOpKind::BitXor, 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)),
|
||||
(BinOpKind::BitOr, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l | r)),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste {
|
|||
if !in_macro(expr.span) {
|
||||
// skip ifs directly in else, it will be checked in the parent if
|
||||
if let Some(&Expr {
|
||||
node: ExprIf(_, _, Some(ref else_expr)),
|
||||
node: ExprKind::If(_, _, Some(ref else_expr)),
|
||||
..
|
||||
}) = get_parent_expr(cx, expr)
|
||||
{
|
||||
|
@ -172,7 +172,7 @@ fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) {
|
|||
|
||||
/// Implementation of `MATCH_SAME_ARMS`.
|
||||
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 mut h = SpanlessHash::new(cx, cx.tables);
|
||||
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 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);
|
||||
if let ExprBlock(ref block, _) = then_expr.node {
|
||||
if let ExprKind::Block(ref block, _) = then_expr.node {
|
||||
blocks.push(block);
|
||||
} 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 {
|
||||
|
@ -253,7 +253,7 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
|
|||
|
||||
// final `else {..}`
|
||||
if !blocks.is_empty() {
|
||||
if let ExprBlock(ref block, _) = expr.node {
|
||||
if let ExprKind::Block(ref block, _) = expr.node {
|
||||
blocks.push(&**block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,14 +147,14 @@ struct CCHelper<'a, 'tcx: 'a> {
|
|||
impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, e: &'tcx Expr) {
|
||||
match e.node {
|
||||
ExprMatch(_, ref arms, _) => {
|
||||
ExprKind::Match(_, ref arms, _) => {
|
||||
walk_expr(self, e);
|
||||
let arms_n: u64 = arms.iter().map(|arm| arm.pats.len() as u64).sum();
|
||||
if arms_n > 1 {
|
||||
self.match_arms += arms_n - 2;
|
||||
}
|
||||
},
|
||||
ExprCall(ref callee, _) => {
|
||||
ExprKind::Call(ref callee, _) => {
|
||||
walk_expr(self, e);
|
||||
let ty = self.cx.tables.node_id_to_type(callee.hir_id);
|
||||
match ty.sty {
|
||||
|
@ -167,15 +167,15 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
|
|||
_ => (),
|
||||
}
|
||||
},
|
||||
ExprClosure(.., _) => (),
|
||||
ExprBinary(op, _, _) => {
|
||||
ExprKind::Closure(.., _) => (),
|
||||
ExprKind::Binary(op, _, _) => {
|
||||
walk_expr(self, e);
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ impl LintPass for DefaultTraitAccess {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
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 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 match_def_path(cx.tcx, def_id, &paths::DEFAULT_TRAIT_METHOD);
|
||||
then {
|
||||
|
|
|
@ -70,7 +70,7 @@ impl LintPass for Derive {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive {
|
||||
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 is_automatically_derived = is_automatically_derived(&*item.attrs);
|
||||
|
||||
|
|
|
@ -41,13 +41,13 @@ impl<'a, 'tcx> DoubleComparisonPass {
|
|||
fn check_binop(
|
||||
&self,
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
op: BinOp_,
|
||||
op: BinOpKind,
|
||||
lhs: &'tcx Expr,
|
||||
rhs: &'tcx Expr,
|
||||
span: Span,
|
||||
) {
|
||||
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)
|
||||
}
|
||||
_ => return,
|
||||
|
@ -67,10 +67,10 @@ impl<'a, 'tcx> DoubleComparisonPass {
|
|||
}}
|
||||
}
|
||||
match (op, lkind, rkind) {
|
||||
(BiOr, BiEq, BiLt) | (BiOr, BiLt, BiEq) => lint_double_comparison!(<=),
|
||||
(BiOr, BiEq, BiGt) | (BiOr, BiGt, BiEq) => lint_double_comparison!(>=),
|
||||
(BiOr, BiLt, BiGt) | (BiOr, BiGt, BiLt) => lint_double_comparison!(!=),
|
||||
(BiAnd, BiLe, BiGe) | (BiAnd, BiGe, BiLe) => lint_double_comparison!(==),
|
||||
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Lt) | (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Eq) => lint_double_comparison!(<=),
|
||||
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Eq) => lint_double_comparison!(>=),
|
||||
(BinOpKind::Or, BinOpKind::Lt, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Lt) => 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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,8 +116,8 @@ impl LintPass for Pass {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if_chain! {
|
||||
if let ExprCall(ref path, ref args) = expr.node;
|
||||
if let ExprPath(ref qpath) = path.node;
|
||||
if let ExprKind::Call(ref path, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath) = path.node;
|
||||
if args.len() == 1;
|
||||
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
|
||||
then {
|
||||
|
|
|
@ -38,8 +38,8 @@ impl LintPass for DurationSubsec {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if_chain! {
|
||||
if let ExprBinary(Spanned { node: BiDiv, .. }, ref left, ref right) = expr.node;
|
||||
if let ExprMethodCall(ref method_path, _ , ref args) = left.node;
|
||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.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 let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right);
|
||||
then {
|
||||
|
|
|
@ -34,7 +34,7 @@ impl LintPass for EmptyEnum {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
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 adt = ty.ty_adt_def()
|
||||
.expect("already checked whether this is an enum");
|
||||
|
|
|
@ -41,13 +41,13 @@ impl LintPass for HashMapLint {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint {
|
||||
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 ExprUnary(UnOp::UnNot, ref check) = check.node {
|
||||
if let ExprKind::If(ref check, ref then_block, ref else_block) = expr.node {
|
||||
if let ExprKind::Unary(UnOp::UnNot, ref check) = check.node {
|
||||
if let Some((ty, map, key)) = check_cond(cx, check) {
|
||||
// in case of `if !m.contains_key(&k) { m.insert(k, v); }`
|
||||
// we can give a better error message
|
||||
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
|
||||
} else {
|
||||
true
|
||||
|
@ -88,10 +88,10 @@ fn check_cond<'a, 'tcx, 'b>(
|
|||
check: &'b Expr,
|
||||
) -> Option<(&'static str, &'b Expr, &'b Expr)> {
|
||||
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 path.ident.name == "contains_key";
|
||||
if let ExprAddrOf(_, ref key) = params[1].node;
|
||||
if let ExprKind::AddrOf(_, ref key) = params[1].node;
|
||||
then {
|
||||
let map = ¶ms[0];
|
||||
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> {
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
||||
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 path.ident.name == "insert";
|
||||
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 {
|
||||
return;
|
||||
}
|
||||
if let ItemEnum(ref def, _) = item.node {
|
||||
if let ItemKind::Enum(ref def, _) = item.node {
|
||||
for var in &def.variants {
|
||||
let variant = &var.node;
|
||||
if let Some(ref anon_const) = variant.disr_expr {
|
||||
|
|
|
@ -44,10 +44,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EnumGlobUse {
|
|||
|
||||
impl EnumGlobUse {
|
||||
fn lint_item(&self, cx: &LateContext, item: &Item) {
|
||||
if item.vis.node == VisibilityKind::Public {
|
||||
if item.vis.node.is_pub() {
|
||||
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 {
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
@ -262,7 +262,7 @@ impl EarlyLintPass for EnumVariantNames {
|
|||
);
|
||||
}
|
||||
}
|
||||
if item.vis.node == VisibilityKind::Public {
|
||||
if item.vis.node.is_pub() {
|
||||
let matching = partial_match(mod_camel, &item_camel);
|
||||
let rmatching = partial_rmatch(mod_camel, &item_camel);
|
||||
let nchars = mod_camel.chars().count();
|
||||
|
|
|
@ -52,7 +52,7 @@ impl LintPass for EqOp {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -66,28 +66,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
|||
return;
|
||||
}
|
||||
let (trait_id, requires_ref) = match op.node {
|
||||
BiAdd => (cx.tcx.lang_items().add_trait(), false),
|
||||
BiSub => (cx.tcx.lang_items().sub_trait(), false),
|
||||
BiMul => (cx.tcx.lang_items().mul_trait(), false),
|
||||
BiDiv => (cx.tcx.lang_items().div_trait(), false),
|
||||
BiRem => (cx.tcx.lang_items().rem_trait(), false),
|
||||
BinOpKind::Add => (cx.tcx.lang_items().add_trait(), false),
|
||||
BinOpKind::Sub => (cx.tcx.lang_items().sub_trait(), false),
|
||||
BinOpKind::Mul => (cx.tcx.lang_items().mul_trait(), false),
|
||||
BinOpKind::Div => (cx.tcx.lang_items().div_trait(), false),
|
||||
BinOpKind::Rem => (cx.tcx.lang_items().rem_trait(), false),
|
||||
// don't lint short circuiting ops
|
||||
BiAnd | BiOr => return,
|
||||
BiBitXor => (cx.tcx.lang_items().bitxor_trait(), false),
|
||||
BiBitAnd => (cx.tcx.lang_items().bitand_trait(), false),
|
||||
BiBitOr => (cx.tcx.lang_items().bitor_trait(), false),
|
||||
BiShl => (cx.tcx.lang_items().shl_trait(), false),
|
||||
BiShr => (cx.tcx.lang_items().shr_trait(), false),
|
||||
BiNe | BiEq => (cx.tcx.lang_items().eq_trait(), true),
|
||||
BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items().ord_trait(), true),
|
||||
BinOpKind::And | BinOpKind::Or => return,
|
||||
BinOpKind::BitXor => (cx.tcx.lang_items().bitxor_trait(), false),
|
||||
BinOpKind::BitAnd => (cx.tcx.lang_items().bitand_trait(), false),
|
||||
BinOpKind::BitOr => (cx.tcx.lang_items().bitor_trait(), false),
|
||||
BinOpKind::Shl => (cx.tcx.lang_items().shl_trait(), false),
|
||||
BinOpKind::Shr => (cx.tcx.lang_items().shr_trait(), false),
|
||||
BinOpKind::Ne | BinOpKind::Eq => (cx.tcx.lang_items().eq_trait(), true),
|
||||
BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => (cx.tcx.lang_items().ord_trait(), true),
|
||||
};
|
||||
if let Some(trait_id) = trait_id {
|
||||
#[allow(match_same_arms)]
|
||||
match (&left.node, &right.node) {
|
||||
// do not suggest to dereference literals
|
||||
(&ExprLit(..), _) | (_, &ExprLit(..)) => {},
|
||||
(&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
|
||||
// &foo == &bar
|
||||
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
|
||||
(&ExprKind::AddrOf(_, ref l), &ExprKind::AddrOf(_, ref r)) => {
|
||||
let lty = cx.tables.expr_ty(l);
|
||||
let rty = cx.tables.expr_ty(r);
|
||||
let lcpy = is_copy(cx, lty);
|
||||
|
@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
|||
}
|
||||
},
|
||||
// &foo == bar
|
||||
(&ExprAddrOf(_, ref l), _) => {
|
||||
(&ExprKind::AddrOf(_, ref l), _) => {
|
||||
let lty = cx.tables.expr_ty(l);
|
||||
let lcpy = is_copy(cx, lty);
|
||||
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
|
||||
(_, &ExprAddrOf(_, ref r)) => {
|
||||
(_, &ExprKind::AddrOf(_, ref r)) => {
|
||||
let rty = cx.tables.expr_ty(r);
|
||||
let rcpy = is_copy(cx, rty);
|
||||
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 {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,13 +36,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp {
|
|||
if in_macro(e.span) {
|
||||
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 {
|
||||
BiMul | BiBitAnd => {
|
||||
BinOpKind::Mul | BinOpKind::BitAnd => {
|
||||
check(cx, left, 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 {
|
||||
let id = map.hir_to_node_id(cmt.hir_id);
|
||||
if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) {
|
||||
if let StmtDecl(ref decl, _) = st.node {
|
||||
if let DeclLocal(ref loc) = decl.node {
|
||||
if let StmtKind::Decl(ref decl, _) = st.node {
|
||||
if let DeclKind::Local(ref loc) = decl.node {
|
||||
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) {
|
||||
// let x = box (...)
|
||||
self.set.insert(consume_pat.id);
|
||||
|
|
|
@ -37,7 +37,7 @@ impl LintPass for EtaPass {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
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)
|
||||
},
|
||||
_ => (),
|
||||
|
@ -46,10 +46,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass {
|
|||
}
|
||||
|
||||
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 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() {
|
||||
// Not the same number of arguments, there
|
||||
// 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) {
|
||||
if let PatKind::Binding(_, _, ident, _) = a1.pat.node {
|
||||
// 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 it's a proper path, it can't be a local variable
|
||||
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) {
|
||||
// Find a write to a local variable.
|
||||
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 path.segments.len() == 1 {
|
||||
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) {
|
||||
match stmt.node {
|
||||
StmtExpr(ref e, _) | StmtSemi(ref e, _) => DivergenceVisitor { cx }.maybe_walk_expr(e),
|
||||
StmtDecl(ref d, _) => if let DeclLocal(ref local) = d.node {
|
||||
StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => DivergenceVisitor { cx }.maybe_walk_expr(e),
|
||||
StmtKind::Decl(ref d, _) => if let DeclKind::Local(ref local) = d.node {
|
||||
if let Local {
|
||||
init: Some(ref e), ..
|
||||
} = **local
|
||||
|
@ -102,8 +102,8 @@ struct DivergenceVisitor<'a, 'tcx: 'a> {
|
|||
impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
|
||||
fn maybe_walk_expr(&mut self, e: &'tcx Expr) {
|
||||
match e.node {
|
||||
ExprClosure(.., _) => {},
|
||||
ExprMatch(ref e, ref arms, _) => {
|
||||
ExprKind::Closure(.., _) => {},
|
||||
ExprKind::Match(ref e, ref arms, _) => {
|
||||
self.visit_expr(e);
|
||||
for arm in arms {
|
||||
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> {
|
||||
fn visit_expr(&mut self, e: &'tcx Expr) {
|
||||
match e.node {
|
||||
ExprContinue(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
|
||||
ExprCall(ref func, _) => {
|
||||
ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e),
|
||||
ExprKind::Call(ref func, _) => {
|
||||
let typ = self.cx.tables.expr_ty(func);
|
||||
match typ.sty {
|
||||
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;
|
||||
if borrowed_table.expr_ty(e).is_never() {
|
||||
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 {
|
||||
ExprArray(_) |
|
||||
ExprTup(_) |
|
||||
ExprMethodCall(..) |
|
||||
ExprCall(_, _) |
|
||||
ExprAssign(_, _) |
|
||||
ExprIndex(_, _) |
|
||||
ExprRepeat(_, _) |
|
||||
ExprStruct(_, _, _) => {
|
||||
ExprKind::Array(_) |
|
||||
ExprKind::Tup(_) |
|
||||
ExprKind::MethodCall(..) |
|
||||
ExprKind::Call(_, _) |
|
||||
ExprKind::Assign(_, _) |
|
||||
ExprKind::Index(_, _) |
|
||||
ExprKind::Repeat(_, _) |
|
||||
ExprKind::Struct(_, _, _) => {
|
||||
walk_expr(vis, expr);
|
||||
},
|
||||
ExprBinary(op, _, _) | ExprAssignOp(op, _, _) => {
|
||||
if op.node == BiAnd || op.node == BiOr {
|
||||
ExprKind::Binary(op, _, _) | ExprKind::AssignOp(op, _, _) => {
|
||||
if op.node == BinOpKind::And || op.node == BinOpKind::Or {
|
||||
// x && y and x || y always evaluate x first, so these are
|
||||
// strictly sequenced.
|
||||
} else {
|
||||
walk_expr(vis, expr);
|
||||
}
|
||||
},
|
||||
ExprClosure(_, _, _, _, _) => {
|
||||
ExprKind::Closure(_, _, _, _, _) => {
|
||||
// Either
|
||||
//
|
||||
// * `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 {
|
||||
match stmt.node {
|
||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => check_expr(vis, expr),
|
||||
StmtDecl(ref decl, _) => {
|
||||
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => check_expr(vis, expr),
|
||||
StmtKind::Decl(ref decl, _) => {
|
||||
// If the declaration is of a local variable, check its initializer
|
||||
// expression if it has one. Otherwise, keep going.
|
||||
let local = match decl.node {
|
||||
DeclLocal(ref local) => Some(local),
|
||||
DeclKind::Local(ref local) => Some(local),
|
||||
_ => None,
|
||||
};
|
||||
local
|
||||
|
@ -297,7 +297,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
match expr.node {
|
||||
ExprPath(ref qpath) => {
|
||||
ExprKind::Path(ref qpath) => {
|
||||
if_chain! {
|
||||
if let QPath::Resolved(None, ref path) = *qpath;
|
||||
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
|
||||
// if) the closure will be evaluated, any reads in it might not
|
||||
// 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
|
||||
// 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
|
||||
ExprAddrOf(_, _) => {
|
||||
ExprKind::AddrOf(_, _) => {
|
||||
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 = ...`.
|
||||
fn is_in_assignment_position(cx: &LateContext, expr: &Expr) -> bool {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision {
|
|||
if_chain! {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
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 Some(sugg) = self.check(sym, fty);
|
||||
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) {
|
||||
if_chain! {
|
||||
// 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";
|
||||
// match call to write_fmt
|
||||
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;
|
||||
if write_fun.ident.name == "write_fmt";
|
||||
// match calls to std::io::stdout() / std::io::stderr ()
|
||||
if write_args.len() > 0;
|
||||
if let ExprCall(ref dest_fun, _) = write_args[0].node;
|
||||
if let ExprPath(ref qpath) = dest_fun.node;
|
||||
if let ExprKind::Call(ref dest_fun, _) = write_args[0].node;
|
||||
if let ExprKind::Path(ref qpath) = dest_fun.node;
|
||||
if let Some(dest_fun_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"]) {
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FallibleImplFrom {
|
|||
// check for `impl From<???> for ..`
|
||||
let impl_def_id = cx.tcx.hir.local_def_id(item.id);
|
||||
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 match_def_path(cx.tcx, impl_trait_ref.def_id, &FROM_TRAIT);
|
||||
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) {
|
||||
// check for `begin_panic`
|
||||
if_chain! {
|
||||
if let ExprCall(ref func_expr, _) = expr.node;
|
||||
if let ExprPath(QPath::Resolved(_, ref path)) = func_expr.node;
|
||||
if let ExprKind::Call(ref func_expr, _) = 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 match_def_path(self.tcx, path_def_id, &BEGIN_PANIC) ||
|
||||
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 {
|
||||
|
||||
// `format!("{}", foo)` expansion
|
||||
ExprCall(ref fun, ref args) => {
|
||||
ExprKind::Call(ref fun, ref args) => {
|
||||
if_chain! {
|
||||
if let ExprPath(ref qpath) = fun.node;
|
||||
if let ExprKind::Path(ref qpath) = fun.node;
|
||||
if args.len() == 3;
|
||||
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);
|
||||
|
@ -64,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
},
|
||||
// `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() {
|
||||
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| {
|
||||
|
@ -81,10 +81,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
/// Checks if the expressions matches `&[""]`
|
||||
fn check_single_piece(expr: &Expr) -> bool {
|
||||
if_chain! {
|
||||
if let ExprAddrOf(_, ref expr) = expr.node; // &[""]
|
||||
if let ExprArray(ref exprs) = expr.node; // [""]
|
||||
if let ExprKind::AddrOf(_, ref expr) = expr.node; // &[""]
|
||||
if let ExprKind::Array(ref exprs) = expr.node; // [""]
|
||||
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;
|
||||
then {
|
||||
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
|
||||
fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> {
|
||||
if_chain! {
|
||||
if let ExprAddrOf(_, ref expr) = expr.node;
|
||||
if let ExprMatch(ref match_expr, ref arms, _) = expr.node;
|
||||
if let ExprKind::AddrOf(_, ref expr) = expr.node;
|
||||
if let ExprKind::Match(ref match_expr, ref arms, _) = expr.node;
|
||||
if arms.len() == 1;
|
||||
if arms[0].pats.len() == 1;
|
||||
if let PatKind::Tuple(ref pat, None) = arms[0].pats[0].node;
|
||||
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 let ExprCall(_, ref args) = exprs[0].node;
|
||||
if let ExprKind::Call(_, ref args) = exprs[0].node;
|
||||
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 match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
|
||||
then {
|
||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -143,14 +143,14 @@ fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> {
|
|||
/// ```
|
||||
fn check_unformatted(expr: &Expr) -> bool {
|
||||
if_chain! {
|
||||
if let ExprAddrOf(_, ref expr) = expr.node;
|
||||
if let ExprArray(ref exprs) = expr.node;
|
||||
if let ExprKind::AddrOf(_, ref expr) = expr.node;
|
||||
if let ExprKind::Array(ref exprs) = expr.node;
|
||||
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 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 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";
|
||||
then {
|
||||
return true;
|
||||
|
|
|
@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
|
|||
use rustc::hir::map::Node::*;
|
||||
|
||||
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 {
|
||||
false
|
||||
};
|
||||
|
@ -168,7 +168,7 @@ impl<'a, 'tcx> Functions {
|
|||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
None
|
||||
|
@ -184,7 +184,7 @@ struct DerefVisitor<'a, 'tcx: 'a> {
|
|||
impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprCall(ref f, ref args) => {
|
||||
hir::ExprKind::Call(ref f, ref args) => {
|
||||
let ty = self.tables.expr_ty(f);
|
||||
|
||||
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 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> {
|
||||
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 self.ptrs.contains(&id) {
|
||||
span_lint(
|
||||
|
|
|
@ -43,19 +43,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
|||
}
|
||||
|
||||
match e.node {
|
||||
ExprMatch(_, ref arms, MatchSource::TryDesugar) => {
|
||||
ExprKind::Match(_, ref arms, MatchSource::TryDesugar) => {
|
||||
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,
|
||||
};
|
||||
if let ExprCall(_, ref args) = e.node {
|
||||
if let ExprKind::Call(_, ref args) = e.node {
|
||||
self.try_desugar_arm.push(args[0].id);
|
||||
} else {
|
||||
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" {
|
||||
let a = cx.tables.expr_ty(e);
|
||||
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 match_def_path(cx.tcx, def_id, &paths::FROM_FROM[..]) {
|
||||
let a = cx.tables.expr_ty(e);
|
||||
|
|
|
@ -36,19 +36,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
|
|||
if in_macro(e.span) {
|
||||
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 {
|
||||
BiAdd | BiBitOr | BiBitXor => {
|
||||
BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {
|
||||
check(cx, left, 0, e.span, right.span);
|
||||
check(cx, right, 0, e.span, left.span);
|
||||
},
|
||||
BiShl | BiShr | BiSub => check(cx, right, 0, e.span, left.span),
|
||||
BiMul => {
|
||||
BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub => check(cx, right, 0, e.span, left.span),
|
||||
BinOpKind::Mul => {
|
||||
check(cx, left, 1, e.span, right.span);
|
||||
check(cx, right, 1, e.span, left.span);
|
||||
},
|
||||
BiDiv => check(cx, right, 1, e.span, left.span),
|
||||
BiBitAnd => {
|
||||
BinOpKind::Div => check(cx, right, 1, e.span, left.span),
|
||||
BinOpKind::BitAnd => {
|
||||
check(cx, left, -1, e.span, right.span);
|
||||
check(cx, right, -1, e.span, left.span);
|
||||
},
|
||||
|
|
|
@ -45,16 +45,20 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
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 {
|
||||
let good_method = match arms[0].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 && pats[0].node == PatKind::Wild => {
|
||||
if match_qpath(path, &paths::RESULT_OK) {
|
||||
"is_ok()"
|
||||
} else if match_qpath(path, &paths::RESULT_ERR) {
|
||||
"is_err()"
|
||||
} else if match_qpath(path, &paths::OPTION_SOME) {
|
||||
"is_some()"
|
||||
PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 => {
|
||||
if let PatKind::Wild = pats[0].node {
|
||||
if match_qpath(path, &paths::RESULT_OK) {
|
||||
"is_ok()"
|
||||
} else if match_qpath(path, &paths::RESULT_ERR) {
|
||||
"is_err()"
|
||||
} else if match_qpath(path, &paths::OPTION_SOME) {
|
||||
"is_some()"
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ impl LintPass for IndexingSlicing {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
||||
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);
|
||||
if let Some(range) = higher::range(cx, index) {
|
||||
// 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) {
|
||||
if_chain! {
|
||||
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 let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pats[0].node;
|
||||
if args.len() == 1;
|
||||
|
|
|
@ -141,7 +141,7 @@ static HEURISTICS: &[(&str, usize, Heuristic, Finiteness)] = &[
|
|||
|
||||
fn is_infinite(cx: &LateContext, expr: &Expr) -> Finiteness {
|
||||
match expr.node {
|
||||
ExprMethodCall(ref method, _, ref args) => {
|
||||
ExprKind::MethodCall(ref method, _, ref args) => {
|
||||
for &(name, len, heuristic, cap) in HEURISTICS.iter() {
|
||||
if method.ident.name == name && args.len() == len {
|
||||
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 let ExprClosure(_, _, body_id, _, _) = args[1].node {
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = args[1].node {
|
||||
let body = cx.tcx.hir.body(body_id);
|
||||
return is_infinite(cx, &body.value);
|
||||
}
|
||||
}
|
||||
Finite
|
||||
},
|
||||
ExprBlock(ref block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
|
||||
ExprBox(ref e) | ExprAddrOf(_, ref e) => is_infinite(cx, e),
|
||||
ExprCall(ref path, _) => if let ExprPath(ref qpath) = path.node {
|
||||
ExprKind::Block(ref block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
|
||||
ExprKind::Box(ref e) | ExprKind::AddrOf(_, ref e) => is_infinite(cx, e),
|
||||
ExprKind::Call(ref path, _) => if let ExprKind::Path(ref qpath) = path.node {
|
||||
match_qpath(qpath, &paths::REPEAT).into()
|
||||
} else {
|
||||
Finite
|
||||
},
|
||||
ExprStruct(..) => higher::range(cx, expr)
|
||||
ExprKind::Struct(..) => higher::range(cx, expr)
|
||||
.map_or(false, |r| r.end.is_none())
|
||||
.into(),
|
||||
_ => Finite,
|
||||
|
@ -205,7 +205,7 @@ static COMPLETING_METHODS: &[(&str, usize)] = &[
|
|||
|
||||
fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness {
|
||||
match expr.node {
|
||||
ExprMethodCall(ref method, _, ref args) => {
|
||||
ExprKind::MethodCall(ref method, _, ref args) => {
|
||||
for &(name, len) in COMPLETING_METHODS.iter() {
|
||||
if method.ident.name == name && args.len() == len {
|
||||
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)
|
||||
.and(is_infinite(cx, r))
|
||||
.and(MaybeInfinite);
|
||||
}, // TODO: ExprLoop + Match
|
||||
}, // TODO: ExprKind::Loop + Match
|
||||
_ => (),
|
||||
}
|
||||
Finite
|
||||
|
|
|
@ -56,7 +56,7 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
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
|
||||
self.impls
|
||||
.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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if_chain! {
|
||||
if let ExprCall(ref path, ref args) = expr.node;
|
||||
if let ExprPath(ref qpath) = path.node;
|
||||
if let ExprKind::Call(ref path, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath) = path.node;
|
||||
if args.len() == 0;
|
||||
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));
|
||||
|
|
|
@ -49,7 +49,7 @@ impl LintPass for LargeEnumVariant {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
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 adt = ty.ty_adt_def()
|
||||
.expect("already checked whether this is an enum");
|
||||
|
|
|
@ -68,8 +68,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ItemTrait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_items),
|
||||
ItemImpl(_, _, _, _, None, _, ref impl_items) => check_impl_items(cx, item, impl_items),
|
||||
ItemKind::Trait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_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;
|
||||
}
|
||||
|
||||
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 {
|
||||
BiEq => {
|
||||
BinOpKind::Eq => {
|
||||
check_cmp(cx, expr.span, left, right, "", 0); // len == 0
|
||||
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, right, left, "!", 0); // 0 != len
|
||||
},
|
||||
BiGt => {
|
||||
BinOpKind::Gt => {
|
||||
check_cmp(cx, expr.span, left, right, "!", 0); // len > 0
|
||||
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, right, left, "!", 0); // 0 < len
|
||||
},
|
||||
BiGe => check_cmp(cx, expr.span, left, right, "!", 1), // len <= 1
|
||||
BiLe => check_cmp(cx, expr.span, right, left, "!", 1), // 1 >= len
|
||||
BinOpKind::Ge => check_cmp(cx, expr.span, left, right, "!", 1), // len <= 1
|
||||
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) {
|
||||
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
|
||||
if let Some(name) = get_item_name(cx, method) {
|
||||
if name == "is_empty" {
|
||||
|
@ -258,11 +258,10 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
|
|||
|
||||
let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr));
|
||||
match ty.sty {
|
||||
ty::TyDynamic(..) => cx.tcx
|
||||
.associated_items(ty.ty_to_def_id().expect("trait impl not found"))
|
||||
ty::TyDynamic(ref tt, ..) => cx.tcx
|
||||
.associated_items(tt.principal().expect("trait impl not found").def_id())
|
||||
.any(|item| is_is_empty(cx, &item)),
|
||||
ty::TyProjection(_) => ty.ty_to_def_id()
|
||||
.map_or(false, |id| has_is_empty_impl(cx, id)),
|
||||
ty::TyProjection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
|
||||
ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did),
|
||||
ty::TyArray(..) | ty::TySlice(..) | ty::TyStr => true,
|
||||
_ => false,
|
||||
|
|
|
@ -65,20 +65,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
|
|||
while let Some(stmt) = it.next() {
|
||||
if_chain! {
|
||||
if let Some(expr) = it.peek();
|
||||
if let hir::StmtDecl(ref decl, _) = stmt.node;
|
||||
if let hir::DeclLocal(ref decl) = decl.node;
|
||||
if let hir::StmtKind::Decl(ref decl, _) = stmt.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::StmtExpr(ref if_, _) = expr.node;
|
||||
if let hir::ExprIf(ref cond, ref then, ref else_) = if_.node;
|
||||
if let hir::StmtKind::Expr(ref if_, _) = expr.node;
|
||||
if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.node;
|
||||
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 !used_in_expr(cx, canonical_id, value);
|
||||
then {
|
||||
let span = stmt.span.to(if_.span);
|
||||
|
||||
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_) {
|
||||
(else_.stmts.len() > 1, default)
|
||||
} 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> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
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 self.id == local_id;
|
||||
then {
|
||||
|
@ -163,9 +163,9 @@ fn check_assign<'a, 'tcx>(
|
|||
if_chain! {
|
||||
if block.expr.is_none();
|
||||
if let Some(expr) = block.stmts.iter().last();
|
||||
if let hir::StmtSemi(ref expr, _) = expr.node;
|
||||
if let hir::ExprAssign(ref var, ref value) = expr.node;
|
||||
if let hir::ExprPath(ref qpath) = var.node;
|
||||
if let hir::StmtKind::Semi(ref expr, _) = expr.node;
|
||||
if let hir::ExprKind::Assign(ref var, ref value) = expr.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 decl == local_id;
|
||||
then {
|
||||
|
|
|
@ -59,7 +59,7 @@ impl LintPass for LifetimePass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -338,14 +338,14 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_ty(&mut self, ty: &'tcx Ty) {
|
||||
match ty.node {
|
||||
TyRptr(ref lt, _) if lt.is_elided() => {
|
||||
TyKind::Rptr(ref lt, _) if lt.is_elided() => {
|
||||
self.record(&None);
|
||||
},
|
||||
TyPath(ref path) => {
|
||||
TyKind::Path(ref path) => {
|
||||
if let QPath::Resolved(_, ref path) = *path {
|
||||
if let Def::Existential(def_id) = path.def {
|
||||
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 {
|
||||
if let GenericBound::Outlives(_) = *bound {
|
||||
self.record(&None);
|
||||
|
@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
|
|||
}
|
||||
self.collect_anonymous_lifetimes(path, ty);
|
||||
}
|
||||
TyTraitObject(ref bounds, ref lt) => {
|
||||
TyKind::TraitObject(ref bounds, ref lt) => {
|
||||
if !lt.is_elided() {
|
||||
self.abort = true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::consts::{constant, Constant};
|
|||
|
||||
use crate::utils::{get_enclosing_block, get_parent_expr, higher, in_external_macro, is_integer_literal, is_refutable,
|
||||
last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, snippet, snippet_opt,
|
||||
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then};
|
||||
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq};
|
||||
use crate::utils::paths;
|
||||
|
||||
/// **What it does:** Checks for for-loops that manually copy items between
|
||||
|
@ -411,7 +411,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
|
||||
// check for never_loop
|
||||
match expr.node {
|
||||
ExprWhile(_, ref block, _) | ExprLoop(ref block, _, _) => {
|
||||
ExprKind::While(_, ref block, _) | ExprKind::Loop(ref block, _, _) => {
|
||||
match never_loop_block(block, expr.id) {
|
||||
NeverLoopResult::AlwaysBreak =>
|
||||
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`
|
||||
// (also matches an explicit "match" instead of "if let")
|
||||
// (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
|
||||
if block.stmts.is_empty() && block.expr.is_none() {
|
||||
span_lint(
|
||||
|
@ -440,7 +440,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
let inner_stmt_expr = extract_expr_from_first_stmt(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 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
|
||||
match *source {
|
||||
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;
|
||||
if let (
|
||||
&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)
|
||||
{
|
||||
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
|
||||
if let ExprWhile(ref cond, _, _) = expr.node {
|
||||
if let ExprKind::While(ref cond, _, _) = expr.node {
|
||||
check_infinite_loop(cx, cond, expr);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
|
||||
if let StmtSemi(ref expr, _) = stmt.node {
|
||||
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
||||
if let StmtKind::Semi(ref expr, _) = stmt.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) {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -584,53 +584,53 @@ fn never_loop_block(block: &Block, main_loop_id: NodeId) -> NeverLoopResult {
|
|||
|
||||
fn stmt_to_expr(stmt: &Stmt) -> Option<&Expr> {
|
||||
match stmt.node {
|
||||
StmtSemi(ref e, ..) | StmtExpr(ref e, ..) => Some(e),
|
||||
StmtDecl(ref d, ..) => decl_to_expr(d),
|
||||
StmtKind::Semi(ref e, ..) | StmtKind::Expr(ref e, ..) => Some(e),
|
||||
StmtKind::Decl(ref d, ..) => decl_to_expr(d),
|
||||
}
|
||||
}
|
||||
|
||||
fn decl_to_expr(decl: &Decl) -> Option<&Expr> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
|
||||
match expr.node {
|
||||
ExprBox(ref e) |
|
||||
ExprUnary(_, ref e) |
|
||||
ExprCast(ref e, _) |
|
||||
ExprType(ref e, _) |
|
||||
ExprField(ref e, _) |
|
||||
ExprAddrOf(_, ref e) |
|
||||
ExprStruct(_, _, Some(ref e)) |
|
||||
ExprRepeat(ref e, _) => never_loop_expr(e, main_loop_id),
|
||||
ExprArray(ref es) | ExprMethodCall(_, _, ref es) | ExprTup(ref es) => {
|
||||
ExprKind::Box(ref e) |
|
||||
ExprKind::Unary(_, ref e) |
|
||||
ExprKind::Cast(ref e, _) |
|
||||
ExprKind::Type(ref e, _) |
|
||||
ExprKind::Field(ref e, _) |
|
||||
ExprKind::AddrOf(_, ref e) |
|
||||
ExprKind::Struct(_, _, Some(ref e)) |
|
||||
ExprKind::Repeat(ref e, _) => never_loop_expr(e, main_loop_id),
|
||||
ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es) | ExprKind::Tup(ref es) => {
|
||||
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),
|
||||
ExprBinary(_, ref e1, ref e2) |
|
||||
ExprAssign(ref e1, ref e2) |
|
||||
ExprAssignOp(_, ref e1, ref e2) |
|
||||
ExprIndex(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
|
||||
ExprIf(ref e, ref e2, ref e3) => {
|
||||
ExprKind::Call(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id),
|
||||
ExprKind::Binary(_, ref e1, ref e2) |
|
||||
ExprKind::Assign(ref e1, ref e2) |
|
||||
ExprKind::AssignOp(_, ref e1, ref e2) |
|
||||
ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
|
||||
ExprKind::If(ref e, ref e2, ref e3) => {
|
||||
let e1 = never_loop_expr(e, main_loop_id);
|
||||
let e2 = never_loop_expr(e2, main_loop_id);
|
||||
let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id));
|
||||
combine_seq(e1, combine_branches(e2, e3))
|
||||
},
|
||||
ExprLoop(ref b, _, _) => {
|
||||
ExprKind::Loop(ref b, _, _) => {
|
||||
// Break can come from the inner loop so remove them.
|
||||
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 result = never_loop_block(b, main_loop_id);
|
||||
// Break can come from the inner loop so remove them.
|
||||
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);
|
||||
if arms.is_empty() {
|
||||
e
|
||||
|
@ -639,8 +639,8 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
|
|||
combine_seq(e, arms)
|
||||
}
|
||||
},
|
||||
ExprBlock(ref b, _) => never_loop_block(b, main_loop_id),
|
||||
ExprContinue(d) => {
|
||||
ExprKind::Block(ref b, _) => never_loop_block(b, main_loop_id),
|
||||
ExprKind::Continue(d) => {
|
||||
let id = d.target_id
|
||||
.expect("target id can only be missing in the presence of compilation errors");
|
||||
if id == main_loop_id {
|
||||
|
@ -649,22 +649,22 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
|
|||
NeverLoopResult::AlwaysBreak
|
||||
}
|
||||
},
|
||||
ExprBreak(_, _) => {
|
||||
ExprKind::Break(_, _) => {
|
||||
NeverLoopResult::AlwaysBreak
|
||||
},
|
||||
ExprRet(ref e) => {
|
||||
ExprKind::Ret(ref e) => {
|
||||
if let Some(ref e) = *e {
|
||||
combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)
|
||||
} else {
|
||||
NeverLoopResult::AlwaysBreak
|
||||
}
|
||||
},
|
||||
ExprStruct(_, _, None) |
|
||||
ExprYield(_) |
|
||||
ExprClosure(_, _, _, _, _) |
|
||||
ExprInlineAsm(_, _, _) |
|
||||
ExprPath(_) |
|
||||
ExprLit(_) => NeverLoopResult::Otherwise,
|
||||
ExprKind::Struct(_, _, None) |
|
||||
ExprKind::Yield(_) |
|
||||
ExprKind::Closure(_, _, _, _, _) |
|
||||
ExprKind::InlineAsm(_, _, _) |
|
||||
ExprKind::Path(_) |
|
||||
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 {
|
||||
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 path.segments.len() == 1;
|
||||
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 extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option<String> {
|
||||
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()),
|
||||
_ => 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,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if !is_slice_like(cx, ty) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let offset = match idx.node {
|
||||
ExprBinary(op, ref lhs, ref rhs) => match op.node {
|
||||
BinOp_::BiAdd => {
|
||||
ExprKind::Binary(op, ref lhs, ref rhs) => match op.node {
|
||||
BinOpKind::Add => {
|
||||
let offset_opt = if same_var(cx, lhs, var) {
|
||||
extract_offset(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)
|
||||
},
|
||||
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,
|
||||
},
|
||||
ExprPath(..) => if same_var(cx, idx, var) {
|
||||
ExprKind::Path(..) => if same_var(cx, idx, var) {
|
||||
Some(Offset::positive("0".into()))
|
||||
} else {
|
||||
None
|
||||
|
@ -810,7 +810,7 @@ fn fetch_cloned_fixed_offset_var<'a, 'tcx>(
|
|||
var: ast::NodeId,
|
||||
) -> Option<FixedOffsetVar> {
|
||||
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 args.len() == 1;
|
||||
if let Some(arg) = args.get(0);
|
||||
|
@ -832,7 +832,7 @@ fn get_indexed_assignments<'a, 'tcx>(
|
|||
e: &Expr,
|
||||
var: ast::NodeId,
|
||||
) -> 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)) {
|
||||
(Some(offset_left), Some(offset_right)) => {
|
||||
// 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 {
|
||||
ref stmts,
|
||||
ref expr,
|
||||
|
@ -859,8 +859,8 @@ fn get_indexed_assignments<'a, 'tcx>(
|
|||
stmts
|
||||
.iter()
|
||||
.map(|stmt| match stmt.node {
|
||||
Stmt_::StmtDecl(..) => None,
|
||||
Stmt_::StmtExpr(ref e, _node_id) | Stmt_::StmtSemi(ref e, _node_id) => Some(get_assignment(cx, e, var)),
|
||||
StmtKind::Decl(..) => None,
|
||||
StmtKind::Expr(ref e, _node_id) | StmtKind::Semi(ref e, _node_id) => Some(get_assignment(cx, e, var)),
|
||||
})
|
||||
.chain(
|
||||
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 {
|
||||
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 len_args.len() == 1;
|
||||
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 {
|
||||
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 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[0].ident.name == var;
|
||||
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) {
|
||||
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
|
||||
if args.len() == 1 {
|
||||
let method_name = &*method.ident.as_str();
|
||||
|
@ -1377,7 +1377,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
|
|||
MutMutable => "_mut",
|
||||
};
|
||||
let arg = match arg.node {
|
||||
ExprAddrOf(_, ref expr) => &**expr,
|
||||
ExprKind::AddrOf(_, ref expr) => &**expr,
|
||||
_ => 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> {
|
||||
if_chain! {
|
||||
if let ExprPath(ref qpath) = bound.node;
|
||||
if let ExprKind::Path(ref qpath) = bound.node;
|
||||
if let QPath::Resolved(None, _) = *qpath;
|
||||
then {
|
||||
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 {
|
||||
if_chain! {
|
||||
// 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 seqvar.segments.len() == 1;
|
||||
then {
|
||||
|
@ -1655,7 +1655,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
||||
if_chain! {
|
||||
// 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))
|
||||
|| (meth.ident.name == "index_mut" && match_trait_method(self.cx, expr, &paths::INDEX_MUT));
|
||||
if !self.check(&args[1], &args[0], expr);
|
||||
|
@ -1664,14 +1664,14 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
|
||||
if_chain! {
|
||||
// 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);
|
||||
then { return }
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
// 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 path.segments.len() == 1;
|
||||
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;
|
||||
match expr.node {
|
||||
ExprAssignOp(_, ref lhs, ref rhs) |
|
||||
ExprAssign(ref lhs, ref rhs) => {
|
||||
ExprKind::AssignOp(_, ref lhs, ref rhs) |
|
||||
ExprKind::Assign(ref lhs, ref rhs) => {
|
||||
self.prefer_mutable = true;
|
||||
self.visit_expr(lhs);
|
||||
self.prefer_mutable = false;
|
||||
self.visit_expr(rhs);
|
||||
},
|
||||
ExprAddrOf(mutbl, ref expr) => {
|
||||
ExprKind::AddrOf(mutbl, ref expr) => {
|
||||
if mutbl == MutMutable {
|
||||
self.prefer_mutable = true;
|
||||
}
|
||||
self.visit_expr(expr);
|
||||
},
|
||||
ExprCall(ref f, ref args) => {
|
||||
ExprKind::Call(ref f, ref args) => {
|
||||
self.visit_expr(f);
|
||||
for expr in args {
|
||||
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);
|
||||
}
|
||||
},
|
||||
ExprMethodCall(_, _, ref args) => {
|
||||
ExprKind::MethodCall(_, _, ref args) => {
|
||||
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) {
|
||||
self.prefer_mutable = false;
|
||||
|
@ -1809,8 +1809,8 @@ fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> {
|
|||
if block.stmts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
if let StmtDecl(ref decl, _) = block.stmts[0].node {
|
||||
if let DeclLocal(ref local) = decl.node {
|
||||
if let StmtKind::Decl(ref decl, _) = block.stmts[0].node {
|
||||
if let DeclKind::Local(ref local) = decl.node {
|
||||
if let Some(ref expr) = local.init {
|
||||
Some(expr)
|
||||
} else {
|
||||
|
@ -1829,8 +1829,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
|
|||
match block.expr {
|
||||
Some(ref expr) if block.stmts.is_empty() => Some(expr),
|
||||
None if !block.stmts.is_empty() => match block.stmts[0].node {
|
||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => Some(expr),
|
||||
StmtDecl(..) => None,
|
||||
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => Some(expr),
|
||||
StmtKind::Decl(..) => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
|
@ -1841,8 +1841,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
|
|||
/// passed expression. The expression may be within a block.
|
||||
fn is_simple_break_expr(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprBreak(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true,
|
||||
ExprBlock(ref b, _) => match extract_first_expr(b) {
|
||||
ExprKind::Break(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true,
|
||||
ExprKind::Block(ref b, _) => match extract_first_expr(b) {
|
||||
Some(subexpr) => is_simple_break_expr(subexpr),
|
||||
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);
|
||||
|
||||
match parent.node {
|
||||
ExprAssignOp(op, ref lhs, ref rhs) => {
|
||||
ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
||||
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 {
|
||||
VarState::Initial if self.depth == 0 => VarState::IncrOnce,
|
||||
_ => 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,
|
||||
ExprAddrOf(mutability, _) if mutability == MutMutable => *state = VarState::DontWarn,
|
||||
ExprKind::Assign(ref lhs, _) if lhs.id == expr.id => *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> {
|
||||
fn visit_decl(&mut self, decl: &'tcx Decl) {
|
||||
// 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 let PatKind::Binding(_, _, ident, _) = local.pat.node {
|
||||
self.name = Some(ident.name);
|
||||
|
@ -1955,7 +1955,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
|
|||
if self.state == VarState::DontWarn {
|
||||
return;
|
||||
}
|
||||
if expr == self.end_expr {
|
||||
if SpanlessEq::new(self.cx).eq_expr(&expr, self.end_expr) {
|
||||
self.past_loop = true;
|
||||
return;
|
||||
}
|
||||
|
@ -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 let Some(parent) = get_parent_expr(self.cx, expr) {
|
||||
match parent.node {
|
||||
ExprAssignOp(_, ref lhs, _) if lhs.id == expr.id => {
|
||||
ExprKind::AssignOp(_, ref lhs, _) if lhs.id == expr.id => {
|
||||
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 {
|
||||
VarState::Warn
|
||||
} else {
|
||||
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> {
|
||||
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);
|
||||
if let Def::Local(node_id) = path_res {
|
||||
return Some(node_id);
|
||||
|
@ -2016,14 +2016,14 @@ fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
|
|||
|
||||
fn is_loop(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprLoop(..) | ExprWhile(..) => true,
|
||||
ExprKind::Loop(..) | ExprKind::While(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_conditional(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprIf(..) | ExprMatch(..) => true,
|
||||
ExprKind::If(..) | ExprKind::Match(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -2053,7 +2053,7 @@ fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool
|
|||
}
|
||||
match cx.tcx.hir.find(parent) {
|
||||
Some(NodeExpr(expr)) => match expr.node {
|
||||
ExprLoop(..) | ExprWhile(..) => {
|
||||
ExprKind::Loop(..) | ExprKind::While(..) => {
|
||||
return true;
|
||||
},
|
||||
_ => (),
|
||||
|
@ -2111,7 +2111,7 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
|
|||
return;
|
||||
}
|
||||
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;
|
||||
},
|
||||
_ => walk_expr(self, expr),
|
||||
|
@ -2137,7 +2137,7 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
|
|||
}
|
||||
|
||||
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;
|
||||
if segments.len() == 1 {
|
||||
return Some(segments[0].ident.name);
|
||||
|
@ -2193,7 +2193,7 @@ struct VarCollectorVisitor<'a, 'tcx: 'a> {
|
|||
impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
|
||||
fn insert_def_id(&mut self, ex: &'tcx Expr) {
|
||||
if_chain! {
|
||||
if let ExprPath(ref qpath) = ex.node;
|
||||
if let ExprKind::Path(ref qpath) = ex.node;
|
||||
if let QPath::Resolved(None, _) = *qpath;
|
||||
let def = self.cx.tables.qpath_def(qpath, ex.hir_id);
|
||||
then {
|
||||
|
@ -2214,9 +2214,9 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
|
|||
impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr) {
|
||||
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
|
||||
ExprCall(..) | ExprMethodCall(..) => self.skip = true,
|
||||
ExprKind::Call(..) | ExprKind::MethodCall(..) => self.skip = true,
|
||||
|
||||
_ => walk_expr(self, ex),
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use rustc::hir::*;
|
|||
use rustc::ty;
|
||||
use syntax::ast;
|
||||
use crate::utils::{get_arg_ident, is_adjusted, iter_input_pats, match_qpath, match_trait_method, match_type,
|
||||
paths, remove_blocks, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
|
||||
paths, remove_blocks, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq};
|
||||
|
||||
/// **What it does:** Checks for mapping `clone()` over an iterator.
|
||||
///
|
||||
|
@ -30,10 +30,10 @@ pub struct Pass;
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
// 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 {
|
||||
match args[1].node {
|
||||
ExprClosure(_, ref decl, closure_eid, _, _) => {
|
||||
ExprKind::Closure(_, ref decl, closure_eid, _, _) => {
|
||||
let body = cx.tcx.hir.body(closure_eid);
|
||||
let closure_expr = remove_blocks(&body.value);
|
||||
if_chain! {
|
||||
|
@ -62,11 +62,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
}
|
||||
// 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" &&
|
||||
clone_args.len() == 1 &&
|
||||
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
|
||||
expr_eq_name(&clone_args[0], arg_ident)
|
||||
expr_eq_name(cx, &clone_args[0], arg_ident)
|
||||
{
|
||||
span_help_and_lint(cx, MAP_CLONE, expr.span, &format!(
|
||||
"you seem to be using .map() to clone the contents of an {}, consider \
|
||||
|
@ -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("_");
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
|
@ -98,9 +98,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
}
|
||||
|
||||
fn expr_eq_name(expr: &Expr, id: ast::Ident) -> bool {
|
||||
fn expr_eq_name(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool {
|
||||
match expr.node {
|
||||
ExprPath(QPath::Resolved(None, ref path)) => {
|
||||
ExprKind::Path(QPath::Resolved(None, ref path)) => {
|
||||
let arg_segment = [
|
||||
PathSegment {
|
||||
ident: id,
|
||||
|
@ -108,7 +108,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Ident) -> bool {
|
|||
infer_types: true,
|
||||
},
|
||||
];
|
||||
!path.is_global() && path.segments[..] == arg_segment
|
||||
!path.is_global() && SpanlessEq::new(cx).eq_path_segments(&path.segments[..], &arg_segment)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static s
|
|||
|
||||
fn only_derefs(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool {
|
||||
match expr.node {
|
||||
ExprUnary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => only_derefs(cx, subexpr, id),
|
||||
_ => expr_eq_name(expr, id),
|
||||
ExprKind::Unary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => only_derefs(cx, subexpr, id),
|
||||
_ => expr_eq_name(cx, expr, id),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::ty;
|
||||
use rustc_errors::{Applicability};
|
||||
use rustc_errors::Applicability;
|
||||
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::paths;
|
||||
|
@ -115,12 +115,12 @@ fn reduce_unit_expression<'a>(cx: &LateContext, expr: &'a hir::Expr) -> Option<S
|
|||
}
|
||||
|
||||
match expr.node {
|
||||
hir::ExprCall(_, _) |
|
||||
hir::ExprMethodCall(_, _, _) => {
|
||||
hir::ExprKind::Call(_, _) |
|
||||
hir::ExprKind::MethodCall(_, _, _) => {
|
||||
// Calls can't be reduced any more
|
||||
Some(expr.span)
|
||||
},
|
||||
hir::ExprBlock(ref block, _) => {
|
||||
hir::ExprKind::Block(ref block, _) => {
|
||||
match (&block.stmts[..], block.expr.as_ref()) {
|
||||
(&[], Some(inner_expr)) => {
|
||||
// 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,
|
||||
// reduce `{ X; }` to `X` or `X;`
|
||||
match inner_stmt.node {
|
||||
hir::StmtDecl(ref d, _) => Some(d.span),
|
||||
hir::StmtExpr(ref e, _) => Some(e.span),
|
||||
hir::StmtSemi(_, _) => Some(inner_stmt.span),
|
||||
hir::StmtKind::Decl(ref d, _) => Some(d.span),
|
||||
hir::StmtKind::Expr(ref e, _) => Some(e.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)> {
|
||||
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_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 `_`.
|
||||
fn let_binding_name(cx: &LateContext, var_arg: &hir::Expr) -> String {
|
||||
match &var_arg.node {
|
||||
hir::ExprField(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"),
|
||||
hir::ExprPath(_) => format!("_{}", snippet(cx, var_arg.span, "")),
|
||||
hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"),
|
||||
hir::ExprKind::Path(_) => format!("_{}", snippet(cx, var_arg.span, "")),
|
||||
_ => "_".to_string()
|
||||
}
|
||||
}
|
||||
|
@ -247,8 +247,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
return;
|
||||
}
|
||||
|
||||
if let hir::StmtSemi(ref expr, _) = stmt.node {
|
||||
if let hir::ExprMethodCall(_, _, _) = expr.node {
|
||||
if let hir::StmtKind::Semi(ref expr, _) = stmt.node {
|
||||
if let hir::ExprKind::MethodCall(_, _, _) = expr.node {
|
||||
if let Some(arglists) = method_chain_args(expr, &["map"]) {
|
||||
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) {
|
||||
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_match_bool(cx, ex, arms, expr);
|
||||
check_overlapping_arms(cx, ex, arms);
|
||||
check_wild_err_arm(cx, ex, arms);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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 = if is_unit_expr(els) {
|
||||
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`
|
||||
Some(els)
|
||||
} else {
|
||||
|
@ -221,7 +221,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
|||
}
|
||||
|
||||
fn check_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, els: Option<&Expr>) {
|
||||
if arms[1].pats[0].node == PatKind::Wild {
|
||||
if is_wild(&arms[1].pats[0]) {
|
||||
report_single_match_single_pattern(cx, ex, arms, expr, els);
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
|
|||
let path = match arms[1].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, ref inner, _) => {
|
||||
// contains any non wildcard patterns? e.g. Err(err)
|
||||
if inner.iter().any(|pat| pat.node != PatKind::Wild) {
|
||||
if !inner.iter().all(is_wild) {
|
||||
return;
|
||||
}
|
||||
print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))
|
||||
|
@ -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 {
|
||||
// no guards
|
||||
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 {
|
||||
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
|
||||
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
|
||||
|
@ -356,6 +356,13 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr,
|
|||
}
|
||||
}
|
||||
|
||||
fn is_wild(pat: &impl std::ops::Deref<Target = Pat>) -> bool {
|
||||
match pat.node {
|
||||
PatKind::Wild => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
|
||||
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
|
||||
if match_type(cx, ex_ty, &paths::RESULT) {
|
||||
|
@ -364,8 +371,8 @@ fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
|
|||
let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false));
|
||||
if_chain! {
|
||||
if path_str == "Err";
|
||||
if inner.iter().any(|pat| pat.node == PatKind::Wild);
|
||||
if let ExprBlock(ref block, _) = arm.body.node;
|
||||
if inner.iter().any(is_wild);
|
||||
if let ExprKind::Block(ref block, _) = arm.body.node;
|
||||
if is_panic_block(block);
|
||||
then {
|
||||
// `Err(_)` arm with `panic!` found
|
||||
|
@ -399,7 +406,7 @@ fn is_panic_block(block: &Block) -> bool {
|
|||
fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||
if has_only_ref_pats(arms) {
|
||||
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()));
|
||||
(
|
||||
"you don't need to add `&` to both the expression and the patterns",
|
||||
|
@ -533,8 +540,8 @@ fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {
|
|||
|
||||
fn is_unit_expr(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprTup(ref v) if v.is_empty() => true,
|
||||
ExprBlock(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true,
|
||||
ExprKind::Tup(ref v) if v.is_empty() => true,
|
||||
ExprKind::Block(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -554,10 +561,10 @@ fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
|
|||
if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
|
||||
if let PatKind::Binding(rb, _, ident, _) = pats[0].node;
|
||||
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
|
||||
if let ExprCall(ref e, ref args) = remove_blocks(&arm.body).node;
|
||||
if let ExprPath(ref some_path) = e.node;
|
||||
if let ExprKind::Call(ref e, ref args) = remove_blocks(&arm.body).node;
|
||||
if let ExprKind::Path(ref some_path) = e.node;
|
||||
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 path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
|
||||
then {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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};
|
||||
|
||||
/// **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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
if let ExprCall(ref path_expr, ref args) = e.node {
|
||||
if let ExprPath(ref qpath) = path_expr.node {
|
||||
if let ExprKind::Call(ref path_expr, ref args) = e.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 match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
|
||||
let forgot_ty = cx.tables.expr_ty(&args[0]);
|
||||
|
|
|
@ -10,7 +10,7 @@ use syntax::codemap::{Span, BytePos};
|
|||
use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self,
|
||||
is_self_ty, iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method,
|
||||
match_type, method_chain_args, match_var, return_ty, remove_blocks, same_tys, single_segment_path, snippet,
|
||||
span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
|
||||
span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sugg;
|
||||
use crate::consts::{constant, Constant};
|
||||
|
@ -718,7 +718,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
|
||||
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
|
||||
// GET_UNWRAP needs to be checked before general `UNWRAP` lints
|
||||
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 {
|
||||
expr,
|
||||
chain: lhs,
|
||||
other: rhs,
|
||||
eq: op.node == hir::BiEq,
|
||||
eq: op.node == hir::BinOpKind::Eq,
|
||||
};
|
||||
lint_binary_expr_with_method_call(cx, &mut info);
|
||||
},
|
||||
|
@ -813,15 +813,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
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) = 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 {
|
||||
if cx.access_levels.is_exported(implitem.id) {
|
||||
// check missing trait implementations
|
||||
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
|
||||
if name == method_name &&
|
||||
sig.decl.inputs.len() == n_args &&
|
||||
out_type.matches(&sig.decl.output) &&
|
||||
self_kind.matches(first_arg_ty, first_arg, self_ty, false, &implitem.generics) {
|
||||
out_type.matches(cx, &sig.decl.output) &&
|
||||
self_kind.matches(cx, first_arg_ty, first_arg, self_ty, false, &implitem.generics) {
|
||||
span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!(
|
||||
"defining a method called `{}` on this type; consider implementing \
|
||||
the `{}` trait or choosing a less ambiguous name", name, trait_name));
|
||||
|
@ -838,9 +838,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
if conv.check(&name.as_str());
|
||||
if !self_kinds
|
||||
.iter()
|
||||
.any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
|
||||
.any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
|
||||
then {
|
||||
let lint = if item.vis.node == hir::VisibilityKind::Public {
|
||||
let lint = if item.vis.node.is_pub() {
|
||||
WRONG_PUB_SELF_CONVENTION
|
||||
} else {
|
||||
WRONG_SELF_CONVENTION
|
||||
|
@ -889,7 +889,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name:
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
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 {
|
||||
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();
|
||||
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);
|
||||
}
|
||||
},
|
||||
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)
|
||||
},
|
||||
_ => {},
|
||||
|
@ -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.
|
||||
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>> {
|
||||
if let hir::ExprAddrOf(_, ref addr_of) = arg.node {
|
||||
if let hir::ExprCall(ref inner_fun, ref inner_args) = addr_of.node {
|
||||
if let hir::ExprKind::AddrOf(_, ref addr_of) = arg.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 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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
if let hir::ExprAddrOf(_, ref format_arg) = a.node {
|
||||
if let hir::ExprMatch(ref format_arg_expr, _, _) = format_arg.node {
|
||||
if let hir::ExprTup(ref format_arg_expr_tup) = format_arg_expr.node {
|
||||
if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node {
|
||||
if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.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();
|
||||
}
|
||||
}
|
||||
|
@ -1090,7 +1090,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n
|
|||
|
||||
if args.len() == 2 {
|
||||
match args[1].node {
|
||||
hir::ExprLit(_) => {},
|
||||
hir::ExprKind::Lit(_) => {},
|
||||
_ => 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) {
|
||||
hir::map::NodeExpr(parent) => match parent.node {
|
||||
// &*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
|
||||
hir::ExprMethodCall(..) => return,
|
||||
hir::ExprKind::MethodCall(..) => return,
|
||||
_ => {},
|
||||
}
|
||||
hir::map::NodeStmt(stmt) => {
|
||||
if let hir::StmtDecl(ref decl, _) = stmt.node {
|
||||
if let hir::DeclLocal(ref loc) = decl.node {
|
||||
if let hir::StmtKind::Decl(ref decl, _) = stmt.node {
|
||||
if let hir::DeclKind::Local(ref loc) = decl.node {
|
||||
if let hir::PatKind::Ref(..) = loc.pat.node {
|
||||
// let ref y = *x borrows x, let ref y = x.clone() does not
|
||||
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) {
|
||||
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 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 match_def_path(cx.tcx, did, &paths::CSTRING_NEW);
|
||||
then {
|
||||
|
@ -1274,18 +1274,18 @@ fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::E
|
|||
fn check_fold_with_op(
|
||||
cx: &LateContext,
|
||||
fold_args: &[hir::Expr],
|
||||
op: hir::BinOp_,
|
||||
op: hir::BinOpKind,
|
||||
replacement_method_name: &str,
|
||||
replacement_has_args: bool) {
|
||||
|
||||
if_chain! {
|
||||
// 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_expr = remove_blocks(&closure_body.value);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
match fold_args[1].node {
|
||||
hir::ExprLit(ref lit) => {
|
||||
hir::ExprKind::Lit(ref lit) => {
|
||||
match lit.node {
|
||||
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(
|
||||
cx, fold_args, hir::BinOp_::BiAnd, "all", true
|
||||
cx, fold_args, hir::BinOpKind::And, "all", true
|
||||
),
|
||||
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(
|
||||
cx, fold_args, hir::BinOp_::BiMul, "product", false
|
||||
cx, fold_args, hir::BinOpKind::Mul, "product", false
|
||||
),
|
||||
_ => 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])) {
|
||||
sugg::Sugg::hir_opt(cx, &args[0]).map(|sugg| sugg.addr())
|
||||
} 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]) {
|
||||
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
|
||||
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)
|
||||
} else {
|
||||
false
|
||||
|
@ -1790,9 +1790,9 @@ fn lint_chars_cmp<'a, 'tcx>(
|
|||
) -> bool {
|
||||
if_chain! {
|
||||
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 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 segment.ident.name == "Some";
|
||||
then {
|
||||
|
@ -1844,7 +1844,7 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
|
|||
) -> bool {
|
||||
if_chain! {
|
||||
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;
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
|
@ -2030,6 +2030,7 @@ enum SelfKind {
|
|||
impl SelfKind {
|
||||
fn matches(
|
||||
self,
|
||||
cx: &LateContext,
|
||||
ty: &hir::Ty,
|
||||
arg: &hir::Arg,
|
||||
self_ty: &hir::Ty,
|
||||
|
@ -2047,7 +2048,7 @@ impl SelfKind {
|
|||
// `Self`, `&mut Self`,
|
||||
// and `Box<Self>`, including the equivalent types with `Foo`.
|
||||
|
||||
let is_actually_self = |ty| is_self_ty(ty) || ty == self_ty;
|
||||
let is_actually_self = |ty| is_self_ty(ty) || SpanlessEq::new(cx).eq_ty(ty, self_ty);
|
||||
if is_self(arg) {
|
||||
match self {
|
||||
SelfKind::Value => is_actually_self(ty),
|
||||
|
@ -2056,7 +2057,7 @@ impl SelfKind {
|
|||
return true;
|
||||
}
|
||||
match ty.node {
|
||||
hir::TyRptr(_, ref mt_ty) => {
|
||||
hir::TyKind::Rptr(_, ref mt_ty) => {
|
||||
let mutability_match = if self == SelfKind::Ref {
|
||||
mt_ty.mutbl == hir::MutImmutable
|
||||
} else {
|
||||
|
@ -2127,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 {
|
||||
match (&ty.node, &self_ty.node) {
|
||||
(
|
||||
&hir::TyPath(hir::QPath::Resolved(_, ref ty_path)),
|
||||
&hir::TyPath(hir::QPath::Resolved(_, ref self_ty_path)),
|
||||
&hir::TyKind::Path(hir::QPath::Resolved(_, ref ty_path)),
|
||||
&hir::TyKind::Path(hir::QPath::Resolved(_, ref self_ty_path)),
|
||||
) => ty_path
|
||||
.segments
|
||||
.iter()
|
||||
|
@ -2139,7 +2140,7 @@ fn is_ty(ty: &hir::Ty, self_ty: &hir::Ty) -> bool {
|
|||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
None
|
||||
|
@ -2173,20 +2174,21 @@ enum OutType {
|
|||
}
|
||||
|
||||
impl OutType {
|
||||
fn matches(self, 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::TyKind::Tup(vec![].into()));
|
||||
match (self, ty) {
|
||||
(OutType::Unit, &hir::DefaultReturn(_)) => true,
|
||||
(OutType::Unit, &hir::Return(ref ty)) if ty.node == hir::TyTup(vec![].into()) => true,
|
||||
(OutType::Unit, &hir::Return(ref ty)) if is_unit(ty) => true,
|
||||
(OutType::Bool, &hir::Return(ref ty)) if is_bool(ty) => true,
|
||||
(OutType::Any, &hir::Return(ref ty)) if ty.node != hir::TyTup(vec![].into()) => true,
|
||||
(OutType::Ref, &hir::Return(ref ty)) => matches!(ty.node, hir::TyRptr(_, _)),
|
||||
(OutType::Any, &hir::Return(ref ty)) if !is_unit(ty) => true,
|
||||
(OutType::Ref, &hir::Return(ref ty)) => matches!(ty.node, hir::TyKind::Rptr(_, _)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"])
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -66,8 +66,8 @@ enum MinMax {
|
|||
}
|
||||
|
||||
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 ExprPath(ref qpath) = path.node {
|
||||
if let ExprKind::Call(ref path, ref args) = expr.node {
|
||||
if let ExprKind::Path(ref qpath) = path.node {
|
||||
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) {
|
||||
fetch_const(cx, args, MinMax::Min)
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc::ty;
|
|||
use syntax::codemap::{ExpnFormat, Span};
|
||||
use crate::utils::{get_item_name, get_parent_expr, implements_trait, in_constant, in_macro, is_integer_literal,
|
||||
iter_input_pats, last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint,
|
||||
span_lint_and_then, walk_ptrs_ty};
|
||||
span_lint_and_then, walk_ptrs_ty, SpanlessEq};
|
||||
use crate::utils::sugg::Sugg;
|
||||
use syntax::ast::{LitKind, CRATE_NODE_ID};
|
||||
use crate::consts::{constant, Constant};
|
||||
|
@ -269,8 +269,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
|
||||
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, s: &'tcx Stmt) {
|
||||
if_chain! {
|
||||
if let StmtDecl(ref d, _) = s.node;
|
||||
if let DeclLocal(ref l) = d.node;
|
||||
if let StmtKind::Decl(ref d, _) = s.node;
|
||||
if let DeclKind::Local(ref l) = d.node;
|
||||
if let PatKind::Binding(an, _, i, None) = l.pat.node;
|
||||
if let Some(ref init) = l.init;
|
||||
then {
|
||||
|
@ -303,9 +303,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
};
|
||||
if_chain! {
|
||||
if let StmtSemi(ref expr, _) = s.node;
|
||||
if let Expr_::ExprBinary(ref binop, ref a, ref b) = expr.node;
|
||||
if binop.node == BiAnd || binop.node == BiOr;
|
||||
if let StmtKind::Semi(ref expr, _) = s.node;
|
||||
if let ExprKind::Binary(ref binop, ref a, ref b) = expr.node;
|
||||
if binop.node == BinOpKind::And || binop.node == BinOpKind::Or;
|
||||
if let Some(sugg) = Sugg::hir_opt(cx, a);
|
||||
then {
|
||||
span_lint_and_then(cx,
|
||||
|
@ -313,7 +313,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
s.span,
|
||||
"boolean short circuit operator in statement may be clearer using an explicit test",
|
||||
|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",
|
||||
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) {
|
||||
match expr.node {
|
||||
ExprCast(ref e, ref ty) => {
|
||||
ExprKind::Cast(ref e, ref ty) => {
|
||||
check_cast(cx, expr.span, e, ty);
|
||||
return;
|
||||
},
|
||||
ExprBinary(ref cmp, ref left, ref right) => {
|
||||
ExprKind::Binary(ref cmp, ref left, ref right) => {
|
||||
let op = cmp.node;
|
||||
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);
|
||||
}
|
||||
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_to_owned(cx, left, right);
|
||||
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) {
|
||||
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.");
|
||||
});
|
||||
} 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");
|
||||
}
|
||||
},
|
||||
|
@ -378,7 +378,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
return;
|
||||
}
|
||||
let binding = match expr.node {
|
||||
ExprPath(ref qpath) => {
|
||||
ExprKind::Path(ref qpath) => {
|
||||
let binding = last_path_segment(qpath).ident.as_str();
|
||||
if binding.starts_with('_') &&
|
||||
!binding.starts_with("__") &&
|
||||
|
@ -392,7 +392,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
None
|
||||
}
|
||||
},
|
||||
ExprField(_, ident) => {
|
||||
ExprKind::Field(_, ident) => {
|
||||
let name = ident.as_str();
|
||||
if name.starts_with('_') && !name.starts_with("__") {
|
||||
Some(name)
|
||||
|
@ -418,7 +418,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
|
||||
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
|
||||
if let PatKind::Binding(_, _, ident, Some(ref right)) = pat.node {
|
||||
if right.node == PatKind::Wild {
|
||||
if let PatKind::Wild = right.node {
|
||||
span_lint(
|
||||
cx,
|
||||
REDUNDANT_PATTERN,
|
||||
|
@ -467,14 +467,14 @@ fn is_float(cx: &LateContext, expr: &Expr) -> bool {
|
|||
|
||||
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) {
|
||||
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) {
|
||||
(cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, ".."))
|
||||
} else {
|
||||
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"]) {
|
||||
(cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, ".."))
|
||||
} 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);
|
||||
if parent_impl != CRATE_NODE_ID {
|
||||
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 {
|
||||
// we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise
|
||||
// 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 {
|
||||
if let Some(parent) = get_parent_expr(cx, expr) {
|
||||
match parent.node {
|
||||
ExprAssign(_, ref rhs) | ExprAssignOp(_, _, ref rhs) => **rhs == *expr,
|
||||
ExprKind::Assign(_, ref rhs) | ExprKind::AssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr),
|
||||
_ => is_used(cx, parent),
|
||||
}
|
||||
} 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) {
|
||||
if_chain! {
|
||||
if let TyPtr(MutTy { mutbl, .. }) = ty.node;
|
||||
if let ExprLit(ref lit) = e.node;
|
||||
if let TyKind::Ptr(MutTy { mutbl, .. }) = ty.node;
|
||||
if let ExprKind::Lit(ref lit) = e.node;
|
||||
if let LitKind::Int(value, ..) = lit.node;
|
||||
if value == 0;
|
||||
if !in_constant(cx, e.id);
|
||||
|
|
|
@ -213,7 +213,7 @@ impl EarlyLintPass for MiscEarly {
|
|||
.name;
|
||||
|
||||
for field in pfields {
|
||||
if field.node.pat.node == PatKind::Wild {
|
||||
if let PatKind::Wild = field.node.pat.node {
|
||||
wilds += 1;
|
||||
}
|
||||
}
|
||||
|
@ -231,14 +231,15 @@ impl EarlyLintPass for MiscEarly {
|
|||
let mut normal = vec![];
|
||||
|
||||
for field in pfields {
|
||||
if field.node.pat.node != PatKind::Wild {
|
||||
if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) {
|
||||
match field.node.pat.node {
|
||||
PatKind::Wild => {},
|
||||
_ => if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) {
|
||||
normal.push(n);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
for field in pfields {
|
||||
if field.node.pat.node == PatKind::Wild {
|
||||
if let PatKind::Wild = field.node.pat.node {
|
||||
wilds -= 1;
|
||||
if wilds > 0 {
|
||||
span_lint(
|
||||
|
|
|
@ -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) {
|
||||
let desc = match it.node {
|
||||
hir::ItemConst(..) => "a constant",
|
||||
hir::ItemEnum(..) => "an enum",
|
||||
hir::ItemFn(..) => {
|
||||
hir::ItemKind::Const(..) => "a constant",
|
||||
hir::ItemKind::Enum(..) => "an enum",
|
||||
hir::ItemKind::Fn(..) => {
|
||||
// ignore main()
|
||||
if it.name == "main" {
|
||||
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"
|
||||
},
|
||||
hir::ItemMod(..) => "a module",
|
||||
hir::ItemStatic(..) => "a static",
|
||||
hir::ItemStruct(..) => "a struct",
|
||||
hir::ItemTrait(..) => "a trait",
|
||||
hir::ItemTraitAlias(..) => "a trait alias",
|
||||
hir::ItemGlobalAsm(..) => "an assembly blob",
|
||||
hir::ItemTy(..) => "a type alias",
|
||||
hir::ItemUnion(..) => "a union",
|
||||
hir::ItemExistential(..) => "an existential type",
|
||||
hir::ItemExternCrate(..) |
|
||||
hir::ItemForeignMod(..) |
|
||||
hir::ItemImpl(..) |
|
||||
hir::ItemUse(..) => return,
|
||||
hir::ItemKind::Mod(..) => "a module",
|
||||
hir::ItemKind::Static(..) => "a static",
|
||||
hir::ItemKind::Struct(..) => "a struct",
|
||||
hir::ItemKind::Trait(..) => "a trait",
|
||||
hir::ItemKind::TraitAlias(..) => "a trait alias",
|
||||
hir::ItemKind::GlobalAsm(..) => "an assembly blob",
|
||||
hir::ItemKind::Ty(..) => "a type alias",
|
||||
hir::ItemKind::Union(..) => "a union",
|
||||
hir::ItemKind::Existential(..) => "an existential type",
|
||||
hir::ItemKind::ExternCrate(..) |
|
||||
hir::ItemKind::ForeignMod(..) |
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Use(..) => return,
|
||||
};
|
||||
|
||||
self.check_missing_docs_attrs(cx, &it.attrs, it.span, desc);
|
||||
|
|
|
@ -108,11 +108,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
|
|||
return;
|
||||
}
|
||||
match it.node {
|
||||
hir::ItemFn(..) => {
|
||||
hir::ItemKind::Fn(..) => {
|
||||
let desc = "a function";
|
||||
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) => {
|
||||
// note: we need to check if the trait is exported so we can't use
|
||||
// `LateLintPass::check_trait_item` here.
|
||||
|
@ -134,20 +134,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
|
|||
}
|
||||
}
|
||||
}
|
||||
hir::ItemConst(..) |
|
||||
hir::ItemEnum(..) |
|
||||
hir::ItemMod(..) |
|
||||
hir::ItemStatic(..) |
|
||||
hir::ItemStruct(..) |
|
||||
hir::ItemTraitAlias(..) |
|
||||
hir::ItemGlobalAsm(..) |
|
||||
hir::ItemTy(..) |
|
||||
hir::ItemUnion(..) |
|
||||
hir::ItemExistential(..) |
|
||||
hir::ItemExternCrate(..) |
|
||||
hir::ItemForeignMod(..) |
|
||||
hir::ItemImpl(..) |
|
||||
hir::ItemUse(..) => {},
|
||||
hir::ItemKind::Const(..) |
|
||||
hir::ItemKind::Enum(..) |
|
||||
hir::ItemKind::Mod(..) |
|
||||
hir::ItemKind::Static(..) |
|
||||
hir::ItemKind::Struct(..) |
|
||||
hir::ItemKind::TraitAlias(..) |
|
||||
hir::ItemKind::GlobalAsm(..) |
|
||||
hir::ItemKind::Ty(..) |
|
||||
hir::ItemKind::Union(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::ExternCrate(..) |
|
||||
hir::ItemKind::ForeignMod(..) |
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Use(..) => {},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
|
|||
// Let's ignore the generated code.
|
||||
intravisit::walk_expr(self, arg);
|
||||
intravisit::walk_expr(self, body);
|
||||
} else if let hir::ExprAddrOf(hir::MutMutable, ref e) = expr.node {
|
||||
if let hir::ExprAddrOf(hir::MutMutable, _) = e.node {
|
||||
} else if let hir::ExprKind::AddrOf(hir::MutMutable, ref e) = expr.node {
|
||||
if let hir::ExprKind::AddrOf(hir::MutMutable, _) = e.node {
|
||||
span_lint(
|
||||
self.cx,
|
||||
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) {
|
||||
if let hir::TyRptr(
|
||||
if let hir::TyKind::Rptr(
|
||||
_,
|
||||
hir::MutTy {
|
||||
ty: ref pty,
|
||||
|
@ -95,7 +95,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
|
|||
},
|
||||
) = ty.node
|
||||
{
|
||||
if let hir::TyRptr(
|
||||
if let hir::TyKind::Rptr(
|
||||
_,
|
||||
hir::MutTy {
|
||||
mutbl: hir::MutMutable,
|
||||
|
|
|
@ -36,7 +36,7 @@ impl LintPass for UnnecessaryMutPassed {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
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(
|
||||
cx,
|
||||
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)),
|
||||
);
|
||||
},
|
||||
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 substs = cx.tables.node_substs(e.hir_id);
|
||||
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 {
|
||||
mutbl: MutImmutable,
|
||||
..
|
||||
}) => if let ExprAddrOf(MutMutable, _) = argument.node {
|
||||
}) => if let ExprKind::AddrOf(MutMutable, _) = argument.node {
|
||||
span_lint(
|
||||
cx,
|
||||
UNNECESSARY_MUT_PASSED,
|
||||
|
|
|
@ -60,7 +60,7 @@ impl LintPass for NeedlessBool {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
use self::Expression::*;
|
||||
if let 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 snip = Sugg::hir(cx, pred, "<predicate>");
|
||||
let snip = if not { !snip } else { snip };
|
||||
|
@ -80,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
|
|||
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)) {
|
||||
(RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => {
|
||||
span_lint(
|
||||
|
@ -105,7 +105,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
|
|||
_ => (),
|
||||
}
|
||||
} 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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
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)) {
|
||||
(Bool(true), Other) => {
|
||||
let hint = snippet(cx, right_side.span, "..").into_owned();
|
||||
|
@ -184,8 +184,8 @@ enum Expression {
|
|||
fn fetch_bool_block(block: &Block) -> Expression {
|
||||
match (&*block.stmts, block.expr.as_ref()) {
|
||||
(&[], Some(e)) => fetch_bool_expr(&**e),
|
||||
(&[ref e], None) => if let StmtSemi(ref e, _) = e.node {
|
||||
if let ExprRet(_) = e.node {
|
||||
(&[ref e], None) => if let StmtKind::Semi(ref e, _) = e.node {
|
||||
if let ExprKind::Ret(_) = e.node {
|
||||
fetch_bool_expr(&**e)
|
||||
} else {
|
||||
Expression::Other
|
||||
|
@ -199,13 +199,13 @@ fn fetch_bool_block(block: &Block) -> Expression {
|
|||
|
||||
fn fetch_bool_expr(expr: &Expr) -> Expression {
|
||||
match expr.node {
|
||||
ExprBlock(ref block, _) => fetch_bool_block(block),
|
||||
ExprLit(ref lit_ptr) => if let LitKind::Bool(value) = lit_ptr.node {
|
||||
ExprKind::Block(ref block, _) => fetch_bool_block(block),
|
||||
ExprKind::Lit(ref lit_ptr) => if let LitKind::Bool(value) = lit_ptr.node {
|
||||
Expression::Bool(value)
|
||||
} else {
|
||||
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::Other,
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! This lint is **warn** by default
|
||||
|
||||
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::adjustment::{Adjust, Adjustment};
|
||||
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) {
|
||||
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 {
|
||||
for adj3 in cx.tables.expr_adjustments(e).windows(3) {
|
||||
if let [Adjustment {
|
||||
|
|
|
@ -88,8 +88,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
|
||||
// Exclude non-inherent impls
|
||||
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
|
||||
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) |
|
||||
ItemTrait(..))
|
||||
if matches!(item.node, ItemKind::Impl(_, _, _, _, Some(_), _, _) |
|
||||
ItemKind::Trait(..))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
if match_type(cx, ty, &paths::VEC);
|
||||
if let Some(clone_spans) =
|
||||
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()
|
||||
.find(|seg| seg.ident.name == "Vec")
|
||||
.and_then(|ps| ps.args.as_ref())
|
||||
|
@ -339,7 +339,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||
match node {
|
||||
map::Node::NodeExpr(e) => {
|
||||
// `match` and `if let`
|
||||
if let ExprMatch(ref c, ..) = e.node {
|
||||
if let ExprKind::Match(ref c, ..) = e.node {
|
||||
self.spans_need_deref
|
||||
.entry(vid)
|
||||
.or_insert_with(HashSet::new)
|
||||
|
@ -350,8 +350,8 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||
map::Node::NodeStmt(s) => {
|
||||
// `let <pat> = x;`
|
||||
if_chain! {
|
||||
if let StmtDecl(ref decl, _) = s.node;
|
||||
if let DeclLocal(ref local) = decl.node;
|
||||
if let StmtKind::Decl(ref decl, _) = s.node;
|
||||
if let DeclKind::Local(ref local) = decl.node;
|
||||
then {
|
||||
self.spans_need_deref
|
||||
.entry(vid)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty;
|
||||
use rustc::hir::{Expr, ExprStruct};
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use crate::utils::span_lint;
|
||||
|
||||
/// **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 {
|
||||
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);
|
||||
if let ty::TyAdt(def, _) = ty.sty {
|
||||
if fields.len() == def.non_enum_variant().fields.len() {
|
||||
|
|
|
@ -18,20 +18,20 @@ use crate::utils::{self, paths, span_lint, in_external_macro};
|
|||
///
|
||||
/// ```rust
|
||||
/// use core::cmp::Ordering;
|
||||
///
|
||||
///
|
||||
/// // Bad
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
///
|
||||
/// let _not_less_or_equal = !(a <= b);
|
||||
///
|
||||
/// // Good
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
///
|
||||
/// let _not_less_or_equal = match a.partial_cmp(&b) {
|
||||
/// None | Some(Ordering::Greater) => true,
|
||||
/// _ => false,
|
||||
/// _ => false,
|
||||
/// };
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
|
@ -54,9 +54,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd {
|
|||
if_chain! {
|
||||
|
||||
if !in_external_macro(cx, expr.span);
|
||||
if let Expr_::ExprUnary(UnOp::UnNot, ref inner) = expr.node;
|
||||
if let Expr_::ExprBinary(ref op, ref left, _) = inner.node;
|
||||
if let BinOp_::BiLe | BinOp_::BiGe | BinOp_::BiLt | BinOp_::BiGt = op.node;
|
||||
if let ExprKind::Unary(UnOp::UnNot, ref inner) = expr.node;
|
||||
if let ExprKind::Binary(ref op, ref left, _) = inner.node;
|
||||
if let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node;
|
||||
|
||||
then {
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ impl LintPass for NegMultiply {
|
|||
#[allow(match_same_arms)]
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
|
||||
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) {
|
||||
(&ExprUnary(..), &ExprUnary(..)) => (),
|
||||
(&ExprUnary(UnNeg, ref lit), _) => check_mul(cx, e.span, lit, r),
|
||||
(_, &ExprUnary(UnNeg, ref lit)) => check_mul(cx, e.span, lit, l),
|
||||
(&ExprKind::Unary(..), &ExprKind::Unary(..)) => (),
|
||||
(&ExprKind::Unary(UnNeg, ref lit), _) => check_mul(cx, e.span, lit, r),
|
||||
(_, &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) {
|
||||
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 val == 1;
|
||||
if cx.tables.expr_ty(exp).is_integral();
|
||||
|
|
|
@ -89,7 +89,7 @@ impl LintPass for NewWithoutDefault {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
|
||||
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 {
|
||||
if let hir::AssociatedItemKind::Method { has_self: false } = assoc_item.kind {
|
||||
let impl_item = cx.tcx.hir.impl_item(assoc_item.id);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
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 std::ops::Deref;
|
||||
|
||||
|
@ -45,26 +45,26 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
|
|||
return false;
|
||||
}
|
||||
match expr.node {
|
||||
Expr_::ExprLit(..) | Expr_::ExprClosure(.., _) => true,
|
||||
Expr_::ExprPath(..) => !has_drop(cx, expr),
|
||||
Expr_::ExprIndex(ref a, ref b) | Expr_::ExprBinary(_, ref a, ref b) => {
|
||||
ExprKind::Lit(..) | ExprKind::Closure(.., _) => true,
|
||||
ExprKind::Path(..) => !has_drop(cx, expr),
|
||||
ExprKind::Index(ref a, ref b) | ExprKind::Binary(_, ref a, ref 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)),
|
||||
Expr_::ExprRepeat(ref inner, _) |
|
||||
Expr_::ExprCast(ref inner, _) |
|
||||
Expr_::ExprType(ref inner, _) |
|
||||
Expr_::ExprUnary(_, ref inner) |
|
||||
Expr_::ExprField(ref inner, _) |
|
||||
Expr_::ExprAddrOf(_, ref inner) |
|
||||
Expr_::ExprBox(ref inner) => has_no_effect(cx, inner),
|
||||
Expr_::ExprStruct(_, ref fields, ref base) => {
|
||||
ExprKind::Array(ref v) | ExprKind::Tup(ref v) => v.iter().all(|val| has_no_effect(cx, val)),
|
||||
ExprKind::Repeat(ref inner, _) |
|
||||
ExprKind::Cast(ref inner, _) |
|
||||
ExprKind::Type(ref inner, _) |
|
||||
ExprKind::Unary(_, ref inner) |
|
||||
ExprKind::Field(ref inner, _) |
|
||||
ExprKind::AddrOf(_, ref inner) |
|
||||
ExprKind::Box(ref inner) => has_no_effect(cx, inner),
|
||||
ExprKind::Struct(_, ref fields, ref 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),
|
||||
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);
|
||||
match def {
|
||||
Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..) => {
|
||||
|
@ -75,7 +75,7 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
|
|||
} else {
|
||||
false
|
||||
},
|
||||
Expr_::ExprBlock(ref block, _) => {
|
||||
ExprKind::Block(ref block, _) => {
|
||||
block.stmts.is_empty() && if let Some(ref expr) = block.expr {
|
||||
has_no_effect(cx, expr)
|
||||
} else {
|
||||
|
@ -97,7 +97,7 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
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) {
|
||||
span_lint(cx, NO_EFFECT, stmt.span, "statement with no effect");
|
||||
} 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;
|
||||
}
|
||||
match expr.node {
|
||||
Expr_::ExprIndex(ref a, ref b) => Some(vec![&**a, &**b]),
|
||||
Expr_::ExprBinary(ref binop, ref a, ref b) if binop.node != BiAnd && binop.node != BiOr => {
|
||||
ExprKind::Index(ref a, ref b) => Some(vec![&**a, &**b]),
|
||||
ExprKind::Binary(ref binop, ref a, ref b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {
|
||||
Some(vec![&**a, &**b])
|
||||
},
|
||||
Expr_::ExprArray(ref v) | Expr_::ExprTup(ref v) => Some(v.iter().collect()),
|
||||
Expr_::ExprRepeat(ref inner, _) |
|
||||
Expr_::ExprCast(ref inner, _) |
|
||||
Expr_::ExprType(ref inner, _) |
|
||||
Expr_::ExprUnary(_, ref inner) |
|
||||
Expr_::ExprField(ref inner, _) |
|
||||
Expr_::ExprAddrOf(_, ref inner) |
|
||||
Expr_::ExprBox(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
|
||||
Expr_::ExprStruct(_, ref fields, ref base) => if has_drop(cx, expr) {
|
||||
ExprKind::Array(ref v) | ExprKind::Tup(ref v) => Some(v.iter().collect()),
|
||||
ExprKind::Repeat(ref inner, _) |
|
||||
ExprKind::Cast(ref inner, _) |
|
||||
ExprKind::Type(ref inner, _) |
|
||||
ExprKind::Unary(_, ref inner) |
|
||||
ExprKind::Field(ref inner, _) |
|
||||
ExprKind::AddrOf(_, ref inner) |
|
||||
ExprKind::Box(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
|
||||
ExprKind::Struct(_, ref fields, ref base) => if has_drop(cx, expr) {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
|
@ -156,7 +156,7 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
|
|||
.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);
|
||||
match def {
|
||||
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 {
|
||||
None
|
||||
},
|
||||
Expr_::ExprBlock(ref block, _) => {
|
||||
ExprKind::Block(ref block, _) => {
|
||||
if block.stmts.is_empty() {
|
||||
block.expr.as_ref().and_then(|e| {
|
||||
match block.rules {
|
||||
|
|
|
@ -164,7 +164,7 @@ impl LintPass for NonCopyConst {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
||||
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);
|
||||
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 = cx.tcx.hir.expect_item(item_node_id);
|
||||
// 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);
|
||||
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) {
|
||||
if let ExprPath(qpath) = &expr.node {
|
||||
if let ExprKind::Path(qpath) = &expr.node {
|
||||
// Only lint if we use the const item inside a function.
|
||||
if in_constant(cx, expr.id) {
|
||||
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) {
|
||||
match &parent_expr.node {
|
||||
ExprAddrOf(..) => {
|
||||
ExprKind::AddrOf(..) => {
|
||||
// `&e` => `e` must be referenced
|
||||
needs_check_adjustment = false;
|
||||
}
|
||||
ExprField(..) => {
|
||||
ExprKind::Field(..) => {
|
||||
dereferenced_expr = parent_expr;
|
||||
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)`,
|
||||
// meaning `e` must be referenced.
|
||||
// no need to go further up since a method call is involved now.
|
||||
needs_check_adjustment = false;
|
||||
break;
|
||||
}
|
||||
ExprUnary(UnDeref, _) => {
|
||||
ExprKind::Unary(UnDeref, _) => {
|
||||
// `*e` => desugared to `*Deref::deref(&e)`,
|
||||
// meaning `e` must be referenced.
|
||||
// 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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
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 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 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 syntax::ast::LitKind;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
|
@ -33,7 +33,7 @@ impl LintPass for NonSensical {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSensical {
|
||||
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]));
|
||||
if path.ident.name == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
||||
let mut options = Vec::new();
|
||||
|
@ -61,13 +61,13 @@ enum OpenOption {
|
|||
}
|
||||
|
||||
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]));
|
||||
|
||||
// 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 {
|
||||
let argument_option = match arguments[1].node {
|
||||
ExprLit(ref span) => {
|
||||
ExprKind::Lit(ref span) => {
|
||||
if let Spanned {
|
||||
node: LitKind::Bool(lit),
|
||||
..
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::hir::*;
|
||||
use crate::utils::span_lint;
|
||||
use crate::utils::{span_lint, SpanlessEq};
|
||||
|
||||
/// **What it does:** Detects classic underflow/overflow checks.
|
||||
///
|
||||
|
@ -31,24 +31,25 @@ impl LintPass for OverflowCheckConditional {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
|
||||
// a + b < a, a > a + b, a < a - b, a - b > a
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
let eq = |l, r| SpanlessEq::new(cx).eq_path_segment(l, r);
|
||||
if_chain! {
|
||||
if let Expr_::ExprBinary(ref op, ref first, ref second) = expr.node;
|
||||
if let Expr_::ExprBinary(ref op2, ref ident1, ref ident2) = first.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node;
|
||||
if path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0];
|
||||
if let ExprKind::Binary(ref op, ref first, ref second) = expr.node;
|
||||
if let ExprKind::Binary(ref op2, ref ident1, ref ident2) = first.node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path1)) = ident1.node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.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 cx.tables.expr_ty(ident1).is_integral();
|
||||
if cx.tables.expr_ty(ident2).is_integral();
|
||||
then {
|
||||
if let BinOp_::BiLt = op.node {
|
||||
if let BinOp_::BiAdd = op2.node {
|
||||
if let BinOpKind::Lt = op.node {
|
||||
if let BinOpKind::Add = op2.node {
|
||||
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
|
||||
"You are trying to use classic C overflow conditions that will fail in Rust.");
|
||||
}
|
||||
}
|
||||
if let BinOp_::BiGt = op.node {
|
||||
if let BinOp_::BiSub = op2.node {
|
||||
if let BinOpKind::Gt = op.node {
|
||||
if let BinOpKind::Sub = op2.node {
|
||||
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
|
||||
"You are trying to use classic C underflow conditions that will fail in Rust.");
|
||||
}
|
||||
|
@ -57,23 +58,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
|
|||
}
|
||||
|
||||
if_chain! {
|
||||
if let Expr_::ExprBinary(ref op, ref first, ref second) = expr.node;
|
||||
if let Expr_::ExprBinary(ref op2, ref ident1, ref ident2) = second.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node;
|
||||
if path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0];
|
||||
if let ExprKind::Binary(ref op, ref first, ref second) = expr.node;
|
||||
if let ExprKind::Binary(ref op2, ref ident1, ref ident2) = second.node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path1)) = ident1.node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.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 cx.tables.expr_ty(ident1).is_integral();
|
||||
if cx.tables.expr_ty(ident2).is_integral();
|
||||
then {
|
||||
if let BinOp_::BiGt = op.node {
|
||||
if let BinOp_::BiAdd = op2.node {
|
||||
if let BinOpKind::Gt = op.node {
|
||||
if let BinOpKind::Add = op2.node {
|
||||
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
|
||||
"You are trying to use classic C overflow conditions that will fail in Rust.");
|
||||
}
|
||||
}
|
||||
if let BinOp_::BiLt = op.node {
|
||||
if let BinOp_::BiSub = op2.node {
|
||||
if let BinOpKind::Lt = op.node {
|
||||
if let BinOpKind::Sub = op2.node {
|
||||
span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
|
||||
"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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
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 ExprCall(ref fun, ref params) = ex.node;
|
||||
if let ExprPath(ref qpath) = fun.node;
|
||||
if let ExprKind::Call(ref fun, ref params) = ex.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 match_def_path(cx.tcx, fun_def_id, &paths::BEGIN_PANIC);
|
||||
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) {
|
||||
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 let LitKind::Str(ref string, _) = lit.node;
|
||||
let string = string.as_str().replace("{{", "").replace("}}", "");
|
||||
|
|
|
@ -38,7 +38,7 @@ impl LintPass for Pass {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||
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 let Some(eq_trait) = cx.tcx.lang_items().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 {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
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 ItemImpl(_, _, _, _, Some(_), _, _) = it.node {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(_), _, _) = it.node {
|
||||
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) {
|
||||
if let ExprBinary(ref op, ref l, ref r) = expr.node {
|
||||
if (op.node == BiEq || op.node == BiNe) && (is_null_path(l) || is_null_path(r)) {
|
||||
if let ExprKind::Binary(ref op, ref l, ref r) = expr.node {
|
||||
if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(l) || is_null_path(r)) {
|
||||
span_lint(
|
||||
cx,
|
||||
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) {
|
||||
let mut ty_snippet = None;
|
||||
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();
|
||||
then {
|
||||
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) {
|
||||
if_chain! {
|
||||
if let TyRptr(_, MutTy { ref ty, ..} ) = arg.node;
|
||||
if let TyPath(ref path) = ty.node;
|
||||
if let TyKind::Rptr(_, MutTy { ref ty, ..} ) = arg.node;
|
||||
if let TyKind::Path(ref path) = ty.node;
|
||||
if let QPath::Resolved(None, ref pp) = *path;
|
||||
if let [ref bx] = *pp.segments;
|
||||
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)> {
|
||||
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))
|
||||
} else {
|
||||
None
|
||||
|
@ -281,9 +281,9 @@ fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability, Span)> {
|
|||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ impl QuestionMarkPass {
|
|||
/// If it matches, it will suggest to use the question mark operator instead
|
||||
fn check_is_none_and_early_return_none(cx: &LateContext, expr: &Expr) {
|
||||
if_chain! {
|
||||
if let ExprIf(ref if_expr, ref body, _) = expr.node;
|
||||
if let ExprMethodCall(ref segment, _, ref args) = if_expr.node;
|
||||
if let ExprKind::If(ref if_expr, ref body, _) = expr.node;
|
||||
if let ExprKind::MethodCall(ref segment, _, ref args) = if_expr.node;
|
||||
if segment.ident.name == "is_none";
|
||||
if Self::expression_returns_none(cx, body);
|
||||
if let Some(subject) = args.get(0);
|
||||
|
@ -87,17 +87,17 @@ impl QuestionMarkPass {
|
|||
|
||||
fn expression_returns_none(cx: &LateContext, expression: &Expr) -> bool {
|
||||
match expression.node {
|
||||
ExprBlock(ref block, _) => {
|
||||
ExprKind::Block(ref block, _) => {
|
||||
if let Some(return_expression) = Self::return_expression(block) {
|
||||
return Self::expression_returns_none(cx, &return_expression);
|
||||
}
|
||||
|
||||
false
|
||||
},
|
||||
ExprRet(Some(ref expr)) => {
|
||||
ExprKind::Ret(Some(ref 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) {
|
||||
return match_def_path(cx.tcx, def_id, &OPTION_NONE);
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ impl QuestionMarkPass {
|
|||
if_chain! {
|
||||
if block.stmts.len() == 1;
|
||||
if let Some(expr) = block.stmts.iter().last();
|
||||
if let StmtSemi(ref expr, _) = expr.node;
|
||||
if let ExprRet(ref ret_expr) = expr.node;
|
||||
if let StmtKind::Semi(ref expr, _) = expr.node;
|
||||
if let ExprKind::Ret(ref ret_expr) = expr.node;
|
||||
if let &Some(ref ret_expr) = ret_expr;
|
||||
|
||||
then {
|
||||
|
|
|
@ -3,7 +3,7 @@ use rustc::hir::*;
|
|||
use syntax::ast::RangeLimits;
|
||||
use syntax::codemap::Spanned;
|
||||
use crate::utils::{is_integer_literal, paths, snippet, span_lint, span_lint_and_then};
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait};
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait, SpanlessEq};
|
||||
use crate::utils::sugg::Sugg;
|
||||
|
||||
/// **What it does:** Checks for calling `.step_by(0)` on iterators,
|
||||
|
@ -88,7 +88,7 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
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();
|
||||
|
||||
// Range with step_by(0).
|
||||
|
@ -107,18 +107,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
let zip_arg = &args[1];
|
||||
if_chain! {
|
||||
// .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";
|
||||
// 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 is_integer_literal(start, 0);
|
||||
// .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;
|
||||
// .iter() and .len() called on same Path
|
||||
if let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node;
|
||||
if let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node;
|
||||
if iter_path.segments == len_path.segments;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref iter_path)) = iter_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);
|
||||
then {
|
||||
span_lint(cx,
|
||||
RANGE_ZIP_WITH_LEN,
|
||||
|
@ -184,7 +184,7 @@ fn has_step_by(cx: &LateContext, expr: &Expr) -> bool {
|
|||
|
||||
fn y_plus_one(expr: &Expr) -> Option<&Expr> {
|
||||
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)
|
||||
} else if is_integer_literal(rhs, 1) {
|
||||
Some(lhs)
|
||||
|
@ -197,7 +197,7 @@ fn y_plus_one(expr: &Expr) -> Option<&Expr> {
|
|||
|
||||
fn y_minus_one(expr: &Expr) -> Option<&Expr> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
|
|||
return;
|
||||
}
|
||||
|
||||
if let ExprStruct(_, ref fields, _) = expr.node {
|
||||
if let ExprKind::Struct(_, ref fields, _) = expr.node {
|
||||
for field in fields {
|
||||
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) {
|
||||
if_chain! {
|
||||
if let ExprCall(ref fun, ref args) = expr.node;
|
||||
if let ExprPath(ref qpath) = fun.node;
|
||||
if let ExprKind::Call(ref fun, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath) = fun.node;
|
||||
if args.len() == 1;
|
||||
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, fun.hir_id));
|
||||
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) {
|
||||
if_chain! {
|
||||
if let ExprAddrOf(_, ref expr) = expr.node;
|
||||
if let ExprArray(ref exprs) = expr.node;
|
||||
if let ExprKind::AddrOf(_, ref expr) = expr.node;
|
||||
if let ExprKind::Array(ref exprs) = expr.node;
|
||||
then {
|
||||
for expr in exprs {
|
||||
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)
|
||||
.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 {
|
||||
let r = &r.as_str();
|
||||
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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
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);
|
||||
then {
|
||||
for &(const_path, repl_snip) in REPLACEMENTS {
|
||||
|
|
|
@ -29,7 +29,7 @@ impl LintPass for Serde {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Serde {
|
||||
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();
|
||||
if let Some(visit_did) = get_trait_def_id(cx, &paths::SERDE_DE_VISITOR) {
|
||||
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();
|
||||
for stmt in &block.stmts {
|
||||
match stmt.node {
|
||||
StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),
|
||||
StmtExpr(ref e, _) | StmtSemi(ref e, _) => check_expr(cx, e, bindings),
|
||||
StmtKind::Decl(ref decl, _) => check_decl(cx, decl, bindings),
|
||||
StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => check_expr(cx, e, bindings),
|
||||
}
|
||||
}
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
if let DeclLocal(ref local) = decl.node {
|
||||
if let DeclKind::Local(ref local) = decl.node {
|
||||
let Local {
|
||||
ref pat,
|
||||
ref ty,
|
||||
|
@ -185,7 +185,7 @@ fn check_pat<'a, 'tcx>(
|
|||
}
|
||||
},
|
||||
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 {
|
||||
let name = field.node.ident.name;
|
||||
let efield = efields
|
||||
|
@ -205,7 +205,7 @@ fn check_pat<'a, 'tcx>(
|
|||
}
|
||||
},
|
||||
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() {
|
||||
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 {
|
||||
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);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
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)
|
||||
},
|
||||
ExprBlock(ref block, _) | ExprLoop(ref block, _, _) => check_block(cx, block, bindings),
|
||||
// ExprCall
|
||||
// ExprMethodCall
|
||||
ExprArray(ref v) | ExprTup(ref v) => for e in v {
|
||||
ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, _, _) => check_block(cx, block, bindings),
|
||||
// ExprKind::Call
|
||||
// ExprKind::MethodCall
|
||||
ExprKind::Array(ref v) | ExprKind::Tup(ref v) => for e in v {
|
||||
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, &**then, bindings);
|
||||
if let Some(ref o) = *otherwise {
|
||||
check_expr(cx, o, bindings);
|
||||
}
|
||||
},
|
||||
ExprWhile(ref cond, ref block, _) => {
|
||||
ExprKind::While(ref cond, ref block, _) => {
|
||||
check_expr(cx, cond, bindings);
|
||||
check_block(cx, block, bindings);
|
||||
},
|
||||
ExprMatch(ref init, ref arms, _) => {
|
||||
ExprKind::Match(ref init, ref arms, _) => {
|
||||
check_expr(cx, init, bindings);
|
||||
let len = bindings.len();
|
||||
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)>) {
|
||||
match ty.node {
|
||||
TySlice(ref sty) => check_ty(cx, sty, bindings),
|
||||
TyArray(ref fty, ref anon_const) => {
|
||||
TyKind::Slice(ref sty) => check_ty(cx, sty, bindings),
|
||||
TyKind::Array(ref fty, ref anon_const) => {
|
||||
check_ty(cx, fty, 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),
|
||||
TyTup(ref tup) => for t in tup {
|
||||
TyKind::Ptr(MutTy { ty: ref mty, .. }) | TyKind::Rptr(_, MutTy { ty: ref mty, .. }) => check_ty(cx, mty, bindings),
|
||||
TyKind::Tup(ref tup) => for t in tup {
|
||||
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 {
|
||||
match expr.node {
|
||||
ExprBox(ref inner) | ExprAddrOf(_, ref inner) => is_self_shadow(name, inner),
|
||||
ExprBlock(ref block, _) => {
|
||||
ExprKind::Box(ref inner) | ExprKind::AddrOf(_, ref inner) => is_self_shadow(name, inner),
|
||||
ExprKind::Block(ref block, _) => {
|
||||
block.stmts.is_empty()
|
||||
&& block
|
||||
.expr
|
||||
.as_ref()
|
||||
.map_or(false, |e| is_self_shadow(name, e))
|
||||
},
|
||||
ExprUnary(op, ref inner) => (UnDeref == op) && is_self_shadow(name, inner),
|
||||
ExprPath(QPath::Resolved(_, ref path)) => path_eq_name(name, path),
|
||||
ExprKind::Unary(op, ref inner) => (UnDeref == op) && is_self_shadow(name, inner),
|
||||
ExprKind::Path(QPath::Resolved(_, ref path)) => path_eq_name(name, path),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,12 +82,12 @@ impl LintPass for StringAdd {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
||||
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_allowed(cx, STRING_ADD_ASSIGN, e.id) {
|
||||
let parent = get_parent_expr(cx, e);
|
||||
if let Some(p) = parent {
|
||||
if let ExprAssign(ref target, _) = p.node {
|
||||
if let ExprKind::Assign(ref target, _) = p.node {
|
||||
// avoid duplicate matches
|
||||
if SpanlessEq::new(cx).eq_expr(target, left) {
|
||||
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",
|
||||
);
|
||||
}
|
||||
} 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) {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -122,8 +122,8 @@ fn is_string(cx: &LateContext, e: &Expr) -> bool {
|
|||
|
||||
fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {
|
||||
match src.node {
|
||||
ExprBinary(Spanned { node: BiAdd, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
|
||||
ExprBlock(ref block, _) => {
|
||||
ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
|
||||
ExprKind::Block(ref block, _) => {
|
||||
block.stmts.is_empty()
|
||||
&& block
|
||||
.expr
|
||||
|
@ -148,9 +148,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
|||
use syntax::ast::LitKind;
|
||||
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 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 lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
|
||||
span_lint_and_sugg(
|
||||
|
|
|
@ -59,10 +59,15 @@ impl LintPass for SuspiciousImpl {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
use rustc::hir::BinOp_::*;
|
||||
if let hir::ExprBinary(binop, _, _) = expr.node {
|
||||
if let hir::ExprKind::Binary(binop, _, _) = expr.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
|
||||
|
@ -71,9 +76,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
while parent_expr != ast::CRATE_NODE_ID {
|
||||
if let hir::map::Node::NodeExpr(e) = cx.tcx.hir.get(parent_expr) {
|
||||
match e.node {
|
||||
hir::ExprBinary(..)
|
||||
| hir::ExprUnary(hir::UnOp::UnNot, _)
|
||||
| hir::ExprUnary(hir::UnOp::UnNeg, _) => return,
|
||||
hir::ExprKind::Binary(..)
|
||||
| hir::ExprKind::Unary(hir::UnOp::UnNot, _)
|
||||
| hir::ExprKind::Unary(hir::UnOp::UnNeg, _) => return,
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +99,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
expr,
|
||||
binop.node,
|
||||
&["Add", "Sub", "Mul", "Div"],
|
||||
&[BiAdd, BiSub, BiMul, BiDiv],
|
||||
&[
|
||||
hir::BinOpKind::Add,
|
||||
hir::BinOpKind::Sub,
|
||||
hir::BinOpKind::Mul,
|
||||
hir::BinOpKind::Div,
|
||||
],
|
||||
) {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -124,7 +134,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
"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(
|
||||
|
@ -144,9 +163,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
fn check_binop<'a>(
|
||||
cx: &LateContext,
|
||||
expr: &hir::Expr,
|
||||
binop: hir::BinOp_,
|
||||
binop: hir::BinOpKind,
|
||||
traits: &[&'a str],
|
||||
expected_ops: &[hir::BinOp_],
|
||||
expected_ops: &[hir::BinOpKind],
|
||||
) -> Option<&'a str> {
|
||||
let mut trait_ids = vec![];
|
||||
let [krate, module] = crate::utils::paths::OPS_MODULE;
|
||||
|
@ -167,7 +186,7 @@ fn check_binop<'a>(
|
|||
if_chain! {
|
||||
if parent_impl != ast::CRATE_NODE_ID;
|
||||
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 binop != expected_ops[idx];
|
||||
then{
|
||||
|
@ -185,9 +204,9 @@ struct BinaryExprVisitor {
|
|||
impl<'a, 'tcx: 'a> Visitor<'tcx> for BinaryExprVisitor {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprBinary(..)
|
||||
| hir::ExprUnary(hir::UnOp::UnNot, _)
|
||||
| hir::ExprUnary(hir::UnOp::UnNeg, _) => {
|
||||
hir::ExprKind::Binary(..)
|
||||
| hir::ExprKind::Unary(hir::UnOp::UnNot, _)
|
||||
| hir::ExprKind::Unary(hir::UnOp::UnNeg, _) => {
|
||||
self.in_binary_expr = true
|
||||
},
|
||||
_ => {},
|
||||
|
|
|
@ -61,19 +61,19 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
|
|||
for w in block.stmts.windows(3) {
|
||||
if_chain! {
|
||||
// let t = foo();
|
||||
if let StmtDecl(ref tmp, _) = w[0].node;
|
||||
if let DeclLocal(ref tmp) = tmp.node;
|
||||
if let StmtKind::Decl(ref tmp, _) = w[0].node;
|
||||
if let DeclKind::Local(ref tmp) = tmp.node;
|
||||
if let Some(ref tmp_init) = tmp.init;
|
||||
if let PatKind::Binding(_, _, ident, None) = tmp.pat.node;
|
||||
|
||||
// foo() = bar();
|
||||
if let StmtSemi(ref first, _) = w[1].node;
|
||||
if let ExprAssign(ref lhs1, ref rhs1) = first.node;
|
||||
if let StmtKind::Semi(ref first, _) = w[1].node;
|
||||
if let ExprKind::Assign(ref lhs1, ref rhs1) = first.node;
|
||||
|
||||
// bar() = t;
|
||||
if let StmtSemi(ref second, _) = w[2].node;
|
||||
if let ExprAssign(ref lhs2, ref rhs2) = second.node;
|
||||
if let ExprPath(QPath::Resolved(None, ref rhs2)) = rhs2.node;
|
||||
if let StmtKind::Semi(ref second, _) = w[2].node;
|
||||
if let ExprKind::Assign(ref lhs2, ref rhs2) = second.node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref rhs2)) = rhs2.node;
|
||||
if rhs2.segments.len() == 1;
|
||||
|
||||
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,
|
||||
lhs2: &'a Expr,
|
||||
) -> Option<(&'a Expr, &'a Expr, &'a Expr)> {
|
||||
if let ExprIndex(ref lhs1, ref idx1) = lhs1.node {
|
||||
if let ExprIndex(ref lhs2, ref idx2) = lhs2.node {
|
||||
if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.node {
|
||||
if let ExprKind::Index(ref lhs2, ref idx2) = lhs2.node {
|
||||
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) {
|
||||
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) {
|
||||
for w in block.stmts.windows(2) {
|
||||
if_chain! {
|
||||
if let StmtSemi(ref first, _) = w[0].node;
|
||||
if let StmtSemi(ref second, _) = w[1].node;
|
||||
if let StmtKind::Semi(ref first, _) = w[0].node;
|
||||
if let StmtKind::Semi(ref second, _) = w[1].node;
|
||||
if !differing_macro_contexts(first.span, second.span);
|
||||
if let ExprAssign(ref lhs0, ref rhs0) = first.node;
|
||||
if let ExprAssign(ref lhs1, ref rhs1) = second.node;
|
||||
if let ExprKind::Assign(ref lhs0, ref rhs0) = first.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(lhs1, rhs0);
|
||||
then {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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::span_lint;
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare_clippy_lint! {
|
|||
|
||||
fn is_temporary(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprStruct(..) | ExprTup(..) => true,
|
||||
ExprKind::Struct(..) | ExprKind::Tup(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ impl LintPass for Pass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if let ExprAssign(ref target, _) = expr.node {
|
||||
if let ExprField(ref base, _) = target.node {
|
||||
if let ExprKind::Assign(ref target, _) = expr.node {
|
||||
if let ExprKind::Field(ref base, _) = target.node {
|
||||
if is_temporary(base) && !is_adjusted(cx, base) {
|
||||
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 {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
if let ExprCall(ref path_expr, ref args) = e.node {
|
||||
if let ExprPath(ref qpath) = path_expr.node {
|
||||
if let ExprKind::Call(ref path_expr, ref args) = e.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 match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
|
||||
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::Lifetime(_) => None,
|
||||
}).nth(1);
|
||||
if let TyRptr(_, ref to_ty) = to_ty.node;
|
||||
if let TyKind::Rptr(_, ref to_ty) = to_ty.node;
|
||||
then {
|
||||
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
|
||||
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
|
||||
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) |
|
||||
ItemTrait(..))
|
||||
if matches!(item.node, ItemKind::Impl(_, _, _, _, Some(_), _, _) |
|
||||
ItemKind::Trait(..))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef {
|
|||
if is_copy(cx, ty);
|
||||
if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes());
|
||||
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 {
|
||||
let value_type = if is_self(arg) {
|
||||
"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) {
|
||||
// skip trait implementations, see #605
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool
|
|||
GenericArg::Type(ty) => Some(ty),
|
||||
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 match_def_path(cx.tcx, did, path);
|
||||
then {
|
||||
|
@ -206,7 +206,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
|
|||
return;
|
||||
}
|
||||
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 def = cx.tables.qpath_def(qpath, hir_id);
|
||||
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
|
||||
TySlice(ref ty) | TyArray(ref ty, _) | TyPtr(MutTy { ref ty, .. }) => check_ty(cx, ty, is_local),
|
||||
TyTup(ref tys) => for ty in tys {
|
||||
TyKind::Slice(ref ty) | TyKind::Array(ref ty, _) | TyKind::Ptr(MutTy { ref ty, .. }) => check_ty(cx, ty, is_local),
|
||||
TyKind::Tup(ref tys) => for ty in tys {
|
||||
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) {
|
||||
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 def = cx.tables.qpath_def(qpath, hir_id);
|
||||
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.
|
||||
fn is_any_trait(t: &hir::Ty) -> bool {
|
||||
if_chain! {
|
||||
if let TyTraitObject(ref traits, _) = t.node;
|
||||
if let TyKind::TraitObject(ref traits, _) = t.node;
|
||||
if traits.len() >= 1;
|
||||
// Only Send/Sync can be used as additional traits, so it is enough to
|
||||
// check only the first trait.
|
||||
|
@ -377,7 +377,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
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 in_external_macro(cx, decl.span) || in_macro(local.pat.span) {
|
||||
return;
|
||||
|
@ -446,11 +446,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
|
|||
if in_macro(expr.span) {
|
||||
return;
|
||||
}
|
||||
if let ExprBinary(ref cmp, ref left, _) = expr.node {
|
||||
if let ExprKind::Binary(ref cmp, ref left, _) = expr.node {
|
||||
let op = cmp.node;
|
||||
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) {
|
||||
let result = match op {
|
||||
BiEq | BiLe | BiGe => "true",
|
||||
BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => "true",
|
||||
_ => "false",
|
||||
};
|
||||
span_lint(
|
||||
|
@ -501,7 +501,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
|
|||
return;
|
||||
}
|
||||
match expr.node {
|
||||
ExprCall(_, ref args) | ExprMethodCall(_, _, ref args) => {
|
||||
ExprKind::Call(_, ref args) | ExprKind::MethodCall(_, _, ref args) => {
|
||||
for arg in args {
|
||||
if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) {
|
||||
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 {
|
||||
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)
|
||||
} else {
|
||||
false
|
||||
|
@ -555,7 +555,7 @@ fn is_unit(ty: Ty) -> bool {
|
|||
|
||||
fn is_unit_literal(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprTup(ref slice) if slice.is_empty() => true,
|
||||
ExprKind::Tup(ref slice) if slice.is_empty() => true,
|
||||
_ => 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 {
|
||||
if let ExprBinary(_, _, _) = op.node {
|
||||
if let ExprKind::Binary(_, _, _) = op.node {
|
||||
if snip.starts_with('(') && snip.ends_with(')') {
|
||||
return true;
|
||||
}
|
||||
|
@ -951,9 +951,9 @@ impl LintPass for CastPass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
|
||||
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));
|
||||
if let ExprLit(ref lit) = ex.node {
|
||||
if let ExprKind::Lit(ref lit) = ex.node {
|
||||
use syntax::ast::{LitIntType, LitKind};
|
||||
match lit.node {
|
||||
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) {
|
||||
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
|
||||
_ => (),
|
||||
}
|
||||
|
@ -1214,15 +1214,15 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
|||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
||||
let (add_score, sub_nest) = match ty.node {
|
||||
// _, &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
|
||||
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
|
||||
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
|
||||
.iter()
|
||||
.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) {
|
||||
use syntax::ast::{LitKind, UintTy};
|
||||
|
||||
if let ExprCast(ref e, _) = expr.node {
|
||||
if let ExprLit(ref l) = e.node {
|
||||
if let ExprKind::Cast(ref e, _) = expr.node {
|
||||
if let ExprKind::Lit(ref l) = e.node {
|
||||
if let LitKind::Char(_) = l.node {
|
||||
if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(expr.span) {
|
||||
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
|
||||
) -> 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 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>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
op: BinOp_,
|
||||
op: BinOpKind,
|
||||
lhs: &'tcx Expr,
|
||||
rhs: &'tcx Expr,
|
||||
) -> Option<(ExtremeExpr<'tcx>, AbsurdComparisonResult)> {
|
||||
|
@ -1453,7 +1453,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons {
|
|||
use crate::types::ExtremeType::*;
|
||||
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 !in_macro(expr.span) {
|
||||
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 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 cast_ty = cx.tables.expr_ty(expr);
|
||||
// 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) {
|
||||
if let ExprCast(ref cast_val, _) = expr.node {
|
||||
if let ExprKind::Cast(ref cast_val, _) = expr.node {
|
||||
span_lint(
|
||||
cx,
|
||||
INVALID_UPCAST_COMPARISONS,
|
||||
|
@ -1693,7 +1693,7 @@ fn upcast_comparison_bounds_err<'a, 'tcx>(
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidUpcastComparisons {
|
||||
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 (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized {
|
||||
val
|
||||
|
@ -1797,7 +1797,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher {
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ItemImpl(_, _, _, ref generics, _, ref ty, ref items) => {
|
||||
ItemKind::Impl(_, _, _, ref generics, _, ref ty, ref items) => {
|
||||
let mut vis = ImplicitHasherTypeVisitor::new(cx);
|
||||
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);
|
||||
|
||||
for ty in &decl.inputs {
|
||||
|
@ -1878,7 +1878,7 @@ enum ImplicitHasherType<'tcx> {
|
|||
impl<'tcx> ImplicitHasherType<'tcx> {
|
||||
/// Checks that `ty` is a target type without a BuildHasher.
|
||||
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()?
|
||||
.args.iter().filter_map(|arg| match arg {
|
||||
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) {
|
||||
if_chain! {
|
||||
if let ExprCall(ref fun, ref args) = e.node;
|
||||
if let ExprPath(QPath::TypeRelative(ref ty, ref method)) = fun.node;
|
||||
if let TyPath(QPath::Resolved(None, ref ty_path)) = ty.node;
|
||||
if let ExprKind::Call(ref fun, ref args) = e.node;
|
||||
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref method)) = fun.node;
|
||||
if let TyKind::Path(QPath::Resolved(None, ref ty_path)) = ty.node;
|
||||
then {
|
||||
if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) {
|
||||
return;
|
||||
|
|
|
@ -71,7 +71,7 @@ impl LintPass for Unicode {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unicode {
|
||||
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 {
|
||||
check_str(cx, lit.span, expr.id)
|
||||
}
|
||||
|
|
|
@ -40,14 +40,14 @@ impl LintPass for UnusedIoAmount {
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
|
||||
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
|
||||
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,
|
||||
};
|
||||
|
||||
match expr.node {
|
||||
hir::ExprMatch(ref res, _, _) if is_try(expr).is_some() => {
|
||||
if let hir::ExprCall(ref func, ref args) = res.node {
|
||||
if let hir::ExprPath(ref path) = func.node {
|
||||
hir::ExprKind::Match(ref res, _, _) if is_try(expr).is_some() => {
|
||||
if let hir::ExprKind::Call(ref func, ref args) = res.node {
|
||||
if let hir::ExprKind::Path(ref path) = func.node {
|
||||
if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 {
|
||||
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" => {
|
||||
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) {
|
||||
if let hir::ExprMethodCall(ref path, _, _) = call.node {
|
||||
if let hir::ExprKind::MethodCall(ref path, _, _) = call.node {
|
||||
let symbol = &*path.ident.as_str();
|
||||
if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" {
|
||||
span_lint(
|
||||
|
|
|
@ -69,10 +69,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel {
|
|||
impl<'a, 'tcx: 'a> Visitor<'tcx> for UnusedLabelVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
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());
|
||||
},
|
||||
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);
|
||||
},
|
||||
_ => (),
|
||||
|
|
|
@ -78,21 +78,21 @@ fn collect_unwrap_info<'a, 'tcx: 'a>(
|
|||
expr: &'tcx Expr,
|
||||
invert: bool,
|
||||
) -> 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) {
|
||||
(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);
|
||||
unwrap_info.append(&mut collect_unwrap_info(cx, right, invert));
|
||||
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);
|
||||
} else {
|
||||
if_chain! {
|
||||
if let Expr_::ExprMethodCall(method_name, _, args) = &expr.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(None, path)) = &args[0].node;
|
||||
if let ExprKind::MethodCall(method_name, _, args) = &expr.node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].node;
|
||||
let ty = cx.tables.expr_ty(&args[0]);
|
||||
if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
|
||||
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> {
|
||||
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);
|
||||
self.visit_branch(cond, then, false);
|
||||
if let Some(els) = els {
|
||||
|
@ -140,8 +140,8 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
|
|||
} else {
|
||||
// find `unwrap[_err]()` calls:
|
||||
if_chain! {
|
||||
if let Expr_::ExprMethodCall(ref method_name, _, ref args) = expr.node;
|
||||
if let Expr_::ExprPath(QPath::Resolved(None, ref path)) = args[0].node;
|
||||
if let ExprKind::MethodCall(ref method_name, _, ref args) = expr.node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = args[0].node;
|
||||
if ["unwrap", "unwrap_err"].contains(&&*method_name.ident.as_str());
|
||||
let call_to_unwrap = method_name.ident.name == "unwrap";
|
||||
if let Some(unwrappable) = self.unwrappables.iter()
|
||||
|
|
|
@ -65,7 +65,7 @@ struct TraitImplTyVisitor<'a, 'tcx: 'a> {
|
|||
impl<'a, 'tcx> Visitor<'tcx> for TraitImplTyVisitor<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, t: &'tcx Ty) {
|
||||
let trait_ty = self.type_walker.next();
|
||||
if let TyPath(QPath::Resolved(_, path)) = &t.node {
|
||||
if let TyKind::Path(QPath::Resolved(_, path)) = &t.node {
|
||||
let impl_is_self_ty = if let def::Def::SelfTy(..) = path.def {
|
||||
true
|
||||
} else {
|
||||
|
@ -137,8 +137,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
|
|||
return;
|
||||
}
|
||||
if_chain! {
|
||||
if let ItemImpl(.., item_type, refs) = &item.node;
|
||||
if let Ty_::TyPath(QPath::Resolved(_, ref item_path)) = item_type.node;
|
||||
if let ItemKind::Impl(.., ref item_type, ref refs) = item.node;
|
||||
if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.node;
|
||||
then {
|
||||
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
|
||||
let should_check = if let Some(ref params) = *parameters {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use rustc::lint::*;
|
||||
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 syntax::ast::{Attribute, LitKind, DUMMY_NODE_ID};
|
||||
use std::collections::HashMap;
|
||||
|
@ -32,10 +32,10 @@ use crate::utils::get_attr;
|
|||
/// ```rust
|
||||
/// // ./tests/ui/new_lint.stdout
|
||||
/// if_chain!{
|
||||
/// if let Expr_::ExprIf(ref cond, ref then, None) = item.node,
|
||||
/// if let Expr_::ExprBinary(BinOp::Eq, ref left, ref right) = cond.node,
|
||||
/// if let Expr_::ExprPath(ref path) = left.node,
|
||||
/// if let Expr_::ExprLit(ref lit) = right.node,
|
||||
/// if let ExprKind::If(ref cond, ref then, None) = item.node,
|
||||
/// if let ExprKind::Binary(BinOp::Eq, ref left, ref right) = cond.node,
|
||||
/// if let ExprKind::Path(ref path) = left.node,
|
||||
/// if let ExprKind::Lit(ref lit) = right.node,
|
||||
/// if let LitKind::Int(42, _) = lit.node,
|
||||
/// then {
|
||||
/// // report your lint here
|
||||
|
@ -192,16 +192,16 @@ struct PrintVisitor {
|
|||
|
||||
impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
||||
fn visit_expr(&mut self, expr: &Expr) {
|
||||
print!(" if let Expr_::Expr");
|
||||
print!(" if let ExprKind::");
|
||||
let current = format!("{}.node", self.current);
|
||||
match expr.node {
|
||||
Expr_::ExprBox(ref inner) => {
|
||||
ExprKind::Box(ref inner) => {
|
||||
let inner_pat = self.next("inner");
|
||||
println!("Box(ref {}) = {};", inner_pat, current);
|
||||
self.current = inner_pat;
|
||||
self.visit_expr(inner);
|
||||
},
|
||||
Expr_::ExprArray(ref elements) => {
|
||||
ExprKind::Array(ref elements) => {
|
||||
let elements_pat = self.next("elements");
|
||||
println!("Array(ref {}) = {};", elements_pat, current);
|
||||
println!(" if {}.len() == {};", elements_pat, elements.len());
|
||||
|
@ -210,7 +210,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.visit_expr(element);
|
||||
}
|
||||
},
|
||||
Expr_::ExprCall(ref func, ref args) => {
|
||||
ExprKind::Call(ref func, ref args) => {
|
||||
let func_pat = self.next("func");
|
||||
let args_pat = self.next("args");
|
||||
println!("Call(ref {}, ref {}) = {};", func_pat, args_pat, current);
|
||||
|
@ -222,11 +222,11 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
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!(" // 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");
|
||||
println!("Tup(ref {}) = {};", elements_pat, current);
|
||||
println!(" if {}.len() == {};", elements_pat, elements.len());
|
||||
|
@ -235,24 +235,24 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
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 left_pat = self.next("left");
|
||||
let right_pat = self.next("right");
|
||||
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.visit_expr(left);
|
||||
self.current = right_pat;
|
||||
self.visit_expr(right);
|
||||
},
|
||||
Expr_::ExprUnary(ref op, ref inner) => {
|
||||
ExprKind::Unary(ref op, ref inner) => {
|
||||
let inner_pat = self.next("inner");
|
||||
println!("Unary(UnOp::{:?}, ref {}) = {};", op, inner_pat, current);
|
||||
self.current = inner_pat;
|
||||
self.visit_expr(inner);
|
||||
},
|
||||
Expr_::ExprLit(ref lit) => {
|
||||
ExprKind::Lit(ref lit) => {
|
||||
let lit_pat = self.next("lit");
|
||||
println!("Lit(ref {}) = {};", lit_pat, current);
|
||||
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_ty = self.next("cast_ty");
|
||||
let qp_label = self.next("qp");
|
||||
|
||||
println!("Cast(ref {}, ref {}) = {};", cast_pat, cast_ty, current);
|
||||
if let Ty_::TyPath(ref qp) = ty.node {
|
||||
println!(" if let Ty_::TyPath(ref {}) = {}.node;", qp_label, cast_ty);
|
||||
if let TyKind::Path(ref qp) = ty.node {
|
||||
println!(" if let TyKind::Path(ref {}) = {}.node;", qp_label, cast_ty);
|
||||
self.current = qp_label;
|
||||
self.print_qpath(qp);
|
||||
}
|
||||
self.current = cast_pat;
|
||||
self.visit_expr(expr);
|
||||
},
|
||||
Expr_::ExprType(ref expr, ref _ty) => {
|
||||
ExprKind::Type(ref expr, ref _ty) => {
|
||||
let cast_pat = self.next("expr");
|
||||
println!("Type(ref {}, _) = {};", cast_pat, current);
|
||||
self.current = cast_pat;
|
||||
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 then_pat = self.next("then");
|
||||
if let Some(ref else_) = *opt_else {
|
||||
|
@ -313,7 +313,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = then_pat;
|
||||
self.visit_expr(then);
|
||||
},
|
||||
Expr_::ExprWhile(ref cond, ref body, _) => {
|
||||
ExprKind::While(ref cond, ref body, _) => {
|
||||
let cond_pat = self.next("cond");
|
||||
let body_pat = self.next("body");
|
||||
let label_pat = self.next("label");
|
||||
|
@ -323,7 +323,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = body_pat;
|
||||
self.visit_block(body);
|
||||
},
|
||||
Expr_::ExprLoop(ref body, _, desugaring) => {
|
||||
ExprKind::Loop(ref body, _, desugaring) => {
|
||||
let body_pat = self.next("body");
|
||||
let des = loop_desugaring_name(desugaring);
|
||||
let label_pat = self.next("label");
|
||||
|
@ -331,7 +331,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = body_pat;
|
||||
self.visit_block(body);
|
||||
},
|
||||
Expr_::ExprMatch(ref expr, ref arms, desugaring) => {
|
||||
ExprKind::Match(ref expr, ref arms, desugaring) => {
|
||||
let des = desugaring_name(desugaring);
|
||||
let expr_pat = self.next("expr");
|
||||
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!(" // 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");
|
||||
println!("Yield(ref sub) = {};", current);
|
||||
self.current = sub_pat;
|
||||
self.visit_expr(sub);
|
||||
},
|
||||
Expr_::ExprBlock(ref block, _) => {
|
||||
ExprKind::Block(ref block, _) => {
|
||||
let block_pat = self.next("block");
|
||||
println!("Block(ref {}) = {};", block_pat, current);
|
||||
self.current = block_pat;
|
||||
self.visit_block(block);
|
||||
},
|
||||
Expr_::ExprAssign(ref target, ref value) => {
|
||||
ExprKind::Assign(ref target, ref value) => {
|
||||
let target_pat = self.next("target");
|
||||
let value_pat = self.next("value");
|
||||
println!("Assign(ref {}, ref {}) = {};", target_pat, value_pat, current);
|
||||
|
@ -380,18 +380,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = value_pat;
|
||||
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 target_pat = self.next("target");
|
||||
let value_pat = self.next("value");
|
||||
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.visit_expr(target);
|
||||
self.current = value_pat;
|
||||
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 field_name_pat = self.next("field_name");
|
||||
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.visit_expr(object);
|
||||
},
|
||||
Expr_::ExprIndex(ref object, ref index) => {
|
||||
ExprKind::Index(ref object, ref index) => {
|
||||
let object_pat = self.next("object");
|
||||
let index_pat = self.next("index");
|
||||
println!("Index(ref {}, ref {}) = {};", object_pat, index_pat, current);
|
||||
|
@ -408,19 +408,19 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
self.current = index_pat;
|
||||
self.visit_expr(index);
|
||||
},
|
||||
Expr_::ExprPath(ref path) => {
|
||||
ExprKind::Path(ref path) => {
|
||||
let path_pat = self.next("path");
|
||||
println!("Path(ref {}) = {};", path_pat, current);
|
||||
self.current = path_pat;
|
||||
self.print_qpath(path);
|
||||
},
|
||||
Expr_::ExprAddrOf(mutability, ref inner) => {
|
||||
ExprKind::AddrOf(mutability, ref inner) => {
|
||||
let inner_pat = self.next("inner");
|
||||
println!("AddrOf({:?}, ref {}) = {};", mutability, inner_pat, current);
|
||||
self.current = inner_pat;
|
||||
self.visit_expr(inner);
|
||||
},
|
||||
Expr_::ExprBreak(ref _destination, ref opt_value) => {
|
||||
ExprKind::Break(ref _destination, ref opt_value) => {
|
||||
let destination_pat = self.next("destination");
|
||||
if let Some(ref value) = *opt_value {
|
||||
let value_pat = self.next("value");
|
||||
|
@ -432,12 +432,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
}
|
||||
// FIXME: implement label printing
|
||||
},
|
||||
Expr_::ExprContinue(ref _destination) => {
|
||||
ExprKind::Continue(ref _destination) => {
|
||||
let destination_pat = self.next("destination");
|
||||
println!("Again(ref {}) = {};", destination_pat, current);
|
||||
// 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");
|
||||
println!("Ret(Some(ref {})) = {};", value_pat, current);
|
||||
self.current = value_pat;
|
||||
|
@ -445,11 +445,11 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
} else {
|
||||
println!("Ret(None) = {};", current);
|
||||
},
|
||||
Expr_::ExprInlineAsm(_, ref _input, ref _output) => {
|
||||
ExprKind::InlineAsm(_, ref _input, ref _output) => {
|
||||
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 fields_pat = self.next("fields");
|
||||
if let Some(ref base) = *opt_base {
|
||||
|
@ -472,7 +472,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
println!(" // unimplemented: field checks");
|
||||
},
|
||||
// FIXME: compute length (needs type info)
|
||||
Expr_::ExprRepeat(ref value, _) => {
|
||||
ExprKind::Repeat(ref value, _) => {
|
||||
let value_pat = self.next("value");
|
||||
println!("Repeat(ref {}, _) = {};", value_pat, current);
|
||||
println!("// unimplemented: repeat count check");
|
||||
|
@ -588,20 +588,20 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &Stmt) {
|
||||
print!(" if let Stmt_::");
|
||||
print!(" if let StmtKind::");
|
||||
let current = format!("{}.node", self.current);
|
||||
match s.node {
|
||||
// Could be an item or a local (let) binding:
|
||||
StmtDecl(ref decl, _) => {
|
||||
StmtKind::Decl(ref decl, _) => {
|
||||
let decl_pat = self.next("decl");
|
||||
println!("StmtDecl(ref {}, _) = {}", decl_pat, current);
|
||||
print!(" if let Decl_::");
|
||||
println!("Decl(ref {}, _) = {}", decl_pat, current);
|
||||
print!(" if let DeclKind::");
|
||||
let current = format!("{}.node", decl_pat);
|
||||
match decl.node {
|
||||
// A local (let) binding:
|
||||
Decl_::DeclLocal(ref local) => {
|
||||
DeclKind::Local(ref 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 {
|
||||
let init_pat = self.next("init");
|
||||
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);
|
||||
},
|
||||
// An item binding:
|
||||
Decl_::DeclItem(_) => {
|
||||
println!("DeclItem(item_id) = {};", current);
|
||||
DeclKind::Item(_) => {
|
||||
println!("Item(item_id) = {};", current);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Expr without trailing semi-colon (must have unit type):
|
||||
StmtExpr(ref e, _) => {
|
||||
StmtKind::Expr(ref e, _) => {
|
||||
let e_pat = self.next("e");
|
||||
println!("StmtExpr(ref {}, _) = {}", e_pat, current);
|
||||
println!("Expr(ref {}, _) = {}", e_pat, current);
|
||||
self.current = e_pat;
|
||||
self.visit_expr(e);
|
||||
},
|
||||
|
||||
// Expr with trailing semi-colon (may have any type):
|
||||
StmtSemi(ref e, _) => {
|
||||
StmtKind::Semi(ref e, _) => {
|
||||
let e_pat = self.next("e");
|
||||
println!("StmtSemi(ref {}, _) = {}", e_pat, current);
|
||||
println!("Semi(ref {}, _) = {}", e_pat, current);
|
||||
self.current = e_pat;
|
||||
self.visit_expr(e);
|
||||
},
|
||||
|
@ -674,7 +674,7 @@ fn print_path(path: &QPath, first: &mut bool) {
|
|||
print!("{:?}", segment.ident.as_str());
|
||||
},
|
||||
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);
|
||||
if *first {
|
||||
*first = false;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#![deny(missing_docs_in_private_items)]
|
||||
|
||||
use rustc::hir::{BinOp_, Expr};
|
||||
use rustc::hir::{BinOpKind, Expr};
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
||||
/// 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
|
||||
/// `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 {
|
||||
BinOp_::BiLt => Some((Rel::Lt, lhs, rhs)),
|
||||
BinOp_::BiLe => Some((Rel::Le, lhs, rhs)),
|
||||
BinOp_::BiGt => Some((Rel::Lt, rhs, lhs)),
|
||||
BinOp_::BiGe => Some((Rel::Le, rhs, lhs)),
|
||||
BinOp_::BiEq => Some((Rel::Eq, rhs, lhs)),
|
||||
BinOp_::BiNe => Some((Rel::Ne, rhs, lhs)),
|
||||
BinOpKind::Lt => Some((Rel::Lt, lhs, rhs)),
|
||||
BinOpKind::Le => Some((Rel::Le, lhs, rhs)),
|
||||
BinOpKind::Gt => Some((Rel::Lt, rhs, lhs)),
|
||||
BinOpKind::Ge => Some((Rel::Le, rhs, lhs)),
|
||||
BinOpKind::Eq => Some((Rel::Eq, rhs, lhs)),
|
||||
BinOpKind::Ne => Some((Rel::Ne, rhs, lhs)),
|
||||
_ => 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};
|
||||
|
||||
/// 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 {
|
||||
hir::BiEq => ast::BinOpKind::Eq,
|
||||
hir::BiGe => ast::BinOpKind::Ge,
|
||||
hir::BiGt => ast::BinOpKind::Gt,
|
||||
hir::BiLe => ast::BinOpKind::Le,
|
||||
hir::BiLt => ast::BinOpKind::Lt,
|
||||
hir::BiNe => ast::BinOpKind::Ne,
|
||||
hir::BiOr => ast::BinOpKind::Or,
|
||||
hir::BiAdd => ast::BinOpKind::Add,
|
||||
hir::BiAnd => ast::BinOpKind::And,
|
||||
hir::BiBitAnd => ast::BinOpKind::BitAnd,
|
||||
hir::BiBitOr => ast::BinOpKind::BitOr,
|
||||
hir::BiBitXor => ast::BinOpKind::BitXor,
|
||||
hir::BiDiv => ast::BinOpKind::Div,
|
||||
hir::BiMul => ast::BinOpKind::Mul,
|
||||
hir::BiRem => ast::BinOpKind::Rem,
|
||||
hir::BiShl => ast::BinOpKind::Shl,
|
||||
hir::BiShr => ast::BinOpKind::Shr,
|
||||
hir::BiSub => ast::BinOpKind::Sub,
|
||||
hir::BinOpKind::Eq => ast::BinOpKind::Eq,
|
||||
hir::BinOpKind::Ge => ast::BinOpKind::Ge,
|
||||
hir::BinOpKind::Gt => ast::BinOpKind::Gt,
|
||||
hir::BinOpKind::Le => ast::BinOpKind::Le,
|
||||
hir::BinOpKind::Lt => ast::BinOpKind::Lt,
|
||||
hir::BinOpKind::Ne => ast::BinOpKind::Ne,
|
||||
hir::BinOpKind::Or => ast::BinOpKind::Or,
|
||||
hir::BinOpKind::Add => ast::BinOpKind::Add,
|
||||
hir::BinOpKind::And => ast::BinOpKind::And,
|
||||
hir::BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
|
||||
hir::BinOpKind::BitOr => ast::BinOpKind::BitOr,
|
||||
hir::BinOpKind::BitXor => ast::BinOpKind::BitXor,
|
||||
hir::BinOpKind::Div => ast::BinOpKind::Div,
|
||||
hir::BinOpKind::Mul => ast::BinOpKind::Mul,
|
||||
hir::BinOpKind::Rem => ast::BinOpKind::Rem,
|
||||
hir::BinOpKind::Shl => ast::BinOpKind::Shl,
|
||||
hir::BinOpKind::Shr => ast::BinOpKind::Shr,
|
||||
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.
|
||||
|
||||
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) {
|
||||
Some(Range {
|
||||
start: None,
|
||||
|
@ -98,7 +98,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
|
|||
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) {
|
||||
Some(Range {
|
||||
start: Some(&args[0]),
|
||||
|
@ -111,7 +111,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
|
|||
} else {
|
||||
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)
|
||||
{
|
||||
Some(Range {
|
||||
|
@ -154,9 +154,9 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
|
|||
// }
|
||||
// ```
|
||||
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 hir::ExprMatch(_, _, hir::MatchSource::ForLoopDesugar) = expr.node;
|
||||
if let hir::ExprKind::Match(_, _, hir::MatchSource::ForLoopDesugar) = expr.node;
|
||||
then {
|
||||
return true;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
|
|||
// }
|
||||
// ```
|
||||
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;
|
||||
then {
|
||||
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)`.
|
||||
pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> {
|
||||
if_chain! {
|
||||
if let hir::ExprMatch(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node;
|
||||
if let hir::ExprCall(_, ref iterargs) = iterexpr.node;
|
||||
if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node;
|
||||
if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.node;
|
||||
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 let [ _, _, ref let_stmt, ref body ] = *block.stmts;
|
||||
if let hir::StmtDecl(ref decl, _) = let_stmt.node;
|
||||
if let hir::DeclLocal(ref decl) = decl.node;
|
||||
if let hir::StmtExpr(ref expr, _) = body.node;
|
||||
if let hir::StmtKind::Decl(ref decl, _) = let_stmt.node;
|
||||
if let hir::DeclKind::Local(ref decl) = decl.node;
|
||||
if let hir::StmtKind::Expr(ref expr, _) = body.node;
|
||||
then {
|
||||
return Some((&*decl.pat, &iterargs[0], expr));
|
||||
}
|
||||
|
@ -213,8 +213,8 @@ pub enum VecArgs<'a> {
|
|||
/// from `vec!`.
|
||||
pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e>> {
|
||||
if_chain! {
|
||||
if let hir::ExprCall(ref fun, ref args) = expr.node;
|
||||
if let hir::ExprPath(ref path) = fun.node;
|
||||
if let hir::ExprKind::Call(ref fun, ref args) = expr.node;
|
||||
if let hir::ExprKind::Path(ref path) = fun.node;
|
||||
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));
|
||||
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 {
|
||||
// `vec![a, b, c]` case
|
||||
if_chain! {
|
||||
if let hir::ExprBox(ref boxed) = args[0].node;
|
||||
if let hir::ExprArray(ref args) = boxed.node;
|
||||
if let hir::ExprKind::Box(ref boxed) = args[0].node;
|
||||
if let hir::ExprKind::Array(ref args) = boxed.node;
|
||||
then {
|
||||
return Some(VecArgs::Vec(&*args));
|
||||
}
|
||||
|
|
|
@ -43,14 +43,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
/// Check whether two statements are the same.
|
||||
pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool {
|
||||
match (&left.node, &right.node) {
|
||||
(&StmtDecl(ref l, _), &StmtDecl(ref r, _)) => {
|
||||
if let (&DeclLocal(ref l), &DeclLocal(ref r)) = (&l.node, &r.node) {
|
||||
(&StmtKind::Decl(ref l, _), &StmtKind::Decl(ref r, _)) => {
|
||||
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))
|
||||
} else {
|
||||
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)
|
||||
},
|
||||
_ => false,
|
||||
|
@ -75,52 +75,52 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
}
|
||||
|
||||
match (&left.node, &right.node) {
|
||||
(&ExprAddrOf(l_mut, ref le), &ExprAddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re),
|
||||
(&ExprContinue(li), &ExprContinue(ri)) => {
|
||||
(&ExprKind::AddrOf(l_mut, ref le), &ExprKind::AddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re),
|
||||
(&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
|
||||
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),
|
||||
(&ExprAssignOp(ref lo, ref ll, ref lr), &ExprAssignOp(ref ro, ref rl, ref rr)) => {
|
||||
(&ExprKind::Assign(ref ll, ref lr), &ExprKind::Assign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, 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)
|
||||
},
|
||||
(&ExprBlock(ref l, _), &ExprBlock(ref r, _)) => self.eq_block(l, r),
|
||||
(&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => {
|
||||
(&ExprKind::Block(ref l, _), &ExprKind::Block(ref r, _)) => self.eq_block(l, r),
|
||||
(&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)
|
||||
|| 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)
|
||||
})
|
||||
},
|
||||
(&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(le, re, |l, r| self.eq_expr(l, r))
|
||||
},
|
||||
(&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r),
|
||||
(&ExprCall(ref l_fun, ref l_args), &ExprCall(ref r_fun, ref r_args)) => {
|
||||
(&ExprKind::Box(ref l), &ExprKind::Box(ref r)) => self.eq_expr(l, r),
|
||||
(&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)
|
||||
},
|
||||
(&ExprCast(ref lx, ref lt), &ExprCast(ref rx, ref rt)) |
|
||||
(&ExprType(ref lx, ref lt), &ExprType(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::Cast(ref lx, ref lt), &ExprKind::Cast(ref rx, ref rt)) |
|
||||
(&ExprKind::Type(ref lx, ref lt), &ExprKind::Type(ref rx, ref rt)) => self.eq_expr(lx, rx) && self.eq_ty(lt, rt),
|
||||
(&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)
|
||||
},
|
||||
(&ExprIndex(ref la, ref li), &ExprIndex(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::Index(ref la, ref li), &ExprKind::Index(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||
(&ExprKind::If(ref lc, ref lt, ref le), &ExprKind::If(ref rc, ref rt, ref re)) => {
|
||||
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
},
|
||||
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node,
|
||||
(&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => {
|
||||
(&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
|
||||
(&ExprKind::Loop(ref lb, ref ll, ref lls), &ExprKind::Loop(ref rb, ref rl, ref rls)) => {
|
||||
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
|
||||
},
|
||||
(&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| {
|
||||
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))
|
||||
})
|
||||
},
|
||||
(&ExprMethodCall(ref l_path, _, ref l_args), &ExprMethodCall(ref r_path, _, ref r_args)) => {
|
||||
!self.ignore_fn && l_path == r_path && self.eq_exprs(l_args, 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)
|
||||
},
|
||||
(&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 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));
|
||||
|
@ -128,16 +128,16 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
|
||||
self.eq_expr(le, re) && ll == rl
|
||||
},
|
||||
(&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r),
|
||||
(&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => {
|
||||
(&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
(&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))
|
||||
&& 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),
|
||||
(&ExprUnary(l_op, ref le), &ExprUnary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re),
|
||||
(&ExprArray(ref l), &ExprArray(ref r)) => self.eq_exprs(l, r),
|
||||
(&ExprWhile(ref lc, ref lb, ref ll), &ExprWhile(ref rc, ref rb, ref rl)) => {
|
||||
(&ExprKind::Tup(ref l_tup), &ExprKind::Tup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
|
||||
(&ExprKind::Unary(l_op, ref le), &ExprKind::Unary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re),
|
||||
(&ExprKind::Array(ref l), &ExprKind::Array(ref r)) => self.eq_exprs(l, r),
|
||||
(&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())
|
||||
},
|
||||
_ => false,
|
||||
|
@ -225,7 +225,11 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool {
|
||||
pub fn eq_path_segments(&mut self, left: &[PathSegment], right: &[PathSegment]) -> bool {
|
||||
left.len() == right.len() && left.iter().zip(right).all(|(l, r)| self.eq_path_segment(l, r))
|
||||
}
|
||||
|
||||
pub fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool {
|
||||
// The == of idents doesn't work with different contexts,
|
||||
// we have to be explicit about hygiene
|
||||
if left.ident.as_str() != right.ident.as_str() {
|
||||
|
@ -238,10 +242,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool {
|
||||
match (&left.node, &right.node) {
|
||||
(&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
|
||||
(&TyArray(ref lt, ref ll_id), &TyArray(ref rt, ref rl_id)) => {
|
||||
pub fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool {
|
||||
self.eq_ty_kind(&left.node, &right.node)
|
||||
}
|
||||
|
||||
pub fn eq_ty_kind(&mut self, left: &TyKind, right: &TyKind) -> bool {
|
||||
match (left, right) {
|
||||
(&TyKind::Slice(ref l_vec), &TyKind::Slice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
|
||||
(&TyKind::Array(ref lt, ref ll_id), &TyKind::Array(ref rt, ref rl_id)) => {
|
||||
let full_table = self.tables;
|
||||
|
||||
let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body));
|
||||
|
@ -256,13 +264,13 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
self.tables = full_table;
|
||||
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),
|
||||
(&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => {
|
||||
(&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),
|
||||
(&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)
|
||||
},
|
||||
(&TyPath(ref l), &TyPath(ref r)) => self.eq_qpath(l, r),
|
||||
(&TyTup(ref l), &TyTup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)),
|
||||
(&TyInfer, &TyInfer) => true,
|
||||
(&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r),
|
||||
(&TyKind::Tup(ref l), &TyKind::Tup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)),
|
||||
(&TyKind::Infer, &TyKind::Infer) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -272,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 {
|
||||
BiAdd | BiMul | BiBitXor | BiBitAnd | BiEq | BiNe | BiBitOr => Some((binop, rhs, lhs)),
|
||||
BiLt => Some((BiGt, rhs, lhs)),
|
||||
BiLe => Some((BiGe, rhs, lhs)),
|
||||
BiGe => Some((BiLe, rhs, lhs)),
|
||||
BiGt => Some((BiLt, rhs, lhs)),
|
||||
BiShl | BiShr | BiRem | BiSub | BiDiv | BiAnd | BiOr => None,
|
||||
BinOpKind::Add |
|
||||
BinOpKind::Mul |
|
||||
BinOpKind::Eq |
|
||||
BinOpKind::Ne |
|
||||
BinOpKind::BitAnd |
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +356,12 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(e);
|
||||
}
|
||||
|
||||
b.rules.hash(&mut self.s);
|
||||
match b.rules {
|
||||
BlockCheckMode::DefaultBlock => 0,
|
||||
BlockCheckMode::UnsafeBlock(_) => 1,
|
||||
BlockCheckMode::PushUnsafeBlock(_) => 2,
|
||||
BlockCheckMode::PopUnsafeBlock(_) => 3,
|
||||
}.hash(&mut self.s);
|
||||
}
|
||||
|
||||
#[allow(many_single_char_names)]
|
||||
|
@ -346,51 +371,51 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
|
||||
match e.node {
|
||||
ExprAddrOf(m, ref e) => {
|
||||
let c: fn(_, _) -> _ = ExprAddrOf;
|
||||
ExprKind::AddrOf(m, ref e) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::AddrOf;
|
||||
c.hash(&mut self.s);
|
||||
m.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
},
|
||||
ExprContinue(i) => {
|
||||
let c: fn(_) -> _ = ExprContinue;
|
||||
ExprKind::Continue(i) => {
|
||||
let c: fn(_) -> _ = ExprKind::Continue;
|
||||
c.hash(&mut self.s);
|
||||
if let Some(i) = i.label {
|
||||
self.hash_name(i.ident.name);
|
||||
}
|
||||
},
|
||||
ExprYield(ref e) => {
|
||||
let c: fn(_) -> _ = ExprYield;
|
||||
ExprKind::Yield(ref e) => {
|
||||
let c: fn(_) -> _ = ExprKind::Yield;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
},
|
||||
ExprAssign(ref l, ref r) => {
|
||||
let c: fn(_, _) -> _ = ExprAssign;
|
||||
ExprKind::Assign(ref l, ref r) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Assign;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(l);
|
||||
self.hash_expr(r);
|
||||
},
|
||||
ExprAssignOp(ref o, ref l, ref r) => {
|
||||
let c: fn(_, _, _) -> _ = ExprAssignOp;
|
||||
ExprKind::AssignOp(ref o, ref l, ref r) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::AssignOp;
|
||||
c.hash(&mut self.s);
|
||||
o.hash(&mut self.s);
|
||||
self.hash_expr(l);
|
||||
self.hash_expr(r);
|
||||
},
|
||||
ExprBlock(ref b, _) => {
|
||||
let c: fn(_, _) -> _ = ExprBlock;
|
||||
ExprKind::Block(ref b, _) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Block;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_block(b);
|
||||
},
|
||||
ExprBinary(op, ref l, ref r) => {
|
||||
let c: fn(_, _, _) -> _ = ExprBinary;
|
||||
ExprKind::Binary(op, ref l, ref r) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::Binary;
|
||||
c.hash(&mut self.s);
|
||||
op.node.hash(&mut self.s);
|
||||
self.hash_expr(l);
|
||||
self.hash_expr(r);
|
||||
},
|
||||
ExprBreak(i, ref j) => {
|
||||
let c: fn(_, _) -> _ = ExprBreak;
|
||||
ExprKind::Break(i, ref j) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Break;
|
||||
c.hash(&mut self.s);
|
||||
if let Some(i) = i.label {
|
||||
self.hash_name(i.ident.name);
|
||||
|
@ -399,47 +424,50 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(&*j);
|
||||
}
|
||||
},
|
||||
ExprBox(ref e) => {
|
||||
let c: fn(_) -> _ = ExprBox;
|
||||
ExprKind::Box(ref e) => {
|
||||
let c: fn(_) -> _ = ExprKind::Box;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
},
|
||||
ExprCall(ref fun, ref args) => {
|
||||
let c: fn(_, _) -> _ = ExprCall;
|
||||
ExprKind::Call(ref fun, ref args) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Call;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(fun);
|
||||
self.hash_exprs(args);
|
||||
},
|
||||
ExprCast(ref e, ref _ty) => {
|
||||
let c: fn(_, _) -> _ = ExprCast;
|
||||
ExprKind::Cast(ref e, ref _ty) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Cast;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
// TODO: _ty
|
||||
},
|
||||
ExprClosure(cap, _, eid, _, _) => {
|
||||
let c: fn(_, _, _, _, _) -> _ = ExprClosure;
|
||||
ExprKind::Closure(cap, _, eid, _, _) => {
|
||||
let c: fn(_, _, _, _, _) -> _ = ExprKind::Closure;
|
||||
c.hash(&mut self.s);
|
||||
cap.hash(&mut self.s);
|
||||
match cap {
|
||||
CaptureClause::CaptureByValue => 0,
|
||||
CaptureClause::CaptureByRef => 1,
|
||||
}.hash(&mut self.s);
|
||||
self.hash_expr(&self.cx.tcx.hir.body(eid).value);
|
||||
},
|
||||
ExprField(ref e, ref f) => {
|
||||
let c: fn(_, _) -> _ = ExprField;
|
||||
ExprKind::Field(ref e, ref f) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Field;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
self.hash_name(f.name);
|
||||
},
|
||||
ExprIndex(ref a, ref i) => {
|
||||
let c: fn(_, _) -> _ = ExprIndex;
|
||||
ExprKind::Index(ref a, ref i) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Index;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(a);
|
||||
self.hash_expr(i);
|
||||
},
|
||||
ExprInlineAsm(..) => {
|
||||
let c: fn(_, _, _) -> _ = ExprInlineAsm;
|
||||
ExprKind::InlineAsm(..) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::InlineAsm;
|
||||
c.hash(&mut self.s);
|
||||
},
|
||||
ExprIf(ref cond, ref t, ref e) => {
|
||||
let c: fn(_, _, _) -> _ = ExprIf;
|
||||
ExprKind::If(ref cond, ref t, ref e) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::If;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(cond);
|
||||
self.hash_expr(&**t);
|
||||
|
@ -447,21 +475,21 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(e);
|
||||
}
|
||||
},
|
||||
ExprLit(ref l) => {
|
||||
let c: fn(_) -> _ = ExprLit;
|
||||
ExprKind::Lit(ref l) => {
|
||||
let c: fn(_) -> _ = ExprKind::Lit;
|
||||
c.hash(&mut self.s);
|
||||
l.hash(&mut self.s);
|
||||
},
|
||||
ExprLoop(ref b, ref i, _) => {
|
||||
let c: fn(_, _, _) -> _ = ExprLoop;
|
||||
ExprKind::Loop(ref b, ref i, _) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::Loop;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_block(b);
|
||||
if let Some(i) = *i {
|
||||
self.hash_name(i.ident.name);
|
||||
}
|
||||
},
|
||||
ExprMatch(ref e, ref arms, ref s) => {
|
||||
let c: fn(_, _, _) -> _ = ExprMatch;
|
||||
ExprKind::Match(ref e, ref arms, ref s) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::Match;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
|
||||
|
@ -475,14 +503,14 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
|
||||
s.hash(&mut self.s);
|
||||
},
|
||||
ExprMethodCall(ref path, ref _tys, ref args) => {
|
||||
let c: fn(_, _, _) -> _ = ExprMethodCall;
|
||||
ExprKind::MethodCall(ref path, ref _tys, ref args) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::MethodCall;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_name(path.ident.name);
|
||||
self.hash_exprs(args);
|
||||
},
|
||||
ExprRepeat(ref e, ref l_id) => {
|
||||
let c: fn(_, _) -> _ = ExprRepeat;
|
||||
ExprKind::Repeat(ref e, ref l_id) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Repeat;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
let full_table = self.tables;
|
||||
|
@ -490,20 +518,20 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(&self.cx.tcx.hir.body(l_id.body).value);
|
||||
self.tables = full_table;
|
||||
},
|
||||
ExprRet(ref e) => {
|
||||
let c: fn(_) -> _ = ExprRet;
|
||||
ExprKind::Ret(ref e) => {
|
||||
let c: fn(_) -> _ = ExprKind::Ret;
|
||||
c.hash(&mut self.s);
|
||||
if let Some(ref e) = *e {
|
||||
self.hash_expr(e);
|
||||
}
|
||||
},
|
||||
ExprPath(ref qpath) => {
|
||||
let c: fn(_) -> _ = ExprPath;
|
||||
ExprKind::Path(ref qpath) => {
|
||||
let c: fn(_) -> _ = ExprKind::Path;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_qpath(qpath);
|
||||
},
|
||||
ExprStruct(ref path, ref fields, ref expr) => {
|
||||
let c: fn(_, _, _) -> _ = ExprStruct;
|
||||
ExprKind::Struct(ref path, ref fields, ref expr) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::Struct;
|
||||
c.hash(&mut self.s);
|
||||
|
||||
self.hash_qpath(path);
|
||||
|
@ -517,32 +545,32 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(e);
|
||||
}
|
||||
},
|
||||
ExprTup(ref tup) => {
|
||||
let c: fn(_) -> _ = ExprTup;
|
||||
ExprKind::Tup(ref tup) => {
|
||||
let c: fn(_) -> _ = ExprKind::Tup;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_exprs(tup);
|
||||
},
|
||||
ExprType(ref e, ref _ty) => {
|
||||
let c: fn(_, _) -> _ = ExprType;
|
||||
ExprKind::Type(ref e, ref _ty) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Type;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(e);
|
||||
// TODO: _ty
|
||||
},
|
||||
ExprUnary(lop, ref le) => {
|
||||
let c: fn(_, _) -> _ = ExprUnary;
|
||||
ExprKind::Unary(lop, ref le) => {
|
||||
let c: fn(_, _) -> _ = ExprKind::Unary;
|
||||
c.hash(&mut self.s);
|
||||
|
||||
lop.hash(&mut self.s);
|
||||
self.hash_expr(le);
|
||||
},
|
||||
ExprArray(ref v) => {
|
||||
let c: fn(_) -> _ = ExprArray;
|
||||
ExprKind::Array(ref v) => {
|
||||
let c: fn(_) -> _ = ExprKind::Array;
|
||||
c.hash(&mut self.s);
|
||||
|
||||
self.hash_exprs(v);
|
||||
},
|
||||
ExprWhile(ref cond, ref b, l) => {
|
||||
let c: fn(_, _, _) -> _ = ExprWhile;
|
||||
ExprKind::While(ref cond, ref b, l) => {
|
||||
let c: fn(_, _, _) -> _ = ExprKind::While;
|
||||
c.hash(&mut self.s);
|
||||
|
||||
self.hash_expr(cond);
|
||||
|
@ -585,23 +613,23 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
|
|||
|
||||
pub fn hash_stmt(&mut self, b: &Stmt) {
|
||||
match b.node {
|
||||
StmtDecl(ref decl, _) => {
|
||||
let c: fn(_, _) -> _ = StmtDecl;
|
||||
StmtKind::Decl(ref decl, _) => {
|
||||
let c: fn(_, _) -> _ = StmtKind::Decl;
|
||||
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 {
|
||||
self.hash_expr(init);
|
||||
}
|
||||
}
|
||||
},
|
||||
StmtExpr(ref expr, _) => {
|
||||
let c: fn(_, _) -> _ = StmtExpr;
|
||||
StmtKind::Expr(ref expr, _) => {
|
||||
let c: fn(_, _) -> _ = StmtKind::Expr;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(expr);
|
||||
},
|
||||
StmtSemi(ref expr, _) => {
|
||||
let c: fn(_, _) -> _ = StmtSemi;
|
||||
StmtKind::Semi(ref expr, _) => {
|
||||
let c: fn(_, _) -> _ = StmtKind::Semi;
|
||||
c.hash(&mut self.s);
|
||||
self.hash_expr(expr);
|
||||
},
|
||||
|
|
|
@ -122,8 +122,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
return;
|
||||
}
|
||||
match stmt.node {
|
||||
hir::StmtDecl(ref decl, _) => print_decl(cx, decl),
|
||||
hir::StmtExpr(ref e, _) | hir::StmtSemi(ref e, _) => print_expr(cx, e, 0),
|
||||
hir::StmtKind::Decl(ref decl, _) => print_decl(cx, decl),
|
||||
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
|
||||
|
@ -141,7 +141,7 @@ fn has_attr(attrs: &[Attribute]) -> bool {
|
|||
|
||||
fn print_decl(cx: &LateContext, decl: &hir::Decl) {
|
||||
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!("pattern:");
|
||||
print_pat(cx, &local.pat, 0);
|
||||
|
@ -150,7 +150,7 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) {
|
|||
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!("{}adjustments: {:?}", ind, cx.tables.adjustments().get(expr.hir_id));
|
||||
match expr.node {
|
||||
hir::ExprBox(ref e) => {
|
||||
hir::ExprKind::Box(ref e) => {
|
||||
println!("{}Box", ind);
|
||||
print_expr(cx, e, indent + 1);
|
||||
},
|
||||
hir::ExprArray(ref v) => {
|
||||
hir::ExprKind::Array(ref v) => {
|
||||
println!("{}Array", ind);
|
||||
for e in v {
|
||||
print_expr(cx, e, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::ExprCall(ref func, ref args) => {
|
||||
hir::ExprKind::Call(ref func, ref args) => {
|
||||
println!("{}Call", ind);
|
||||
println!("{}function:", ind);
|
||||
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);
|
||||
}
|
||||
},
|
||||
hir::ExprMethodCall(ref path, _, ref args) => {
|
||||
hir::ExprKind::MethodCall(ref path, _, ref args) => {
|
||||
println!("{}MethodCall", ind);
|
||||
println!("{}method name: {}", ind, path.ident.name);
|
||||
for arg in args {
|
||||
print_expr(cx, arg, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::ExprTup(ref v) => {
|
||||
hir::ExprKind::Tup(ref v) => {
|
||||
println!("{}Tup", ind);
|
||||
for e in v {
|
||||
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!("{}op: {:?}", ind, op.node);
|
||||
println!("{}lhs:", ind);
|
||||
|
@ -200,26 +200,26 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
|
|||
println!("{}rhs:", ind);
|
||||
print_expr(cx, rhs, indent + 1);
|
||||
},
|
||||
hir::ExprUnary(op, ref inner) => {
|
||||
hir::ExprKind::Unary(op, ref inner) => {
|
||||
println!("{}Unary", ind);
|
||||
println!("{}op: {:?}", ind, op);
|
||||
print_expr(cx, inner, indent + 1);
|
||||
},
|
||||
hir::ExprLit(ref lit) => {
|
||||
hir::ExprKind::Lit(ref lit) => {
|
||||
println!("{}Lit", ind);
|
||||
println!("{}{:?}", ind, lit);
|
||||
},
|
||||
hir::ExprCast(ref e, ref target) => {
|
||||
hir::ExprKind::Cast(ref e, ref target) => {
|
||||
println!("{}Cast", ind);
|
||||
print_expr(cx, e, indent + 1);
|
||||
println!("{}target type: {:?}", ind, target);
|
||||
},
|
||||
hir::ExprType(ref e, ref target) => {
|
||||
hir::ExprKind::Type(ref e, ref target) => {
|
||||
println!("{}Type", ind);
|
||||
print_expr(cx, e, indent + 1);
|
||||
println!("{}target type: {:?}", ind, target);
|
||||
},
|
||||
hir::ExprIf(ref e, _, ref els) => {
|
||||
hir::ExprKind::If(ref e, _, ref els) => {
|
||||
println!("{}If", ind);
|
||||
println!("{}condition:", ind);
|
||||
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);
|
||||
}
|
||||
},
|
||||
hir::ExprWhile(ref cond, _, _) => {
|
||||
hir::ExprKind::While(ref cond, _, _) => {
|
||||
println!("{}While", ind);
|
||||
println!("{}condition:", ind);
|
||||
print_expr(cx, cond, indent + 1);
|
||||
},
|
||||
hir::ExprLoop(..) => {
|
||||
hir::ExprKind::Loop(..) => {
|
||||
println!("{}Loop", ind);
|
||||
},
|
||||
hir::ExprMatch(ref cond, _, ref source) => {
|
||||
hir::ExprKind::Match(ref cond, _, ref source) => {
|
||||
println!("{}Match", ind);
|
||||
println!("{}condition:", ind);
|
||||
print_expr(cx, cond, indent + 1);
|
||||
println!("{}source: {:?}", ind, source);
|
||||
},
|
||||
hir::ExprClosure(ref clause, _, _, _, _) => {
|
||||
hir::ExprKind::Closure(ref clause, _, _, _, _) => {
|
||||
println!("{}Closure", ind);
|
||||
println!("{}clause: {:?}", ind, clause);
|
||||
},
|
||||
hir::ExprYield(ref sub) => {
|
||||
hir::ExprKind::Yield(ref sub) => {
|
||||
println!("{}Yield", ind);
|
||||
print_expr(cx, sub, indent + 1);
|
||||
},
|
||||
hir::ExprBlock(_, _) => {
|
||||
hir::ExprKind::Block(_, _) => {
|
||||
println!("{}Block", ind);
|
||||
},
|
||||
hir::ExprAssign(ref lhs, ref rhs) => {
|
||||
hir::ExprKind::Assign(ref lhs, ref rhs) => {
|
||||
println!("{}Assign", ind);
|
||||
println!("{}lhs:", ind);
|
||||
print_expr(cx, lhs, indent + 1);
|
||||
println!("{}rhs:", ind);
|
||||
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!("{}op: {:?}", ind, binop.node);
|
||||
println!("{}lhs:", ind);
|
||||
|
@ -268,46 +268,46 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
|
|||
println!("{}rhs:", ind);
|
||||
print_expr(cx, rhs, indent + 1);
|
||||
},
|
||||
hir::ExprField(ref e, ident) => {
|
||||
hir::ExprKind::Field(ref e, ident) => {
|
||||
println!("{}Field", ind);
|
||||
println!("{}field name: {}", ind, ident.name);
|
||||
println!("{}struct expr:", ind);
|
||||
print_expr(cx, e, indent + 1);
|
||||
},
|
||||
hir::ExprIndex(ref arr, ref idx) => {
|
||||
hir::ExprKind::Index(ref arr, ref idx) => {
|
||||
println!("{}Index", ind);
|
||||
println!("{}array expr:", ind);
|
||||
print_expr(cx, arr, indent + 1);
|
||||
println!("{}index expr:", ind);
|
||||
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!("{}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!("{}seg: {:?}", ind, seg);
|
||||
},
|
||||
hir::ExprAddrOf(ref muta, ref e) => {
|
||||
hir::ExprKind::AddrOf(ref muta, ref e) => {
|
||||
println!("{}AddrOf", ind);
|
||||
println!("mutability: {:?}", muta);
|
||||
print_expr(cx, e, indent + 1);
|
||||
},
|
||||
hir::ExprBreak(_, ref e) => {
|
||||
hir::ExprKind::Break(_, ref e) => {
|
||||
println!("{}Break", ind);
|
||||
if let Some(ref e) = *e {
|
||||
print_expr(cx, e, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::ExprContinue(_) => println!("{}Again", ind),
|
||||
hir::ExprRet(ref e) => {
|
||||
hir::ExprKind::Continue(_) => println!("{}Again", ind),
|
||||
hir::ExprKind::Ret(ref e) => {
|
||||
println!("{}Ret", ind);
|
||||
if let Some(ref e) = *e {
|
||||
print_expr(cx, e, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::ExprInlineAsm(_, ref input, ref output) => {
|
||||
hir::ExprKind::InlineAsm(_, ref input, ref output) => {
|
||||
println!("{}InlineAsm", ind);
|
||||
println!("{}inputs:", ind);
|
||||
for e in input {
|
||||
|
@ -318,7 +318,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
|
|||
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!("{}path: {:?}", ind, path);
|
||||
for field in fields {
|
||||
|
@ -330,7 +330,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
|
|||
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!("{}value:", ind);
|
||||
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"),
|
||||
}
|
||||
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);
|
||||
if let Some(crate_id) = cx.tcx.extern_mod_stmt_cnum(def_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");
|
||||
}
|
||||
},
|
||||
hir::ItemUse(ref path, ref kind) => println!("{:?}, {:?}", path, kind),
|
||||
hir::ItemStatic(..) => println!("static item of type {:#?}", cx.tcx.type_of(did)),
|
||||
hir::ItemConst(..) => println!("const item of type {:#?}", cx.tcx.type_of(did)),
|
||||
hir::ItemFn(..) => {
|
||||
hir::ItemKind::Use(ref path, ref kind) => println!("{:?}, {:?}", path, kind),
|
||||
hir::ItemKind::Static(..) => println!("static item of type {:#?}", cx.tcx.type_of(did)),
|
||||
hir::ItemKind::Const(..) => println!("const item of type {:#?}", cx.tcx.type_of(did)),
|
||||
hir::ItemKind::Fn(..) => {
|
||||
let item_ty = cx.tcx.type_of(did);
|
||||
println!("function of type {:#?}", item_ty);
|
||||
},
|
||||
hir::ItemMod(..) => println!("module"),
|
||||
hir::ItemForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi),
|
||||
hir::ItemGlobalAsm(ref asm) => println!("global asm: {:?}", asm),
|
||||
hir::ItemTy(..) => {
|
||||
hir::ItemKind::Mod(..) => println!("module"),
|
||||
hir::ItemKind::ForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi),
|
||||
hir::ItemKind::GlobalAsm(ref asm) => println!("global asm: {:?}", asm),
|
||||
hir::ItemKind::Ty(..) => {
|
||||
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));
|
||||
},
|
||||
hir::ItemEnum(..) => {
|
||||
hir::ItemKind::Enum(..) => {
|
||||
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));
|
||||
},
|
||||
hir::ItemUnion(..) => {
|
||||
hir::ItemKind::Union(..) => {
|
||||
println!("union definition of type {:?}", cx.tcx.type_of(did));
|
||||
},
|
||||
hir::ItemTrait(..) => {
|
||||
hir::ItemKind::Trait(..) => {
|
||||
println!("trait decl");
|
||||
if cx.tcx.trait_is_auto(did) {
|
||||
println!("trait is auto");
|
||||
|
@ -400,13 +400,13 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
|
|||
println!("trait is not auto");
|
||||
}
|
||||
},
|
||||
hir::ItemTraitAlias(..) => {
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
println!("trait alias");
|
||||
}
|
||||
hir::ItemImpl(_, _, _, _, Some(ref _trait_ref), _, _) => {
|
||||
hir::ItemKind::Impl(_, _, _, _, Some(ref _trait_ref), _, _) => {
|
||||
println!("trait impl");
|
||||
},
|
||||
hir::ItemImpl(_, _, _, _, None, _, _) => {
|
||||
hir::ItemKind::Impl(_, _, _, _, None, _, _) => {
|
||||
println!("impl");
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use crate::utils::{match_qpath, paths, span_lint};
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
@ -117,15 +118,17 @@ impl LintPass for LintWithoutLintPass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
||||
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) {
|
||||
self.declared_lints.insert(item.name, item.span);
|
||||
} else if is_lint_array_type(ty) && item.vis.node == VisibilityKind::Inherited && item.name == "ARRAY" {
|
||||
let mut collector = LintCollector {
|
||||
output: &mut self.registered_lints,
|
||||
cx,
|
||||
};
|
||||
collector.visit_expr(&cx.tcx.hir.body(body_id).value);
|
||||
} else if is_lint_array_type(ty) && item.name == "ARRAY" {
|
||||
if let VisibilityKind::Inherited = item.vis.node {
|
||||
let mut collector = LintCollector {
|
||||
output: &mut self.registered_lints,
|
||||
cx,
|
||||
};
|
||||
collector.visit_expr(&cx.tcx.hir.body(body_id).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +163,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
|||
|
||||
|
||||
fn is_lint_ref_type(ty: &Ty) -> bool {
|
||||
if let TyRptr(
|
||||
if let TyKind::Rptr(
|
||||
_,
|
||||
MutTy {
|
||||
ty: ref inner,
|
||||
|
@ -168,7 +171,7 @@ fn is_lint_ref_type(ty: &Ty) -> bool {
|
|||
},
|
||||
) = ty.node
|
||||
{
|
||||
if let TyPath(ref path) = inner.node {
|
||||
if let TyKind::Path(ref path) = inner.node {
|
||||
return match_qpath(path, &paths::LINT);
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +180,7 @@ fn is_lint_ref_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)
|
||||
} else {
|
||||
false
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue