diff --git a/.travis.yml b/.travis.yml index 97f31b18684..c6bd67ae0f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,8 +48,6 @@ matrix: - env: INTEGRATION=serde-rs/serde - env: INTEGRATION=Geal/nom - env: INTEGRATION=hyperium/hyper - - env: INTEGRATION=rust-lang/cargo - - env: INTEGRATION=rust-lang-nursery/rls script: - | diff --git a/CHANGELOG.md b/CHANGELOG.md index a341424ef5e..48585df0603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Change Log All notable changes to this project will be documented in this file. +## 0.0.212 +* Rustup to *rustc 1.29.0-nightly (e06c87544 2018-07-06)* + ## 0.0.211 * Rustup to *rustc 1.28.0-nightly (e3bf634e0 2018-06-28)* @@ -504,7 +507,7 @@ All notable changes to this project will be documented in this file. ## 0.0.74 — 2016-06-07 * Fix bug with `cargo-clippy` JSON parsing * Add the `CLIPPY_DISABLE_DOCS_LINKS` environment variable to deactivate the - “for further information visit *wiki-link*” message. + “for further information visit *lint-link*” message. ## 0.0.73 — 2016-06-05 * Fix false positives in [`useless_let_if_seq`] @@ -609,7 +612,7 @@ All notable changes to this project will be documented in this file. [`AsRef`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html [configuration file]: ./rust-clippy#configuration -<!-- begin autogenerated links to wiki --> +<!-- begin autogenerated links to lint list --> [`absurd_extreme_comparisons`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons [`almost_swapped`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#almost_swapped [`approx_constant`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#approx_constant @@ -744,6 +747,7 @@ All notable changes to this project will be documented in this file. [`misaligned_transmute`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#misaligned_transmute [`misrefactored_assign_op`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#misrefactored_assign_op [`missing_docs_in_private_items`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#missing_docs_in_private_items +[`missing_inline_in_public_items`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#missing_inline_in_public_items [`mixed_case_hex_literals`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#mixed_case_hex_literals [`module_inception`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#module_inception [`modulo_one`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#modulo_one @@ -890,4 +894,4 @@ All notable changes to this project will be documented in this file. [`zero_prefixed_literal`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#zero_prefixed_literal [`zero_ptr`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#zero_ptr [`zero_width_space`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#zero_width_space -<!-- end autogenerated links to wiki --> +<!-- end autogenerated links to lint list --> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09f4f34b98d..293418416a2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to rust-clippy +# Contributing to Clippy Hello fellow Rustacean! Great to see your interest in compiler internals and lints! @@ -63,7 +63,7 @@ an AST expression). `match_def_path()` in Clippy's `utils` module can also be us ## Writing code -Compiling clippy from scratch can take almost a minute or more depending on your machine. +Compiling Clippy from scratch can take almost a minute or more depending on your machine. However, since Rust 1.24.0 incremental compilation is enabled by default and compile times for small changes should be quick. [Llogiq's blog post on lints](https://llogiq.github.io/2015/06/04/workflows.html) is a nice primer @@ -74,7 +74,7 @@ of this. ### Author lint -There is also the internal `author` lint to generate clippy code that detects the offending pattern. It does not work for all of the Rust syntax, but can give a good starting point. +There is also the internal `author` lint to generate Clippy code that detects the offending pattern. It does not work for all of the Rust syntax, but can give a good starting point. First, create a new UI test file in the `tests/ui/` directory with the pattern you want to match: @@ -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 @@ -148,7 +148,7 @@ Therefore you should use `tests/ui/update-all-references.sh` (after running ### Testing manually Manually testing against an example file is useful if you have added some -`println!`s and test suite output becomes unreadable. To try clippy with your +`println!`s and test suite output becomes unreadable. To try Clippy with your local modifications, run `cargo run --bin clippy-driver -- -L ./target/debug input.rs` from the working copy root. @@ -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 diff --git a/Cargo.toml b/Cargo.toml index 72d2d8cc6ba..7c9fe251237 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["edition"] [package] name = "clippy" -version = "0.0.211" +version = "0.0.212" authors = [ "Manish Goregaokar <manishsmail@gmail.com>", "Andre Bogus <bogusandre@gmail.com>", @@ -40,11 +40,51 @@ path = "src/driver.rs" [dependencies] # begin automatic update -clippy_lints = { version = "0.0.211", path = "clippy_lints" } +clippy_lints = { version = "0.0.212", path = "clippy_lints" } # end automatic update regex = "1" semver = "0.9" +# Not actually needed right now but required to make sure that clippy/ and cargo build +# with the same set of features in rust-lang/rust +num-traits = "0.2" # enable the default feature +backtrace = "0.3" + +# keep in sync with `cargo`'s `Cargo.toml' +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = [ + # keep in sync with `cargo`'s `Cargo.toml' + "handleapi", + "jobapi", + "jobapi2", + "minwindef", + "ntdef", + "ntstatus", + "processenv", + "processthreadsapi", + "psapi", + "synchapi", + "winerror", + "winbase", + "wincon", + "winnt", + # no idea where these come from + "basetsd", + "lmcons", + "memoryapi", + "minschannel", + "minwinbase", + "ntsecapi", + "profileapi", + "schannel", + "securitybaseapi", + "synchapi", + "sysinfoapi", + "timezoneapi", + "wincrypt", +] + [dev-dependencies] cargo_metadata = "0.5" compiletest_rs = "0.3.7" diff --git a/PUBLISH.md b/PUBLISH.md index a9496d5b414..749eae97304 100644 --- a/PUBLISH.md +++ b/PUBLISH.md @@ -1,7 +1,8 @@ -Steps to publish a new clippy version +Steps to publish a new Clippy version - Bump `package.version` in `./Cargo.toml` (no need to manually bump `dependencies.clippy_lints.version`). - Write a changelog entry. +- If a nightly update is needed, update `min_version.txt` using `rustc -vV > min_version.txt` - Run `./pre_publish.sh` - Review and commit all changed files - `git push` diff --git a/README.md b/README.md index 05496fc1ccc..41eacdba1a4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -We are currently in the process of discussing Clippy 1.0 via the RFC process in https://github.com/rust-lang/rfcs/pull/2476 . The RFC's goal is to clarify policies around lint categorizations and the policy around which lints should be in the compiler and which lints should be in clippy. Please leave your thoughts on the RFC PR. +We are currently in the process of discussing Clippy 1.0 via the RFC process in https://github.com/rust-lang/rfcs/pull/2476 . The RFC's goal is to clarify policies around lint categorizations and the policy around which lints should be in the compiler and which lints should be in Clippy. Please leave your thoughts on the RFC PR. -# rust-clippy +# Clippy [](https://travis-ci.org/rust-lang-nursery/rust-clippy) [](https://ci.appveyor.com/project/rust-lang-libs/rust-clippy) @@ -9,9 +9,9 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 272 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) +[There are 273 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) -We have a bunch of lint categories to allow you to choose how much clippy is supposed to ~~annoy~~ help you: +We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: * `clippy` (everything that has no false positives) * `clippy_pedantic` (everything) @@ -33,49 +33,51 @@ Table of contents: ## Usage 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. +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`. If nightly is your +default toolchain in rustup, `cargo clippy` will work fine. -Now you can run clippy by invoking `cargo +nightly clippy`. +### Running Clippy from the command line without installing it -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 -``` - -### Running clippy from the command line without installing it - -To have cargo compile your crate with clippy without clippy installation +To have cargo compile your crate with Clippy without Clippy installation in your code, you can use: ```terminal @@ -83,7 +85,7 @@ cargo run --bin cargo-clippy --manifest-path=path_to_clippys_Cargo.toml ``` *[Note](https://github.com/rust-lang-nursery/rust-clippy/wiki#a-word-of-warning):* -Be sure that clippy was compiled with the same version of rustc that cargo invokes here! +Be sure that Clippy was compiled with the same version of rustc that cargo invokes here! ## Configuration @@ -117,7 +119,7 @@ You can add options to `allow`/`warn`/`deny`: Note: `deny` produces errors instead of warnings. For convenience, `cargo clippy` automatically defines a `cargo-clippy` -feature. This lets you set lint levels and compile with or without clippy +feature. This lets you set lint levels and compile with or without Clippy transparently: ```rust @@ -126,12 +128,12 @@ transparently: ## Updating rustc -Sometimes, rustc moves forward without clippy catching up. Therefore updating -rustc may leave clippy a non-functional state until we fix the resulting +Sometimes, rustc moves forward without Clippy catching up. Therefore updating +rustc may leave Clippy a non-functional state until we fix the resulting breakage. You can use the [rust-update](rust-update) script to update rustc only if -clippy would also update correctly. +Clippy would also update correctly. ## License diff --git a/build.rs b/build.rs index 241c8579a48..9d05678f718 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,8 @@ -//! This build script ensures that clippy is not compiled with an +//! This build script ensures that Clippy is not compiled with an //! incompatible version of rust. It will panic with a descriptive //! error message instead. //! -//! We specifially want to ensure that clippy is only built with a +//! We specifially want to ensure that Clippy is only built with a //! rustc version that is newer or equal to the one specified in the //! `min_version.txt` file. //! @@ -63,7 +63,7 @@ fn check_rustc_version() { eprintln!( "\n{} {}", Red.bold().paint("error:"), - "clippy requires a nightly version of Rust." + "Clippy requires a nightly version of Rust." ); print_version_err(¤t_version, &*current_date_str); eprintln!( @@ -80,7 +80,7 @@ fn check_rustc_version() { eprintln!( "\n{} {}", Red.bold().paint("error:"), - "clippy does not support this version of rustc nightly." + "Clippy does not support this version of rustc nightly." ); eprintln!( "> {}{}{}", diff --git a/ci/base-tests.sh b/ci/base-tests.sh index 37c13fe069e..4b304f6f2a6 100755 --- a/ci/base-tests.sh +++ b/ci/base-tests.sh @@ -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 ../.. diff --git a/ci/integration-tests.sh b/ci/integration-tests.sh index 28785f633c3..a989b261ac7 100755 --- a/ci/integration-tests.sh +++ b/ci/integration-tests.sh @@ -1,4 +1,5 @@ set -x +rm ~/.cargo/bin/cargo-clippy cargo install --force --path . echo "Running integration test for crate ${INTEGRATION}" diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index e7ad3b1b759..5c3af20bde8 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -3,7 +3,7 @@ cargo-features = ["edition"] [package] name = "clippy_lints" # begin automatic update -version = "0.0.211" +version = "0.0.212" # end automatic update authors = [ "Manish Goregaokar <manishsmail@gmail.com>", @@ -21,8 +21,8 @@ edition = "2018" [dependencies] cargo_metadata = "0.5" itertools = "0.7" -lazy_static = "1.0" -matches = "0.1.2" +lazy_static = "1.0.2" +matches = "0.1.7" quine-mc_cluskey = "0.2.2" regex-syntax = "0.6" semver = "0.9.0" @@ -32,7 +32,7 @@ toml = "0.4" unicode-normalization = "0.1" pulldown-cmark = "0.1" url = "1.7.0" -if_chain = "0.1" +if_chain = "0.1.3" [features] debugging = [] diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index d3741d78801..cd2444ff31f 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -1,6 +1,7 @@ use crate::utils::span_lint; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use std::f64::consts as f64; use syntax::ast::{FloatTy, Lit, LitKind}; use syntax::symbol; @@ -63,13 +64,13 @@ 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); } } } -fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) { +fn check_lit(cx: &LateContext<'_, '_>, lit: &Lit, e: &Expr) { match lit.node { LitKind::Float(s, FloatTy::F32) => check_known_consts(cx, e, s, "f32"), LitKind::Float(s, FloatTy::F64) => check_known_consts(cx, e, s, "f64"), @@ -78,7 +79,7 @@ fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) { } } -fn check_known_consts(cx: &LateContext, e: &Expr, s: symbol::Symbol, module: &str) { +fn check_known_consts(cx: &LateContext<'_, '_>, e: &Expr, s: symbol::Symbol, module: &str) { let s = s.as_str(); if s.parse::<f64>().is_ok() { for &(constant, name, min_digits) in KNOWN_CONSTS { diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index a9ccc336a19..b3d78d2d13f 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -1,6 +1,7 @@ use crate::utils::span_lint; use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Span; /// **What it does:** Checks for plain integer arithmetic. @@ -55,21 +56,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 +82,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"); diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index ba405610c90..1ce690abcfe 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -3,6 +3,8 @@ use crate::utils::{higher, sugg}; use rustc::hir; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast; /// **What it does:** Checks for compound assignment operations (`+=` and @@ -49,8 +51,10 @@ declare_clippy_lint! { /// **Why is this bad?** Most likely these are bugs where one meant to write `a /// op= b`. /// -/// **Known problems:** Someone might actually mean `a op= a op b`, but that -/// should rather be written as `a = (2 * a) op b` where applicable. +/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have +/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both. +/// If `a op= a op b` is really the correct behaviour it should be +/// written as `a = a op a op b` as it's less confusing. /// /// **Example:** /// ```rust @@ -76,7 +80,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 +91,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 +135,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 +146,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 +163,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 +179,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 +228,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 +248,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, } } diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index b9d8976b28b..3d25f524afd 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -7,6 +7,8 @@ use crate::utils::{ }; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, TyCtxt}; use semver::Version; use syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; @@ -39,22 +41,31 @@ declare_clippy_lint! { } /// **What it does:** Checks for `extern crate` and `use` items annotated with -/// lint attributes +/// lint attributes. +/// +/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on +/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a +/// `#[macro_use]` attribute. /// /// **Why is this bad?** Lint attributes have no effect on crate imports. Most -/// likely a `!` was -/// forgotten +/// likely a `!` was forgotten. /// -/// **Known problems:** Technically one might allow `unused_import` on a `use` -/// item, -/// but it's easier to remove the unused item. +/// **Known problems:** None. /// /// **Example:** /// ```rust +/// // Bad /// #[deny(dead_code)] /// extern crate foo; -/// #[allow(unused_import)] +/// #[forbid(dead_code)] /// use foo::bar; +/// +/// // Ok +/// #[allow(unused_imports)] +/// use foo::baz; +/// #[allow(unused_imports)] +/// #[macro_use] +/// extern crate baz; /// ``` declare_clippy_lint! { pub USELESS_ATTRIBUTE, @@ -154,17 +165,26 @@ 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(..) => { + let skip_unused_imports = item.attrs.iter().any(|attr| attr.name() == "macro_use"); + for attr in &item.attrs { if let Some(ref lint_list) = attr.meta_item_list() { match &*attr.name().as_str() { "allow" | "warn" | "deny" | "forbid" => { - // whitelist `unused_imports` and `deprecated` + // whitelist `unused_imports` and `deprecated` for `use` items + // and `unused_imports` for `extern crate` items with `macro_use` for lint in lint_list { - if is_word(lint, "unused_imports") || is_word(lint, "deprecated") { - if let ItemUse(_, _) = item.node { - return; - } + match item.node { + ItemKind::Use(..) => if is_word(lint, "unused_imports") + || is_word(lint, "deprecated") { + return + }, + ItemKind::ExternCrate(..) => if is_word(lint, "unused_imports") + && skip_unused_imports { + return + }, + _ => {}, } } let line_span = last_line_of_span(cx, attr.span); @@ -206,22 +226,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass { } } -fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool { - if let ItemFn(_, _, _, eid) = item.node { +fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool { + if let ItemKind::Fn(_, _, _, eid) = item.node { is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value) } else { true } } -fn is_relevant_impl(tcx: TyCtxt, item: &ImplItem) -> bool { +fn is_relevant_impl(tcx: TyCtxt<'_, '_, '_>, item: &ImplItem) -> bool { match item.node { ImplItemKind::Method(_, eid) => is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value), _ => false, } } -fn is_relevant_trait(tcx: TyCtxt, item: &TraitItem) -> bool { +fn is_relevant_trait(tcx: TyCtxt<'_, '_, '_>, item: &TraitItem) -> bool { match item.node { TraitItemKind::Method(_, TraitMethod::Required(_)) => true, TraitItemKind::Method(_, TraitMethod::Provided(eid)) => { @@ -231,23 +251,23 @@ fn is_relevant_trait(tcx: TyCtxt, item: &TraitItem) -> bool { } } -fn is_relevant_block(tcx: TyCtxt, tables: &ty::TypeckTables, block: &Block) -> bool { +fn is_relevant_block(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, block: &Block) -> bool { if let Some(stmt) = block.stmts.first() { 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)) } } -fn is_relevant_expr(tcx: TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool { +fn is_relevant_expr(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, expr: &Expr) -> bool { match expr.node { - 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 { @@ -260,7 +280,7 @@ fn is_relevant_expr(tcx: TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool } } -fn check_attrs(cx: &LateContext, span: Span, name: Name, attrs: &[Attribute]) { +fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attribute]) { if in_macro(span) { return; } @@ -311,7 +331,7 @@ fn check_attrs(cx: &LateContext, span: Span, name: Name, attrs: &[Attribute]) { } } -fn check_semver(cx: &LateContext, span: Span, lit: &Lit) { +fn check_semver(cx: &LateContext<'_, '_>, span: Span, lit: &Lit) { if let LitKind::Str(ref is, _) = lit.node { if Version::parse(&is.as_str()).is_ok() { return; @@ -338,7 +358,7 @@ fn is_word(nmi: &NestedMetaItem, expected: &str) -> bool { // sources that the user has no control over. // For some reason these attributes don't have any expansion info on them, so // we have to check it this way until there is a better way. -fn is_present_in_source(cx: &LateContext, span: Span) -> bool { +fn is_present_in_source(cx: &LateContext<'_, '_>, span: Span) -> bool { if let Some(snippet) = snippet_opt(cx, span) { if snippet.is_empty() { return false; diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs index 9f548b9e320..249ebbde2f7 100644 --- a/clippy_lints/src/bit_mask.rs +++ b/clippy_lints/src/bit_mask.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast::LitKind; use syntax::codemap::Span; use crate::utils::{span_lint, span_lint_and_then}; @@ -109,7 +111,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 +121,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 +145,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 +169,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 +188,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 +202,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 +217,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 +231,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 +249,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,14 +263,14 @@ 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, "^"), _ => (), }, _ => (), } } -fn check_ineffective_lt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str) { +fn check_ineffective_lt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, op: &str) { if c.is_power_of_two() && m < c { span_lint( cx, @@ -284,7 +286,7 @@ fn check_ineffective_lt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str } } -fn check_ineffective_gt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str) { +fn check_ineffective_gt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, op: &str) { if (c + 1).is_power_of_two() && m <= c { span_lint( cx, @@ -300,7 +302,7 @@ fn check_ineffective_gt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str } } -fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option<u128> { +fn fetch_int_literal(cx: &LateContext<'_, '_>, lit: &Expr) -> Option<u128> { match constant(cx, cx.tables, lit)?.0 { Constant::Int(n) => Some(n), _ => None, diff --git a/clippy_lints/src/blacklisted_name.rs b/clippy_lints/src/blacklisted_name.rs index 29660399233..cfec01d14ae 100644 --- a/clippy_lints/src/blacklisted_name.rs +++ b/clippy_lints/src/blacklisted_name.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::span_lint; diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index 5f484341186..f57a3571b57 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -1,4 +1,6 @@ +use matches::matches; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use crate::utils::*; @@ -56,10 +58,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 +79,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 { diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index b541bfc6b2f..f1596476bfd 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -1,4 +1,5 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::hir::intravisit::*; use syntax::ast::{LitKind, NodeId, DUMMY_NODE_ID}; @@ -84,9 +85,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 +102,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 +122,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 +134,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 +179,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) { @@ -274,7 +275,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> { } // The boolean part of the return indicates whether some simplifications have been applied. -fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> (String, bool) { +fn suggest(cx: &LateContext<'_, '_>, suggestion: &Bool, terminals: &[&Expr]) -> (String, bool) { let mut suggest_context = SuggestContext { terminals, cx, @@ -441,8 +442,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); diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index 6f2ea320f93..2d4279d3cc1 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use syntax::ast::{Name, UintTy}; use crate::utils::{contains_name, get_pat_name, match_type, paths, single_segment_path, snippet, span_lint_and_sugg, @@ -36,22 +38,22 @@ impl LintPass for ByteCount { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { - fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) { if_chain! { - if 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 +68,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 +100,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, } } diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 786148f6eec..2771006aad3 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -13,6 +13,8 @@ //! This lint is **warn** by default use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast; use crate::utils::{in_macro, snippet_block, span_lint_and_sugg, span_lint_and_then}; @@ -78,14 +80,14 @@ impl LintPass for CollapsibleIf { } impl EarlyLintPass for CollapsibleIf { - fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { if !in_macro(expr.span) { check_if(cx, expr) } } } -fn check_if(cx: &EarlyContext, expr: &ast::Expr) { +fn check_if(cx: &EarlyContext<'_>, expr: &ast::Expr) { match expr.node { ast::ExprKind::If(ref check, ref then, ref else_) => if let Some(ref else_) = *else_ { check_collapsible_maybe_if_let(cx, else_); @@ -99,7 +101,7 @@ fn check_if(cx: &EarlyContext, expr: &ast::Expr) { } } -fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) { +fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { if_chain! { if let ast::ExprKind::Block(ref block, _) = else_.node; if let Some(else_) = expr_block(block); @@ -120,7 +122,7 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) { } } -fn check_collapsible_no_if_let(cx: &EarlyContext, expr: &ast::Expr, check: &ast::Expr, then: &ast::Block) { +fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: &ast::Expr, then: &ast::Block) { if_chain! { if let Some(inner) = expr_block(then); if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node; diff --git a/clippy_lints/src/const_static_lifetime.rs b/clippy_lints/src/const_static_lifetime.rs index bde5ee4dc8b..1af0741d67f 100644 --- a/clippy_lints/src/const_static_lifetime.rs +++ b/clippy_lints/src/const_static_lifetime.rs @@ -1,5 +1,6 @@ use syntax::ast::*; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use crate::utils::{in_macro, snippet, span_lint_and_then}; /// **What it does:** Checks for constants with an explicit `'static` lifetime. @@ -34,7 +35,7 @@ impl LintPass for StaticConst { impl StaticConst { // Recursively visit types - fn visit_type(&mut self, ty: &Ty, cx: &EarlyContext) { + fn visit_type(&mut self, ty: &Ty, cx: &EarlyContext<'_>) { match ty.node { // Be careful of nested structures (arrays and tuples) TyKind::Array(ref ty, _) => { @@ -78,7 +79,7 @@ impl StaticConst { } impl EarlyLintPass for StaticConst { - fn check_item(&mut self, cx: &EarlyContext, item: &Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { if !in_macro(item.span) { // Match only constants... if let ItemKind::Const(ref var_type, _) = item.node { diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 36417cd0877..84167553a54 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -2,6 +2,7 @@ #![allow(float_cmp)] use rustc::lint::LateContext; +use rustc::{span_bug, bug}; use rustc::hir::def::Def; use rustc::hir::*; use rustc::ty::{self, Ty, TyCtxt, Instance}; @@ -13,7 +14,6 @@ use std::mem; use std::rc::Rc; use syntax::ast::{FloatTy, LitKind}; use syntax::ptr::P; -use rustc::middle::const_val::ConstVal; use crate::utils::{sext, unsext, clip}; #[derive(Debug, Copy, Clone)] @@ -123,7 +123,7 @@ impl Hash for Constant { } impl Constant { - pub fn partial_cmp(tcx: TyCtxt, cmp_type: &ty::TypeVariants, left: &Self, right: &Self) -> Option<Ordering> { + pub fn partial_cmp(tcx: TyCtxt<'_, '_, '_>, cmp_type: &ty::TypeVariants<'_>, left: &Self, right: &Self) -> Option<Ordering> { match (left, right) { (&Constant::Str(ref ls), &Constant::Str(ref rs)) => Some(ls.cmp(rs)), (&Constant::Char(ref l), &Constant::Char(ref r)) => Some(l.cmp(r)), @@ -212,31 +212,31 @@ 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, } } - fn constant_not(&self, o: &Constant, ty: ty::Ty) -> Option<Constant> { + fn constant_not(&self, o: &Constant, ty: ty::Ty<'_>) -> Option<Constant> { use self::Constant::*; match *o { Bool(b) => Some(Bool(!b)), @@ -252,7 +252,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { } } - fn constant_negate(&self, o: &Constant, ty: ty::Ty) -> Option<Constant> { + fn constant_negate(&self, o: &Constant, ty: ty::Ty<'_>) -> Option<Constant> { use self::Constant::*; match *o { Int(value) => { @@ -280,7 +280,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 { @@ -341,43 +341,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, } }, @@ -385,40 +385,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, }, } @@ -428,7 +428,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<'tcx>) -> Option<Constant> { use rustc::mir::interpret::{Scalar, ConstValue}; match result.val { - ConstVal::Value(ConstValue::Scalar(Scalar::Bits{ bits: b, ..})) => match result.ty.sty { + ConstValue::Scalar(Scalar::Bits{ bits: b, ..}) => match result.ty.sty { ty::TyBool => Some(Constant::Bool(b == 1)), ty::TyUint(_) | ty::TyInt(_) => Some(Constant::Int(b)), ty::TyFloat(FloatTy::F32) => Some(Constant::F32(f32::from_bits(b as u32))), @@ -436,7 +436,7 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<' // FIXME: implement other conversion _ => None, }, - ConstVal::Value(ConstValue::ScalarPair(Scalar::Ptr(ptr), Scalar::Bits { bits: n, .. })) => match result.ty.sty { + ConstValue::ScalarPair(Scalar::Ptr(ptr), Scalar::Bits { bits: n, .. }) => match result.ty.sty { ty::TyRef(_, tam, _) => match tam.sty { ty::TyStr => { let alloc = tcx diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 430ff59cd4d..5709526c600 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty::Ty; use rustc::hir::*; use std::collections::HashMap; @@ -115,7 +116,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) { @@ -133,7 +134,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { } /// Implementation of `IF_SAME_THEN_ELSE`. -fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) { +fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block]) { let eq: &dyn Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) }; if let Some((i, j)) = search_same_sequenced(blocks, eq) { @@ -149,7 +150,7 @@ fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) { } /// Implementation of `IFS_SAME_COND`. -fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) { +fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr]) { let hash: &dyn Fn(&&Expr) -> u64 = &|expr| -> u64 { let mut h = SpanlessHash::new(cx, cx.tables); h.hash_expr(expr); @@ -171,8 +172,8 @@ 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 { +fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) { + 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 +237,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 +254,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); } } diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs index ea5f5cf9b58..d66e6f2849b 100644 --- a/clippy_lints/src/cyclomatic_complexity.rs +++ b/clippy_lints/src/cyclomatic_complexity.rs @@ -2,6 +2,7 @@ use rustc::cfg::CFG; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::ty; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; @@ -147,14 +148,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 +168,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), } } @@ -186,7 +187,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> { #[cfg(feature = "debugging")] #[allow(too_many_arguments)] -fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, _: NodeId) { +fn report_cc_bug(_: &LateContext<'_, '_>, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, _: NodeId) { span_bug!( span, "Clippy encountered a bug calculating cyclomatic complexity: cc = {}, arms = {}, \ @@ -200,7 +201,7 @@ fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, re } #[cfg(not(feature = "debugging"))] #[allow(too_many_arguments)] -fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, id: NodeId) { +fn report_cc_bug(cx: &LateContext<'_, '_>, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, id: NodeId) { if !is_allowed(cx, CYCLOMATIC_COMPLEXITY, id) { cx.sess().span_note_without_error( span, diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 30dcafc2daf..4078237e8aa 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::TypeVariants; use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg}; @@ -38,9 +40,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 { diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 364c019c486..0689ef25c20 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use rustc::hir::*; use syntax::codemap::Span; @@ -70,7 +72,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); diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index dfd59af9adb..2b11e8fa77d 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -1,6 +1,7 @@ use itertools::Itertools; use pulldown_cmark; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast; use syntax::codemap::{BytePos, Span}; use syntax_pos::Pos; @@ -51,11 +52,11 @@ impl LintPass for Doc { } impl EarlyLintPass for Doc { - fn check_crate(&mut self, cx: &EarlyContext, krate: &ast::Crate) { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) { check_attrs(cx, &self.valid_idents, &krate.attrs); } - fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { check_attrs(cx, &self.valid_idents, &item.attrs); } } @@ -138,7 +139,7 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<( panic!("not a doc-comment: {}", comment); } -pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [ast::Attribute]) { +pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &[String], attrs: &'a [ast::Attribute]) { let mut doc = String::new(); let mut spans = vec![]; @@ -185,7 +186,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a } fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>( - cx: &EarlyContext, + cx: &EarlyContext<'_>, valid_idents: &[String], docs: Events, spans: &[(usize, Span)], @@ -231,7 +232,7 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>( } } -fn check_text(cx: &EarlyContext, valid_idents: &[String], text: &str, span: Span) { +fn check_text(cx: &EarlyContext<'_>, valid_idents: &[String], text: &str, span: Span) { for word in text.split_whitespace() { // Trim punctuation as in `some comment (see foo::bar).` // ^^ @@ -254,7 +255,7 @@ fn check_text(cx: &EarlyContext, valid_idents: &[String], text: &str, span: Span } } -fn check_word(cx: &EarlyContext, word: &str, span: Span) { +fn check_word(cx: &EarlyContext<'_>, word: &str, span: Span) { /// Checks if a string is camel-case, ie. contains at least two uppercase /// letter (`Clippy` is /// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs index ba398c82064..434ccb69921 100644 --- a/clippy_lints/src/double_comparison.rs +++ b/clippy_lints/src/double_comparison.rs @@ -2,6 +2,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Span; use crate::utils::{snippet, span_lint_and_sugg, SpanlessEq}; @@ -41,13 +42,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 +68,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 +79,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); } } diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index 2b81e1db257..abd5666385d 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -1,5 +1,6 @@ use syntax::ast::*; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::{declare_lint, lint_array}; /// **What it does:** Checks for unnecessary double parentheses. /// @@ -30,7 +31,7 @@ impl LintPass for DoubleParens { } impl EarlyLintPass for DoubleParens { - fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { match expr.node { ExprKind::Paren(ref in_paren) => match in_paren.node { ExprKind::Paren(_) | ExprKind::Tup(_) => { diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index eb271a899c4..071afde986a 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use rustc::hir::*; use crate::utils::{is_copy, match_def_path, opt_def_id, paths, span_note_and_lint}; @@ -116,8 +118,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 { diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index 16b94d24b16..517befa7790 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::codemap::Spanned; use crate::consts::{constant, Constant}; @@ -38,8 +40,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 { diff --git a/clippy_lints/src/else_if_without_else.rs b/clippy_lints/src/else_if_without_else.rs index 96c215df405..39404bbafcc 100644 --- a/clippy_lints/src/else_if_without_else.rs +++ b/clippy_lints/src/else_if_without_else.rs @@ -1,9 +1,10 @@ //! lint on if expressions with an else if, but without a final else branch use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; -use crate::utils::{in_external_macro, span_lint_and_sugg}; +use crate::utils::span_lint_and_sugg; /// **What it does:** Checks for usage of if expressions with an `else if` branch, /// but without a final `else` branch. @@ -48,8 +49,8 @@ impl LintPass for ElseIfWithoutElse { } impl EarlyLintPass for ElseIfWithoutElse { - fn check_expr(&mut self, cx: &EarlyContext, mut item: &Expr) { - if in_external_macro(cx, item.span) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, mut item: &Expr) { + if in_external_macro(cx.sess(), item.span) { return; } diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 3265338ce12..f95ae32d561 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -1,6 +1,7 @@ //! lint when there is an enum with no variants use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::span_lint_and_then; @@ -32,9 +33,9 @@ impl LintPass for EmptyEnum { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum { - fn check_item(&mut self, cx: &LateContext, item: &Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item) { let did = cx.tcx.hir.local_def_id(item.id); - 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"); diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 13c75f39bb8..26ee6be5796 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -1,6 +1,8 @@ use rustc::hir::*; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::codemap::Span; use crate::utils::SpanlessEq; use crate::utils::{get_item_name, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty}; @@ -41,13 +43,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 +90,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 +125,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]); diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index f191150f3e7..62cbead1929 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -2,6 +2,7 @@ //! don't fit into an `i32` use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::ty; use rustc::ty::subst::Substs; @@ -47,7 +48,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 { diff --git a/clippy_lints/src/enum_glob_use.rs b/clippy_lints/src/enum_glob_use.rs index 943a5406b54..6f8afc710de 100644 --- a/clippy_lints/src/enum_glob_use.rs +++ b/clippy_lints/src/enum_glob_use.rs @@ -3,6 +3,7 @@ use rustc::hir::*; use rustc::hir::def::Def; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use syntax::ast::NodeId; use syntax::codemap::Span; use crate::utils::span_lint; @@ -43,11 +44,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EnumGlobUse { } impl EnumGlobUse { - fn lint_item(&self, cx: &LateContext, item: &Item) { - if item.vis == Visibility::Public { + fn lint_item(&self, cx: &LateContext<'_, '_>, item: &Item) { + 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, diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index a200383b41d..16c9212e5db 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -1,6 +1,7 @@ //! lint on enum variants that are prefixed or suffixed by the same characters use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use syntax::codemap::Span; use syntax::symbol::LocalInternedString; @@ -148,7 +149,7 @@ fn partial_rmatch(post: &str, name: &str) -> usize { // FIXME: #600 #[allow(while_let_on_iterator)] fn check_variant( - cx: &EarlyContext, + cx: &EarlyContext<'_>, threshold: u64, def: &EnumDef, item_name: &str, @@ -239,12 +240,12 @@ fn to_camel_case(item_name: &str) -> String { } impl EarlyLintPass for EnumVariantNames { - fn check_item_post(&mut self, _cx: &EarlyContext, _item: &Item) { + fn check_item_post(&mut self, _cx: &EarlyContext<'_>, _item: &Item) { let last = self.modules.pop(); assert!(last.is_some()); } - fn check_item(&mut self, cx: &EarlyContext, item: &Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { let item_name = item.ident.as_str(); let item_name_chars = item_name.chars().count(); let item_camel = to_camel_case(&item_name); @@ -262,7 +263,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(); diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 19761fbe864..dfbc3b12633 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -1,5 +1,6 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use crate::utils::{in_macro, implements_trait, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq}; /// **What it does:** Checks for equal operands to comparison, logical and @@ -52,7 +53,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 +67,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 +129,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 +140,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 +160,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, } } diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs index faf297fd5b2..4960a48b3c8 100644 --- a/clippy_lints/src/erasing_op.rs +++ b/clippy_lints/src/erasing_op.rs @@ -1,6 +1,7 @@ use crate::consts::{constant_simple, Constant}; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Span; use crate::utils::{in_macro, span_lint}; @@ -36,20 +37,20 @@ 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), _ => (), } } } } -fn check(cx: &LateContext, e: &Expr, span: Span) { +fn check(cx: &LateContext<'_, '_>, e: &Expr, span: Span) { if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) { if v == 0 { span_lint( diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 9482c3782d4..ebbc2c34811 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -2,6 +2,7 @@ use rustc::hir::*; use rustc::hir::intravisit as visit; use rustc::hir::map::Node::{NodeExpr, NodeStmt}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::{cmt_, Categorization}; use rustc::ty::{self, Ty}; @@ -38,7 +39,7 @@ declare_clippy_lint! { "using `Box<T>` where unnecessary" } -fn is_non_trait_box(ty: Ty) -> bool { +fn is_non_trait_box(ty: Ty<'_>) -> bool { ty.is_box() && !ty.boxed_ty().is_trait() } @@ -108,11 +109,12 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { return; } if let Categorization::Rvalue(..) = cmt.cat { - if let Some(NodeStmt(st)) = map.find(map.get_parent_node(cmt.id)) { - if let StmtDecl(ref decl, _) = st.node { - if let DeclLocal(ref loc) = decl.node { + let id = map.hir_to_node_id(cmt.hir_id); + if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) { + 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); @@ -135,7 +137,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } } } - fn borrow(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, _: ty::Region, _: ty::BorrowKind, loan_cause: LoanCause) { + fn borrow(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, _: ty::Region<'_>, _: ty::BorrowKind, loan_cause: LoanCause) { if let Categorization::Local(lid) = cmt.cat { match loan_cause { // x.foo() diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index e924ba6bdbb..2071628a6cf 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; use rustc::hir::*; use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then}; @@ -37,7 +38,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) }, _ => (), @@ -45,11 +46,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaPass { } } -fn check_closure(cx: &LateContext, expr: &Expr) { - if let ExprClosure(_, ref decl, eid, _, _) = expr.node { +fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) { + 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 +74,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; diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index d773289263e..7ccf8c31569 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -2,6 +2,8 @@ use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::hir::*; use rustc::ty; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast; use crate::utils::{get_parent_expr, span_lint, span_note_and_lint}; @@ -62,7 +64,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 +84,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 +104,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 +126,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 +139,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); @@ -173,7 +175,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { /// logical operators are considered to have a defined evaluation order. /// /// When such a read is found, the lint is triggered. -fn check_for_unsequenced_reads(vis: &mut ReadVisitor) { +fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) { let map = &vis.cx.tcx.hir; let mut cur_id = vis.write_expr.id; loop { @@ -218,25 +220,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 +264,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 +299,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 +322,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 +334,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> { // ``` // // TODO: fix this - ExprAddrOf(_, _) => { + ExprKind::AddrOf(_, _) => { return; } _ => {} @@ -346,9 +348,9 @@ 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 { +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; } } diff --git a/clippy_lints/src/excessive_precision.rs b/clippy_lints/src/excessive_precision.rs index aa648003c0c..28819077f9b 100644 --- a/clippy_lints/src/excessive_precision.rs +++ b/clippy_lints/src/excessive_precision.rs @@ -1,5 +1,7 @@ use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::TypeVariants; use std::f32; use std::f64; @@ -45,7 +47,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 { diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 7c741100bde..22e6834ee88 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use crate::utils::{is_expn_of, match_def_path, resolve_node, span_lint}; use crate::utils::opt_def_id; @@ -35,17 +37,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"]) { diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index 64cdc05b44d..3db644911d7 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir; use rustc::ty; use syntax_pos::Span; @@ -39,7 +41,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 +65,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); @@ -126,7 +128,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it } } -fn match_type(tcx: ty::TyCtxt, ty: ty::Ty, path: &[&str]) -> bool { +fn match_type(tcx: ty::TyCtxt<'_, '_, '_>, ty: ty::Ty<'_>, path: &[&str]) -> bool { match ty.sty { ty::TyAdt(adt, _) => match_def_path(tcx, adt.did, path), _ => false, diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 890fe51819a..80fc4c3acfe 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use syntax::ast::LitKind; use syntax_pos::Span; @@ -46,9 +48,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 +66,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 +83,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(); @@ -103,25 +105,25 @@ fn check_single_piece(expr: &Expr) -> bool { /// ``` /// and that type of `__arg0` is `&str` or `String` /// then returns the span of first element of the matched tuple -fn get_single_string_arg(cx: &LateContext, expr: &Expr) -> Option<Span> { +fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span> { if_chain! { - if 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 +145,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; diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 8008bb3ed66..60001c792c0 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast; use crate::utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint}; use syntax::ptr::P; @@ -82,7 +83,7 @@ impl LintPass for Formatting { } impl EarlyLintPass for Formatting { - fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) { + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) { for w in block.stmts.windows(2) { match (&w[0].node, &w[1].node) { (&ast::StmtKind::Expr(ref first), &ast::StmtKind::Expr(ref second)) | @@ -94,7 +95,7 @@ impl EarlyLintPass for Formatting { } } - fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { check_assign(cx, expr); check_else_if(cx, expr); check_array(cx, expr); @@ -102,7 +103,7 @@ impl EarlyLintPass for Formatting { } /// Implementation of the `SUSPICIOUS_ASSIGNMENT_FORMATTING` lint. -fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { +fn check_assign(cx: &EarlyContext<'_>, expr: &ast::Expr) { if let ast::ExprKind::Assign(ref lhs, ref rhs) = expr.node { if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro(lhs.span) { let eq_span = lhs.span.between(rhs.span); @@ -131,7 +132,7 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { } /// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for weird `else if`. -fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) { +fn check_else_if(cx: &EarlyContext<'_>, expr: &ast::Expr) { if let Some((then, &Some(ref else_))) = unsugar_if(expr) { if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) { // this will be a span from the closing ‘}’ of the “then” block (excluding) to @@ -163,7 +164,7 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) { } /// Implementation of the `POSSIBLE_MISSING_COMMA` lint for array -fn check_array(cx: &EarlyContext, expr: &ast::Expr) { +fn check_array(cx: &EarlyContext<'_>, expr: &ast::Expr) { if let ast::ExprKind::Array(ref array) = expr.node { for element in array { if let ast::ExprKind::Binary(ref op, ref lhs, _) = element.node { @@ -189,7 +190,7 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) { } /// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs. -fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) { +fn check_consecutive_ifs(cx: &EarlyContext<'_>, first: &ast::Expr, second: &ast::Expr) { if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) && unsugar_if(first).is_some() && unsugar_if(second).is_some() { diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 554c983d7c5..8903766c330 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -1,6 +1,8 @@ +use matches::matches; use rustc::hir::intravisit; use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; use rustc::hir::def::Def; use std::collections::HashSet; @@ -86,7 +88,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 }; @@ -126,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { } impl<'a, 'tcx> Functions { - fn check_arg_number(self, cx: &LateContext, decl: &hir::FnDecl, span: Span) { + fn check_arg_number(self, cx: &LateContext<'_, '_>, decl: &hir::FnDecl, span: Span) { let args = decl.inputs.len() as u64; if args > self.threshold { span_lint( @@ -168,7 +170,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 +186,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 +195,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 +205,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 +218,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( diff --git a/clippy_lints/src/identity_conversion.rs b/clippy_lints/src/identity_conversion.rs index 2effb8bd8db..a0705f62544 100644 --- a/clippy_lints/src/identity_conversion.rs +++ b/clippy_lints/src/identity_conversion.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use syntax::ast::NodeId; use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then}; @@ -43,19 +44,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 +69,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); diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index e983e5746a1..23b34362171 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -1,6 +1,7 @@ use crate::consts::{constant_simple, Constant}; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Span; use crate::utils::{in_macro, snippet, span_lint, unsext, clip}; use rustc::ty; @@ -36,19 +37,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); }, @@ -59,7 +60,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp { } #[allow(cast_possible_wrap)] -fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) { +fn check(cx: &LateContext<'_, '_>, e: &Expr, m: i8, span: Span, arg: Span) { if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) { let check = match cx.tables.expr_ty(e).sty { ty::TyInt(ity) => unsext(cx.tcx, -1i128, ity), diff --git a/clippy_lints/src/if_let_redundant_pattern_matching.rs b/clippy_lints/src/if_let_redundant_pattern_matching.rs index 92b2bab3ba8..bc97584a23d 100644 --- a/clippy_lints/src/if_let_redundant_pattern_matching.rs +++ b/clippy_lints/src/if_let_redundant_pattern_matching.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::{match_qpath, paths, snippet, span_lint_and_then}; @@ -45,16 +46,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; } diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 22ca1a61c9b..fea3069f37d 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -2,9 +2,10 @@ //! on the condition use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; -use crate::utils::{in_external_macro, span_help_and_lint}; +use crate::utils::span_help_and_lint; /// **What it does:** Checks for usage of `!` or `!=` in an if condition with an /// else branch. @@ -46,8 +47,8 @@ impl LintPass for IfNotElse { } impl EarlyLintPass for IfNotElse { - fn check_expr(&mut self, cx: &EarlyContext, item: &Expr) { - if in_external_macro(cx, item.span) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) { + if in_external_macro(cx.sess(), item.span) { return; } if let ExprKind::If(ref cond, _, Some(ref els)) = item.node { diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index 7dd72a5383c..677f59d32cc 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -6,6 +6,7 @@ use crate::utils::higher; use crate::utils::higher::Range; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; use syntax::ast::RangeLimits; @@ -94,7 +95,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[..] @@ -154,7 +155,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { /// the range. fn to_const_range<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, - range: Range, + range: Range<'_>, array_size: u128, ) -> Option<(u128, u128)> { let s = range diff --git a/clippy_lints/src/infallible_destructuring_match.rs b/clippy_lints/src/infallible_destructuring_match.rs index a2b3846b986..8b8cb32deb1 100644 --- a/clippy_lints/src/infallible_destructuring_match.rs +++ b/clippy_lints/src/infallible_destructuring_match.rs @@ -1,6 +1,8 @@ use super::utils::{get_arg_name, match_var, remove_blocks, snippet, span_lint_and_sugg}; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; /// **What it does:** Checks for matches being used to destructure a single-variant enum /// or tuple struct where a `let` will suffice. @@ -50,7 +52,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; diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 8f6d499329f..eaa93cb62f8 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -1,5 +1,6 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, paths, span_lint}; /// **What it does:** Checks for iteration that is guaranteed to be infinite. @@ -139,9 +140,9 @@ static HEURISTICS: &[(&str, usize, Heuristic, Finiteness)] = &[ ("scan", 3, First, MaybeInfinite), ]; -fn is_infinite(cx: &LateContext, expr: &Expr) -> 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 +154,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, @@ -203,9 +204,9 @@ static COMPLETING_METHODS: &[(&str, usize)] = &[ ("product", 1), ]; -fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness { +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 +225,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 diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index 637ea917a8f..fc06af81574 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -2,6 +2,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use std::collections::HashMap; use std::default::Default; use syntax_pos::Span; @@ -56,7 +57,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())); diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index 8dab9fbd12f..70f88a76f45 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -1,6 +1,7 @@ //! checks for `#[inline]` on trait methods without bodies use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use syntax::ast::{Attribute, Name}; use crate::utils::span_lint_and_then; @@ -43,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -fn check_attrs(cx: &LateContext, name: Name, attrs: &[Attribute]) { +fn check_attrs(cx: &LateContext<'_, '_>, name: Name, attrs: &[Attribute]) { for attr in attrs { if attr.name() != "inline" { continue; diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 8daf3d296c7..9b6fc579a31 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -1,6 +1,7 @@ //! lint on blocks unnecessarily using >= with a + 1 or - 1 use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use crate::utils::{snippet_opt, span_lint_and_then}; @@ -60,7 +61,7 @@ impl IntPlusOne { false } - fn check_binop(&self, cx: &EarlyContext, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> { + fn check_binop(&self, cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> { match (binop, &lhs.node, &rhs.node) { // case where `x - 1 >= ...` or `-1 + x >= ...` (BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => { @@ -126,7 +127,7 @@ impl IntPlusOne { fn generate_recommendation( &self, - cx: &EarlyContext, + cx: &EarlyContext<'_>, binop: BinOpKind, node: &Expr, other_side: &Expr, @@ -149,7 +150,7 @@ impl IntPlusOne { None } - fn emit_warning(&self, cx: &EarlyContext, block: &Expr, recommendation: String) { + fn emit_warning(&self, cx: &EarlyContext<'_>, block: &Expr, recommendation: String) { span_lint_and_then(cx, INT_PLUS_ONE, block.span, "Unnecessary `>= y + 1` or `x - 1 >=`", |db| { db.span_suggestion(block.span, "change `>= y + 1` to `> y` as shown", recommendation); }); @@ -157,7 +158,7 @@ impl IntPlusOne { } impl EarlyLintPass for IntPlusOne { - fn check_expr(&mut self, cx: &EarlyContext, item: &Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) { if let ExprKind::Binary(ref kind, ref lhs, ref rhs) = item.node { if let Some(ref rec) = self.check_binop(cx, kind.node, lhs, rhs) { self.emit_warning(cx, item, rec.clone()); diff --git a/clippy_lints/src/invalid_ref.rs b/clippy_lints/src/invalid_ref.rs index 0ebdda9ec88..b529cb3ac38 100644 --- a/clippy_lints/src/invalid_ref.rs +++ b/clippy_lints/src/invalid_ref.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use rustc::hir::*; use crate::utils::{match_def_path, opt_def_id, paths, span_help_and_lint}; @@ -35,8 +37,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)); diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index 685c91c0457..07ef086d694 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -1,6 +1,8 @@ //! lint when items are used after statements +use matches::matches; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use crate::utils::{in_macro, span_lint}; @@ -41,7 +43,7 @@ impl LintPass for ItemsAfterStatements { } impl EarlyLintPass for ItemsAfterStatements { - fn check_block(&mut self, cx: &EarlyContext, item: &Block) { + fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) { if in_macro(item.span) { return; } diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index ca136f06aec..2c03b6b5f68 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -1,6 +1,7 @@ //! lint when there is a large size difference between variants on an enum use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::{snippet_opt, span_lint_and_then}; use rustc::ty::layout::LayoutOf; @@ -47,9 +48,9 @@ impl LintPass for LargeEnumVariant { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { - fn check_item(&mut self, cx: &LateContext, item: &Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item) { let did = cx.tcx.hir.local_def_id(item.id); - 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"); diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 33930ab58db..b73f912fad5 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,6 +1,7 @@ use rustc::hir::def_id::DefId; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; use std::collections::HashSet; use syntax::ast::{Lit, LitKind, Name}; @@ -68,8 +69,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,34 +80,34 @@ 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 _ => (), } } } } -fn check_trait_items(cx: &LateContext, visited_trait: &Item, trait_items: &[TraitItemRef]) { - fn is_named_self(cx: &LateContext, item: &TraitItemRef, name: &str) -> bool { +fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items: &[TraitItemRef]) { + fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: &str) -> bool { item.ident.name == name && if let AssociatedItemKind::Method { has_self } = item.kind { has_self && { let did = cx.tcx.hir.local_def_id(item.id.node_id); @@ -118,7 +119,7 @@ fn check_trait_items(cx: &LateContext, visited_trait: &Item, trait_items: &[Trai } // fill the set with current and super traits - fn fill_trait_set(traitt: DefId, set: &mut HashSet<DefId>, cx: &LateContext) { + fn fill_trait_set(traitt: DefId, set: &mut HashSet<DefId>, cx: &LateContext<'_, '_>) { if set.insert(traitt) { for supertrait in ::rustc::traits::supertrait_def_ids(cx.tcx, traitt) { fill_trait_set(supertrait, set, cx); @@ -153,8 +154,8 @@ fn check_trait_items(cx: &LateContext, visited_trait: &Item, trait_items: &[Trai } } -fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) { - fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool { +fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplItemRef]) { + fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef, name: &str) -> bool { item.ident.name == name && if let AssociatedItemKind::Method { has_self } = item.kind { has_self && { let did = cx.tcx.hir.local_def_id(item.id.node_id); @@ -193,8 +194,8 @@ 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) { +fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr, lit: &Expr, op: &str, compare_to: u32) { + 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" { @@ -206,7 +207,7 @@ fn check_cmp(cx: &LateContext, span: Span, method: &Expr, lit: &Expr, op: &str, } } -fn check_len(cx: &LateContext, span: Span, method_name: Name, args: &[Expr], lit: &Lit, op: &str, compare_to: u32) { +fn check_len(cx: &LateContext<'_, '_>, span: Span, method_name: Name, args: &[Expr], lit: &Lit, op: &str, compare_to: u32) { if let Spanned { node: LitKind::Int(lit, _), .. @@ -231,9 +232,9 @@ fn check_len(cx: &LateContext, span: Span, method_name: Name, args: &[Expr], lit } /// Check if this type has an `is_empty` method. -fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { +fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { /// Get an `AssociatedItem` and return true if it matches `is_empty(self)`. - fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool { + fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssociatedItem) -> bool { if let ty::AssociatedKind::Method = item.kind { if item.ident.name == "is_empty" { let sig = cx.tcx.fn_sig(item.def_id); @@ -248,7 +249,7 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { } /// Check the inherent impl's items for an `is_empty(self)` method. - fn has_is_empty_impl(cx: &LateContext, id: DefId) -> bool { + fn has_is_empty_impl(cx: &LateContext<'_, '_>, id: DefId) -> bool { cx.tcx.inherent_impls(id).iter().any(|imp| { cx.tcx .associated_items(*imp) @@ -258,11 +259,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, diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 4e0d3de799e..57ca5eff955 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir; use rustc::hir::BindingAnnotation; use rustc::hir::def::Def; @@ -65,20 +67,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 +142,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 +165,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 { diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 28827387b9d..b08449d2beb 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -14,54 +14,41 @@ #![feature(rust_2018_preview)] #![warn(rust_2018_idioms)] -#[macro_use] -extern crate rustc; - use toml; use rustc_plugin; +use rustc; -#[macro_use] -extern crate matches as matches_macro; - -#[macro_use] -extern crate serde_derive; - -#[macro_use] -extern crate lazy_static; - -#[macro_use] -extern crate if_chain; macro_rules! declare_clippy_lint { { pub $name:tt, style, $description:tt } => { - declare_lint! { pub $name, Warn, $description } + declare_lint! { pub $name, Warn, $description, report_in_external_macro: true } }; { pub $name:tt, correctness, $description:tt } => { - declare_lint! { pub $name, Deny, $description } + declare_lint! { pub $name, Deny, $description, report_in_external_macro: true } }; { pub $name:tt, complexity, $description:tt } => { - declare_lint! { pub $name, Warn, $description } + declare_lint! { pub $name, Warn, $description, report_in_external_macro: true } }; { pub $name:tt, perf, $description:tt } => { - declare_lint! { pub $name, Warn, $description } + declare_lint! { pub $name, Warn, $description, report_in_external_macro: true } }; { pub $name:tt, pedantic, $description:tt } => { - declare_lint! { pub $name, Allow, $description } + declare_lint! { pub $name, Allow, $description, report_in_external_macro: true } }; { pub $name:tt, restriction, $description:tt } => { - declare_lint! { pub $name, Allow, $description } + declare_lint! { pub $name, Allow, $description, report_in_external_macro: true } }; { pub $name:tt, cargo, $description:tt } => { - declare_lint! { pub $name, Allow, $description } + declare_lint! { pub $name, Allow, $description, report_in_external_macro: true } }; { pub $name:tt, nursery, $description:tt } => { - declare_lint! { pub $name, Allow, $description } + declare_lint! { pub $name, Allow, $description, report_in_external_macro: true } }; { pub $name:tt, internal, $description:tt } => { - declare_lint! { pub $name, Allow, $description } + declare_lint! { pub $name, Allow, $description, report_in_external_macro: true } }; { pub $name:tt, internal_warn, $description:tt } => { - declare_lint! { pub $name, Warn, $description } + declare_lint! { pub $name, Warn, $description, report_in_external_macro: true } }; } @@ -134,6 +121,7 @@ pub mod minmax; pub mod misc; pub mod misc_early; pub mod missing_doc; +pub mod missing_inline; pub mod multiple_crate_versions; pub mod mut_mut; pub mod mut_reference; @@ -188,8 +176,12 @@ mod reexport { crate use syntax::ast::{Name, NodeId}; } +pub fn register_pre_expansion_lints(session: &rustc::session::Session, store: &mut rustc::lint::LintStore) { + store.register_pre_expansion_pass(Some(session), box write::Pass); +} + #[cfg_attr(rustfmt, rustfmt_skip)] -pub fn register_plugins(reg: &mut rustc_plugin::Registry) { +pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>) { let conf = match utils::conf::file_from_args(reg.args()) { Ok(file_name) => { // if the user specified a file, it must exist, otherwise default to `clippy.toml` but @@ -333,7 +325,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box strings::StringLitAsBytes); reg.register_late_lint_pass(box derive::Derive); reg.register_late_lint_pass(box types::CharLitAsU8); - reg.register_late_lint_pass(box write::Pass); reg.register_late_lint_pass(box vec::Pass); reg.register_early_lint_pass(box non_expressive_names::NonExpressiveNames { single_char_binding_names_threshold: conf.single_char_binding_names_threshold, @@ -364,6 +355,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box let_if_seq::LetIfSeq); reg.register_late_lint_pass(box eval_order_dependence::EvalOrderDependence); reg.register_late_lint_pass(box missing_doc::MissingDoc::new()); + reg.register_late_lint_pass(box missing_inline::MissingInline); reg.register_late_lint_pass(box ok_if_let::Pass); reg.register_late_lint_pass(box if_let_redundant_pattern_matching::Pass); reg.register_late_lint_pass(box partialeq_ne_impl::Pass); @@ -422,6 +414,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { methods::WRONG_PUB_SELF_CONVENTION, misc::FLOAT_CMP_CONST, missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS, + missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS, panic_unimplemented::UNIMPLEMENTED, shadow::SHADOW_REUSE, shadow::SHADOW_SAME, diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index efa50a8f743..cf7a016231e 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -1,11 +1,13 @@ use crate::reexport::*; +use matches::matches; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::def::Def; use rustc::hir::*; use rustc::hir::intravisit::*; use std::collections::{HashMap, HashSet}; use syntax::codemap::Span; -use crate::utils::{in_external_macro, last_path_segment, span_lint}; +use crate::utils::{last_path_segment, span_lint}; use syntax::symbol::keywords; /// **What it does:** Checks for lifetime annotations which can be removed by @@ -59,7 +61,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); } } @@ -96,7 +98,7 @@ fn check_fn_inner<'a, 'tcx>( generics: &'tcx Generics, span: Span, ) { - if in_external_macro(cx, span) || has_where_lifetimes(cx, &generics.where_clause) { + if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, &generics.where_clause) { return; } @@ -126,7 +128,7 @@ fn check_fn_inner<'a, 'tcx>( GenericArg::Type(_) => None, }); for bound in lifetimes { - if bound.name.ident().name != "'static" && !bound.is_elided() { + if bound.name != LifetimeName::Static && !bound.is_elided() { return; } bounds_lts.push(bound); @@ -251,7 +253,7 @@ fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet<RefLt> { fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> { for lt in bounds_lts { - if lt.name.ident().name != "'static" { + if lt.name != LifetimeName::Static { vec.push(RefLt::Named(lt.name.ident().name)); } } @@ -282,7 +284,7 @@ impl<'v, 't> RefVisitor<'v, 't> { fn record(&mut self, lifetime: &Option<Lifetime>) { if let Some(ref lt) = *lifetime { - if lt.name.ident().name == "'static" { + if lt.name == LifetimeName::Static { self.lts.push(RefLt::Static); } else if lt.is_elided() { self.lts.push(RefLt::Unnamed); @@ -338,22 +340,29 @@ 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) => { - self.collect_anonymous_lifetimes(path, ty); - }, - TyImplTraitExistential(exist_ty_id, _, _) => { - if let ItemExistential(ref exist_ty) = self.cx.tcx.hir.expect_item(exist_ty_id.id).node { - for bound in &exist_ty.bounds { - if let GenericBound::Outlives(_) = *bound { - self.record(&None); + 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 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); + } + } + } else { + unreachable!() } + walk_ty(self, ty); + return; } } + self.collect_anonymous_lifetimes(path, ty); } - TyTraitObject(ref bounds, ref lt) => { + TyKind::TraitObject(ref bounds, ref lt) => { if !lt.is_elided() { self.abort = true; } diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 9b6c30f7f4c..45f9af49a15 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -2,9 +2,11 @@ //! floating-point literal expressions. use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast::*; use syntax_pos; -use crate::utils::{in_external_macro, snippet_opt, span_lint_and_sugg}; +use crate::utils::{snippet_opt, span_lint_and_sugg}; /// **What it does:** Warns if a long integral or floating-point constant does /// not contain underscores. @@ -227,7 +229,7 @@ enum WarningType { } impl WarningType { - crate fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: syntax_pos::Span) { + crate fn display(&self, grouping_hint: &str, cx: &EarlyContext<'_>, span: syntax_pos::Span) { match self { WarningType::UnreadableLiteral => span_lint_and_sugg( cx, @@ -279,8 +281,8 @@ impl LintPass for LiteralDigitGrouping { } impl EarlyLintPass for LiteralDigitGrouping { - fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { - if in_external_macro(cx, expr.span) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if in_external_macro(cx.sess(), expr.span) { return; } @@ -291,7 +293,7 @@ impl EarlyLintPass for LiteralDigitGrouping { } impl LiteralDigitGrouping { - fn check_lit(self, cx: &EarlyContext, lit: &Lit) { + fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) { match lit.node { LitKind::Int(..) => { // Lint integral literals. @@ -419,8 +421,8 @@ impl LintPass for LiteralRepresentation { } impl EarlyLintPass for LiteralRepresentation { - fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { - if in_external_macro(cx, expr.span) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if in_external_macro(cx.sess(), expr.span) { return; } @@ -436,7 +438,7 @@ impl LiteralRepresentation { threshold, } } - fn check_lit(self, cx: &EarlyContext, lit: &Lit) { + fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) { // Lint integral literals. if_chain! { if let LitKind::Int(..) = lit.node; diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 8b7032893d8..b95bc01c013 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -6,6 +6,8 @@ use rustc::hir::def_id; use rustc::hir::intravisit::{walk_block, walk_decl, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; use rustc::hir::map::Node::{NodeBlock, NodeExpr, NodeStmt}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::middle::region; // use rustc::middle::region::CodeExtent; use rustc::middle::expr_use_visitor::*; @@ -21,9 +23,9 @@ use crate::utils::{sugg, sext}; use crate::utils::usage::mutated_variables; use crate::consts::{constant, Constant}; -use crate::utils::{get_enclosing_block, get_parent_expr, higher, in_external_macro, is_integer_literal, is_refutable, +use crate::utils::{get_enclosing_block, get_parent_expr, higher, 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 +413,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 +426,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 +442,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 { .. } => { @@ -448,7 +450,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { && arms[1].pats.len() == 1 && arms[1].guard.is_none() && is_simple_break_expr(&arms[1].body) { - if in_external_macro(cx, expr.span) { + if in_external_macro(cx.sess(), expr.span) { return; } @@ -476,11 +478,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 +507,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 +586,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 +641,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 +651,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 +703,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); @@ -741,7 +743,7 @@ struct FixedOffsetVar { offset: Offset, } -fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty) -> bool { +fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool { let is_slice = match ty.sty { ty::TyRef(_, subty, _) => is_slice_like(cx, subty), ty::TySlice(..) | ty::TyArray(..) => true, @@ -754,24 +756,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 +784,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 +812,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 +834,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 +851,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 +861,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 +908,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 +1100,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 { @@ -1183,7 +1185,7 @@ fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx } } -fn lint_iter_method(cx: &LateContext, args: &[Expr], arg: &Expr, method_name: &str) { +fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr], arg: &Expr, method_name: &str) { let object = snippet(cx, args[0].span, "_"); let muta = if method_name == "iter_mut" { "mut " @@ -1201,9 +1203,9 @@ fn lint_iter_method(cx: &LateContext, args: &[Expr], arg: &Expr, method_name: &s ) } -fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { +fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Expr) { let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used - 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(); @@ -1256,7 +1258,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { } /// Check for `for` loops over `Option`s and `Results` -fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { +fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) { let ty = cx.tables.expr_ty(arg); if match_type(cx, ty, &paths::OPTION) { span_help_and_lint( @@ -1377,7 +1379,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, }; @@ -1418,7 +1420,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate { fn consume_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: ConsumeMode) {} - fn borrow(&mut self, _: NodeId, sp: Span, cmt: &cmt_<'tcx>, _: ty::Region, bk: ty::BorrowKind, _: LoanCause) { + fn borrow(&mut self, _: NodeId, sp: Span, cmt: &cmt_<'tcx>, _: ty::Region<'_>, bk: ty::BorrowKind, _: LoanCause) { if let ty::BorrowKind::MutBorrow = bk { if let Categorization::Local(id) = cmt.cat { if Some(id) == self.node_id_low { @@ -1451,7 +1453,7 @@ impl<'tcx> MutatePairDelegate { } } -fn check_for_mut_range_bound(cx: &LateContext, arg: &Expr, body: &Expr) { +fn check_for_mut_range_bound(cx: &LateContext<'_, '_>, arg: &Expr, body: &Expr) { if let Some(higher::Range { start: Some(start), end: Some(end), @@ -1470,7 +1472,7 @@ fn check_for_mut_range_bound(cx: &LateContext, arg: &Expr, body: &Expr) { } } -fn mut_warn_with_span(cx: &LateContext, span: Option<Span>) { +fn mut_warn_with_span(cx: &LateContext<'_, '_>, span: Option<Span>) { if let Some(sp) = span { span_lint( cx, @@ -1481,9 +1483,9 @@ fn mut_warn_with_span(cx: &LateContext, span: Option<Span>) { } } -fn check_for_mutability(cx: &LateContext, bound: &Expr) -> Option<NodeId> { +fn check_for_mutability(cx: &LateContext<'_, '_>, bound: &Expr) -> Option<NodeId> { if_chain! { - if 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); @@ -1503,7 +1505,7 @@ fn check_for_mutability(cx: &LateContext, bound: &Expr) -> Option<NodeId> { None } -fn check_for_mutation(cx: &LateContext, body: &Expr, bound_ids: &[Option<NodeId>]) -> (Option<Span>, Option<Span>) { +fn check_for_mutation(cx: &LateContext<'_, '_>, body: &Expr, bound_ids: &[Option<NodeId>]) -> (Option<Span>, Option<Span>) { let mut delegate = MutatePairDelegate { node_id_low: bound_ids[0], node_id_high: bound_ids[1], @@ -1598,7 +1600,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 +1657,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 +1666,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 +1689,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 +1715,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; @@ -1780,7 +1782,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> { /// Return true if the type of expr is one that provides `IntoIterator` impls /// for `&T` and `&mut T`, such as `Vec`. #[cfg_attr(rustfmt, rustfmt_skip)] -fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool { +fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr) -> bool { // no walk_ptrs_ty: calling iter() on a reference can make sense because it // will allow further borrows afterwards let ty = cx.tables.expr_ty(e); @@ -1795,7 +1797,7 @@ fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool { match_type(cx, ty, &paths::BTREESET) } -fn is_iterable_array(ty: Ty, cx: &LateContext) -> bool { +fn is_iterable_array(ty: Ty<'_>, cx: &LateContext<'_, '_>) -> bool { // IntoIterator is currently only implemented for array sizes <= 32 in rustc match ty.sty { ty::TyArray(_, n) => (0..=32).contains(&n.assert_usize(cx.tcx).expect("array length")), @@ -1809,8 +1811,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 +1831,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 +1843,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 +1884,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 +1897,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 +1933,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 +1957,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 +1971,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, _ => (), } } @@ -2004,8 +2006,8 @@ 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 { +fn var_def_id(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<NodeId> { + 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,19 +2018,19 @@ 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, } } -fn is_nested(cx: &LateContext, match_expr: &Expr, iter_expr: &Expr) -> bool { +fn is_nested(cx: &LateContext<'_, '_>, match_expr: &Expr, iter_expr: &Expr) -> bool { if_chain! { if let Some(loop_block) = get_enclosing_block(cx, match_expr.id); if let Some(map::Node::NodeExpr(loop_expr)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(loop_block.id)); @@ -2039,7 +2041,7 @@ fn is_nested(cx: &LateContext, match_expr: &Expr, iter_expr: &Expr) -> bool { false } -fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool { +fn is_loop_nested(cx: &LateContext<'_, '_>, loop_expr: &Expr, iter_expr: &Expr) -> bool { let mut id = loop_expr.id; let iter_name = if let Some(name) = path_name(iter_expr) { name @@ -2053,7 +2055,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 +2113,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 +2139,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 +2195,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 +2216,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), } diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 5ea873e31e1..d8b14db605f 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -1,9 +1,11 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; 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 +32,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 +64,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 +79,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 +100,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,13 +110,13 @@ 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, } } -fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> { +fn get_type_name(cx: &LateContext<'_, '_>, expr: &Expr, arg: &Expr) -> Option<&'static str> { if match_trait_method(cx, expr, &paths::ITERATOR) { Some("iterator") } else if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(arg)), &paths::OPTION) { @@ -124,10 +126,10 @@ fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static s } } -fn only_derefs(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool { +fn only_derefs(cx: &LateContext<'_, '_>, expr: &Expr, id: ast::Ident) -> bool { match expr.node { - 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), } } diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index a1f4b70a4dc..6ccf8daa71d 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -1,7 +1,9 @@ use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; 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; @@ -82,7 +84,7 @@ impl LintPass for Pass { } } -fn is_unit_type(ty: ty::Ty) -> bool { +fn is_unit_type(ty: ty::Ty<'_>) -> bool { match ty.sty { ty::TyTuple(slice) => slice.is_empty(), ty::TyNever => true, @@ -90,7 +92,7 @@ fn is_unit_type(ty: ty::Ty) -> bool { } } -fn is_unit_function(cx: &LateContext, expr: &hir::Expr) -> bool { +fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> bool { let ty = cx.tables.expr_ty(expr); if let ty::TyFnDef(id, _) = ty.sty { @@ -101,7 +103,7 @@ fn is_unit_function(cx: &LateContext, expr: &hir::Expr) -> bool { false } -fn is_unit_expression(cx: &LateContext, expr: &hir::Expr) -> bool { +fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> bool { is_unit_type(cx.tables.expr_ty(expr)) } @@ -109,18 +111,18 @@ fn is_unit_expression(cx: &LateContext, expr: &hir::Expr) -> bool { /// semicolons, which causes problems when generating a suggestion. Given an /// expression that evaluates to '()' or '!', recursively remove useless braces /// and semi-colons until is suitable for including in the suggestion template -fn reduce_unit_expression<'a>(cx: &LateContext, expr: &'a hir::Expr) -> Option<Span> { +fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr) -> Option<Span> { if !is_unit_expression(cx, expr) { return None; } 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 +133,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 +153,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; @@ -173,10 +175,10 @@ fn unit_closure<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'a hir::Expr) -> Op /// `y` => `_y` /// /// Anything else will return `_`. -fn let_binding_name(cx: &LateContext, var_arg: &hir::Expr) -> String { +fn let_binding_name(cx: &LateContext<'_, '_>, var_arg: &hir::Expr) -> String { match &var_arg.node { - 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() } } @@ -189,7 +191,7 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String { ) } -fn lint_map_unit_fn(cx: &LateContext, stmt: &hir::Stmt, expr: &hir::Expr, map_args: &[hir::Expr]) { +fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt, expr: &hir::Expr, map_args: &[hir::Expr]) { let var_arg = &map_args[0]; let fn_arg = &map_args[1]; @@ -242,13 +244,13 @@ fn lint_map_unit_fn(cx: &LateContext, stmt: &hir::Stmt, expr: &hir::Expr, map_ar } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_stmt(&mut self, cx: &LateContext, stmt: &hir::Stmt) { + fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &hir::Stmt) { if in_macro(stmt.span) { 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]); } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 207343c92c6..c7452f0027e 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1,12 +1,14 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use std::cmp::Ordering; use std::collections::Bound; use syntax::ast::LitKind; use syntax::codemap::Span; use crate::utils::paths; -use crate::utils::{expr_block, in_external_macro, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, +use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty}; use crate::utils::sugg::Sugg; use crate::consts::{constant, Constant}; @@ -181,31 +183,31 @@ impl LintPass for MatchPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_external_macro(cx, expr.span) { + if in_external_macro(cx.sess(), 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); } } } #[cfg_attr(rustfmt, rustfmt_skip)] -fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { +fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { if arms.len() == 2 && arms[0].pats.len() == 1 && arms[0].guard.is_none() && arms[1].pats.len() == 1 && arms[1].guard.is_none() { 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 { @@ -220,13 +222,13 @@ 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 { +fn check_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr, els: Option<&Expr>) { + if is_wild(&arms[1].pats[0]) { report_single_match_single_pattern(cx, ex, arms, expr, els); } } -fn report_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, els: Option<&Expr>) { +fn report_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr, els: Option<&Expr>) { let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { @@ -250,7 +252,7 @@ fn report_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], ); } -fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, ty: Ty, els: Option<&Expr>) { +fn check_single_match_opt_like(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr, ty: Ty<'_>, els: Option<&Expr>) { // list of candidate Enums we know will never get any more members let candidates = &[ (&paths::COW, "Borrowed"), @@ -265,7 +267,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)) @@ -282,7 +284,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: } } -fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { +fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { // type of expression == bool if cx.tables.expr_ty(ex).sty == ty::TyBool { span_lint_and_then( @@ -294,7 +296,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,7 +358,14 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr, } } -fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) { +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) { for arm in arms { @@ -364,8 +373,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 @@ -396,10 +405,10 @@ fn is_panic_block(block: &Block) -> bool { } } -fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { +fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { if has_only_ref_pats(arms) { 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", @@ -427,7 +436,7 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) } } -fn check_match_as_ref(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { +fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { if arms.len() == 2 && arms[0].pats.len() == 1 && arms[0].guard.is_none() && arms[1].pats.len() == 1 && arms[1].guard.is_none() { @@ -533,8 +542,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 +563,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 { diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index 816c1bb6fbf..88c24458646 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -1,5 +1,6 @@ use rustc::lint::*; -use rustc::hir::{Expr, ExprCall, ExprPath}; +use rustc::{declare_lint, lint_array}; +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 +31,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]); diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 71f9dc8e03f..28ff303fc83 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -1,5 +1,8 @@ +use matches::matches; use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use rustc::hir::def::Def; use std::borrow::Cow; @@ -7,10 +10,10 @@ use std::fmt; use std::iter; use syntax::ast; 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, +use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, 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 +721,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 +792,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); }, @@ -803,7 +806,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::ImplItem) { - if in_external_macro(cx, implitem.span) { + if in_external_macro(cx.sess(), implitem.span) { return; } let name = implitem.ident.name; @@ -813,15 +816,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 +841,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 == hir::Visibility::Public { + let lint = if item.vis.node.is_pub() { WRONG_PUB_SELF_CONVENTION } else { WRONG_SELF_CONVENTION @@ -873,10 +876,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } /// Checks for the `OR_FUN_CALL` lint. -fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) { +fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) { /// Check for `unwrap_or(T::new())` or `unwrap_or(T::default())`. fn check_unwrap_or_default( - cx: &LateContext, + cx: &LateContext<'_, '_>, name: &str, fun: &hir::Expr, self_expr: &hir::Expr, @@ -889,7 +892,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) { @@ -921,7 +924,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name: /// Check for `*or(foo())`. #[allow(too_many_arguments)] fn check_general_case( - cx: &LateContext, + cx: &LateContext<'_, '_>, name: &str, method_span: Span, fun_span: Span, @@ -964,7 +967,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, name: return; } - let sugg: Cow<_> = match (fn_has_arguments, !or_has_args) { + let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) { (true, _) => format!("|_| {}", snippet(cx, arg.span, "..")).into(), (false, false) => format!("|| {}", snippet(cx, arg.span, "..")).into(), (false, true) => snippet(cx, fun_span, ".."), @@ -982,13 +985,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) }, _ => {}, @@ -997,12 +1000,12 @@ 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 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); } } @@ -1012,10 +1015,10 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n None } - 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 { + fn generate_format_arg_snippet(cx: &LateContext<'_, '_>, a: &hir::Expr) -> String { + 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(); } } @@ -1025,7 +1028,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n } fn check_general_case( - cx: &LateContext, + cx: &LateContext<'_, '_>, name: &str, method_span: Span, self_expr: &hir::Expr, @@ -1076,7 +1079,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n return; } - let sugg: Cow<_> = snippet(cx, arg.span, ".."); + let sugg: Cow<'_, _> = snippet(cx, arg.span, ".."); span_lint_and_sugg( cx, @@ -1090,14 +1093,14 @@ 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), } } } /// Checks for the `CLONE_ON_COPY` lint. -fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: Ty) { +fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Expr, arg_ty: Ty<'_>) { let ty = cx.tables.expr_ty(expr); if let ty::TyRef(_, inner, _) = arg_ty.sty { if let ty::TyRef(_, innermost, _) = inner.sty { @@ -1133,14 +1136,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; @@ -1165,7 +1168,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t } } -fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) { +fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Expr) { let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg)); if let ty::TyAdt(_, subst) = obj_ty.sty { @@ -1191,7 +1194,7 @@ fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) { } -fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { +fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) { let arg = &args[1]; if let Some(arglists) = method_chain_args(arg, &["chars"]) { let target = &arglists[0][0]; @@ -1220,18 +1223,18 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { } } -fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { +fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) { let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); if match_type(cx, obj_ty, &paths::STRING) { lint_string_extend(cx, expr, args); } } -fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwrap: &hir::Expr) { +fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, new: &hir::Expr, unwrap: &hir::Expr) { if_chain! { - if 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 { @@ -1248,7 +1251,7 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr } } -fn lint_iter_cloned_collect(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr]) { +fn lint_iter_cloned_collect(cx: &LateContext<'_, '_>, expr: &hir::Expr, iter_args: &[hir::Expr]) { if match_type(cx, cx.tables.expr_ty(expr), &paths::VEC) && derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() { @@ -1262,7 +1265,7 @@ fn lint_iter_cloned_collect(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir } } -fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::Expr]) { +fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args: &[hir::Expr]) { // Check that this is a call to Iterator::fold rather than just some function called fold if !match_trait_method(cx, expr, &paths::ITERATOR) { return; @@ -1272,20 +1275,20 @@ fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::E "Expected fold_args to have three entries - the receiver, the initial value and the closure"); fn check_fold_with_op( - cx: &LateContext, + 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 +1332,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 } @@ -1350,7 +1353,7 @@ fn lint_unnecessary_fold(cx: &LateContext, expr: &hir::Expr, fold_args: &[hir::E }; } -fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is_mut: bool) { +fn lint_iter_nth(cx: &LateContext<'_, '_>, expr: &hir::Expr, iter_args: &[hir::Expr], is_mut: bool) { let mut_str = if is_mut { "_mut" } else { "" }; let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() { "slice" @@ -1374,7 +1377,7 @@ fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is ); } -fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) { +fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) { // Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap, // because they do not implement `IndexMut` let expr_ty = cx.tables.expr_ty(&get_args[0]); @@ -1413,7 +1416,7 @@ fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], i ); } -fn lint_iter_skip_next(cx: &LateContext, expr: &hir::Expr) { +fn lint_iter_skip_next(cx: &LateContext<'_, '_>, expr: &hir::Expr) { // lint if caller of skip is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { span_lint( @@ -1425,8 +1428,8 @@ fn lint_iter_skip_next(cx: &LateContext, expr: &hir::Expr) { } } -fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: Ty) -> Option<sugg::Sugg<'static>> { - fn may_slice(cx: &LateContext, ty: Ty) -> bool { +fn derefs_to_slice(cx: &LateContext<'_, '_>, expr: &hir::Expr, ty: Ty<'_>) -> Option<sugg::Sugg<'static>> { + fn may_slice(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { match ty.sty { ty::TySlice(_) => true, ty::TyAdt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), @@ -1437,7 +1440,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 { @@ -1458,7 +1461,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: Ty) -> Option<sugg::S } /// lint use of `unwrap()` for `Option`s and `Result`s -fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) { +fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, unwrap_args: &[hir::Expr]) { let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&unwrap_args[0])); let mess = if match_type(cx, obj_ty, &paths::OPTION) { @@ -1486,7 +1489,7 @@ fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) { } /// lint use of `ok().expect()` for `Result`s -fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) { +fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr, ok_args: &[hir::Expr]) { // lint if the caller of `ok()` is a `Result` if match_type(cx, cx.tables.expr_ty(&ok_args[0]), &paths::RESULT) { let result_type = cx.tables.expr_ty(&ok_args[0]); @@ -1504,7 +1507,7 @@ fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) { } /// lint use of `map().unwrap_or()` for `Option`s -fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) { +fn lint_map_unwrap_or(cx: &LateContext<'_, '_>, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) { // lint if the caller of `map()` is an `Option` if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) { // get snippets for args to map() and unwrap_or() @@ -1615,7 +1618,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 @@ -1762,7 +1765,7 @@ struct BinaryExprInfo<'a> { } /// Checks for the `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. -fn lint_binary_expr_with_method_call<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, info: &mut BinaryExprInfo) { +fn lint_binary_expr_with_method_call(cx: &LateContext<'_, '_>, info: &mut BinaryExprInfo<'_>) { macro_rules! lint_with_both_lhs_and_rhs { ($func:ident, $cx:expr, $info:ident) => { if !$func($cx, $info) { @@ -1781,18 +1784,18 @@ fn lint_binary_expr_with_method_call<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, i } /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_NEXT_CMP` lints. -fn lint_chars_cmp<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - info: &BinaryExprInfo, +fn lint_chars_cmp( + cx: &LateContext<'_, '_>, + info: &BinaryExprInfo<'_>, chain_methods: &[&str], lint: &'static Lint, suggest: &str, ) -> 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 { @@ -1821,12 +1824,12 @@ fn lint_chars_cmp<'a, 'tcx>( } /// Checks for the `CHARS_NEXT_CMP` lint. -fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo) -> bool { +fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { lint_chars_cmp(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with") } /// Checks for the `CHARS_LAST_CMP` lint. -fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo) -> bool { +fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_NEXT_CMP, "ends_with") { true } else { @@ -1837,14 +1840,14 @@ fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprIn /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`. fn lint_chars_cmp_with_unwrap<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, - info: &BinaryExprInfo, + info: &BinaryExprInfo<'_>, chain_methods: &[&str], lint: &'static Lint, suggest: &str, ) -> 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( @@ -1868,12 +1871,12 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>( } /// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`. -fn lint_chars_next_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo) -> bool { +fn lint_chars_next_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { lint_chars_cmp_with_unwrap(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with") } /// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`. -fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo) -> bool { +fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { if lint_chars_cmp_with_unwrap(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") { true } else { @@ -1904,7 +1907,7 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hi } /// Checks for the `USELESS_ASREF` lint. -fn lint_asref(cx: &LateContext, expr: &hir::Expr, call_name: &str, as_ref_args: &[hir::Expr]) { +fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_ref_args: &[hir::Expr]) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" // check if the call is to the actual `AsRef` or `AsMut` trait if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { @@ -1928,7 +1931,7 @@ fn lint_asref(cx: &LateContext, expr: &hir::Expr, call_name: &str, as_ref_args: } /// Given a `Result<T, E>` type, return its error type (`E`). -fn get_error_type<'a>(cx: &LateContext, ty: Ty<'a>) -> Option<Ty<'a>> { +fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> { if let ty::TyAdt(_, substs) = ty.sty { if match_type(cx, ty, &paths::RESULT) { substs.types().nth(1) @@ -2030,6 +2033,7 @@ enum SelfKind { impl SelfKind { fn matches( self, + cx: &LateContext<'_, '_>, ty: &hir::Ty, arg: &hir::Arg, self_ty: &hir::Ty, @@ -2047,7 +2051,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 +2060,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 +2131,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 +2143,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 @@ -2156,7 +2160,7 @@ impl Convention { } impl fmt::Display for Convention { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { Convention::Eq(this) => this.fmt(f), Convention::StartsWith(this) => this.fmt(f).and_then(|_| '*'.fmt(f)), @@ -2173,20 +2177,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 diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 4be2b9f5227..bc573841cc8 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -2,6 +2,7 @@ use crate::consts::{constant_simple, Constant}; use crate::utils::{match_def_path, opt_def_id, paths, span_lint}; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use std::cmp::Ordering; /// **What it does:** Checks for expressions where `std::cmp::min` and `max` are @@ -65,9 +66,9 @@ enum MinMax { Max, } -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 { +fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<(MinMax, Constant, &'a Expr)> { + 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) @@ -85,7 +86,7 @@ fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &' } } -fn fetch_const<'a>(cx: &LateContext, args: &'a [Expr], m: MinMax) -> Option<(MinMax, Constant, &'a Expr)> { +fn fetch_const<'a>(cx: &LateContext<'_, '_>, args: &'a [Expr], m: MinMax) -> Option<(MinMax, Constant, &'a Expr)> { if args.len() != 2 { return None; } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 697f15bdd1d..b01d24a1ad3 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -1,12 +1,15 @@ use crate::reexport::*; +use matches::matches; use rustc::hir::*; use rustc::hir::intravisit::FnKind; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; 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 +272,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 +306,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 +316,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 +326,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 +370,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 +381,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 +395,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 +421,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, @@ -430,7 +433,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -fn check_nan(cx: &LateContext, path: &Path, expr: &Expr) { +fn check_nan(cx: &LateContext<'_, '_>, path: &Path, expr: &Expr) { if !in_constant(cx, expr.id) { if let Some(seg) = path.segments.last() { if seg.ident.name == "NAN" { @@ -461,20 +464,20 @@ fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -> bool { } } -fn is_float(cx: &LateContext, expr: &Expr) -> bool { +fn is_float(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::TyFloat(_)) } -fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { +fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) { let (arg_ty, snip) = match expr.node { - 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 +523,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 @@ -539,10 +542,10 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { /// Heuristic to see if an expression is used. Should be compatible with /// `unused_variables`'s idea /// of what it means for an expression to be "used". -fn is_used(cx: &LateContext, expr: &Expr) -> bool { +fn is_used(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { if let Some(parent) = get_parent_expr(cx, expr) { 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 { @@ -562,17 +565,17 @@ fn in_attributes_expansion(expr: &Expr) -> bool { } /// Test whether `def` is a variable defined outside a macro. -fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool { +fn non_macro_local(cx: &LateContext<'_, '_>, def: &def::Def) -> bool { match *def { def::Def::Local(id) | def::Def::Upvar(id, _, _) => !in_macro(cx.tcx.hir.span(id)), _ => false, } } -fn check_cast(cx: &LateContext, span: Span, e: &Expr, ty: &Ty) { +fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr, ty: &Ty) { if_chain! { - if 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); diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index 87e4d343ab4..9b8e0743f39 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -1,10 +1,12 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use std::collections::HashMap; use std::char; use syntax::ast::*; use syntax::codemap::Span; use syntax::visit::FnKind; -use crate::utils::{constants, in_external_macro, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then}; +use crate::utils::{constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then}; /// **What it does:** Checks for structure field patterns bound to wildcards. /// @@ -187,7 +189,7 @@ impl LintPass for MiscEarly { } impl EarlyLintPass for MiscEarly { - fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) { + fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) { for param in &gen.params { if let GenericParamKind::Type { .. } = param.kind { let name = param.ident.as_str(); @@ -203,7 +205,7 @@ impl EarlyLintPass for MiscEarly { } } - fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) { + fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) { if let PatKind::Struct(ref npat, ref pfields, _) = pat.node { let mut wilds = 0; let type_name = npat.segments @@ -213,7 +215,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 +233,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( @@ -263,7 +266,7 @@ impl EarlyLintPass for MiscEarly { } } - fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: Span, _: NodeId) { + fn check_fn(&mut self, cx: &EarlyContext<'_>, _: FnKind<'_>, decl: &FnDecl, _: Span, _: NodeId) { let mut registered_names: HashMap<String, Span> = HashMap::new(); for arg in &decl.inputs { @@ -290,8 +293,8 @@ impl EarlyLintPass for MiscEarly { } } - fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { - if in_external_macro(cx, expr.span) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if in_external_macro(cx.sess(), expr.span) { return; } match expr.node { @@ -322,7 +325,7 @@ impl EarlyLintPass for MiscEarly { } } - fn check_block(&mut self, cx: &EarlyContext, block: &Block) { + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) { for w in block.stmts.windows(2) { if_chain! { if let StmtKind::Local(ref local) = w[0].node; @@ -349,7 +352,7 @@ impl EarlyLintPass for MiscEarly { } impl MiscEarly { - fn check_lit(self, cx: &EarlyContext, lit: &Lit) { + fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) { if_chain! { if let LitKind::Int(value, ..) = lit.node; if let Some(src) = snippet_opt(cx, lit.span); diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index ebb3869f48c..fe2bbbdb9af 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -20,6 +20,7 @@ use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; use syntax::ast; use syntax::attr; @@ -66,7 +67,7 @@ impl MissingDoc { .expect("empty doc_hidden_stack") } - fn check_missing_docs_attrs(&self, cx: &LateContext, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { + fn check_missing_docs_attrs(&self, cx: &LateContext<'_, '_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { // If we're building a test harness, then warning about // documentation is probably not really relevant right now. if cx.sess().opts.test { @@ -122,9 +123,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 +136,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); @@ -177,6 +178,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ImplItemKind::Const(..) => "an associated constant", hir::ImplItemKind::Method(..) => "a method", hir::ImplItemKind::Type(_) => "an associated type", + hir::ImplItemKind::Existential(_) => "an existential type", }; self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, desc); } diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs new file mode 100644 index 00000000000..e19ec4da67e --- /dev/null +++ b/clippy_lints/src/missing_inline.rs @@ -0,0 +1,191 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// + +use rustc::hir; +use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use syntax::ast; +use syntax::codemap::Span; + +/// **What it does:** it lints if an exported function, method, trait method with default impl, +/// or trait method impl is not `#[inline]`. +/// +/// **Why is this bad?** In general, it is not. Functions can be inlined across +/// crates when that's profitable as long as any form of LTO is used. When LTO is disabled, +/// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates +/// might intend for most of the methods in their public API to be able to be inlined across +/// crates even when LTO is disabled. For these types of crates, enabling this lint might make sense. +/// It allows the crate to require all exported methods to be `#[inline]` by default, and then opt +/// out for specific methods where this might not make sense. +/// +/// **Known problems:** None. +/// +/// **Example:** +/// ```rust +/// pub fn foo() {} // missing #[inline] +/// fn ok() {} // ok +/// #[inline] pub fn bar() {} // ok +/// #[inline(always)] pub fn baz() {} // ok +/// +/// pub trait Bar { +/// fn bar(); // ok +/// fn def_bar() {} // missing #[inline] +/// } +/// +/// struct Baz; +/// impl Baz { +/// fn priv() {} // ok +/// } +/// +/// impl Bar for Baz { +/// fn bar() {} // ok - Baz is not exported +/// } +/// +/// pub struct PubBaz; +/// impl PubBaz { +/// fn priv() {} // ok +/// pub not_ptriv() {} // missing #[inline] +/// } +/// +/// impl Bar for PubBaz { +/// fn bar() {} // missing #[inline] +/// fn def_bar() {} // missing #[inline] +/// } +/// ``` +declare_clippy_lint! { + pub MISSING_INLINE_IN_PUBLIC_ITEMS, + restriction, + "detects missing #[inline] attribute for public callables (functions, trait methods, methods...)" +} + +pub struct MissingInline; + +fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, + attrs: &[ast::Attribute], sp: Span, desc: &'static str) { + let has_inline = attrs + .iter() + .any(|a| a.name() == "inline" ); + if !has_inline { + cx.span_lint( + MISSING_INLINE_IN_PUBLIC_ITEMS, + sp, + &format!("missing `#[inline]` for {}", desc), + ); + } +} + +fn is_executable<'a, 'tcx>(cx: &LateContext<'a, 'tcx>) -> bool { + use rustc::session::config::CrateType; + + cx.tcx.sess.crate_types.get().iter().any(|t: &CrateType| { + match t { + CrateType::CrateTypeExecutable => true, + _ => false, + } + }) +} + +impl LintPass for MissingInline { + fn get_lints(&self) -> LintArray { + lint_array![MISSING_INLINE_IN_PUBLIC_ITEMS] + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline { + fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item) { + if is_executable(cx) { + return; + } + + if !cx.access_levels.is_exported(it.id) { + return; + } + match it.node { + hir::ItemKind::Fn(..) => { + let desc = "a function"; + check_missing_inline_attrs(cx, &it.attrs, it.span, desc); + }, + 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. + for tit in trait_items { + let tit_ = cx.tcx.hir.trait_item(tit.id); + match tit_.node { + hir::TraitItemKind::Const(..) | + hir::TraitItemKind::Type(..) => {}, + hir::TraitItemKind::Method(..) => { + if tit.defaultness.has_value() { + // trait method with default body needs inline in case + // an impl is not provided + let desc = "a default trait method"; + let item = cx.tcx.hir.expect_trait_item(tit.id.node_id); + check_missing_inline_attrs(cx, &item.attrs, + item.span, desc); + } + }, + } + } + } + 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(..) => {}, + }; + } + + fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem) { + use rustc::ty::{TraitContainer, ImplContainer}; + if is_executable(cx) { + return; + } + + // If the item being implemented is not exported, then we don't need #[inline] + if !cx.access_levels.is_exported(impl_item.id) { + return; + } + + let desc = match impl_item.node { + hir::ImplItemKind::Method(..) => "a method", + hir::ImplItemKind::Const(..) | + hir::ImplItemKind::Type(_) | + hir::ImplItemKind::Existential(_) => return, + }; + + let def_id = cx.tcx.hir.local_def_id(impl_item.id); + let trait_def_id = match cx.tcx.associated_item(def_id).container { + TraitContainer(cid) => Some(cid), + ImplContainer(cid) => cx.tcx.impl_trait_ref(cid).map(|t| t.def_id), + }; + + if let Some(trait_def_id) = trait_def_id { + if let Some(n) = cx.tcx.hir.as_local_node_id(trait_def_id) { + if !cx.access_levels.is_exported(n) { + // If a trait is being implemented for an item, and the + // trait is not exported, we don't need #[inline] + return; + } + } + } + + check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc); + } +} diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs index d347270236d..d4246045506 100644 --- a/clippy_lints/src/multiple_crate_versions.rs +++ b/clippy_lints/src/multiple_crate_versions.rs @@ -1,6 +1,7 @@ //! lint on multiple versions of a crate being used use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use cargo_metadata; @@ -38,7 +39,7 @@ impl LintPass for Pass { } impl EarlyLintPass for Pass { - fn check_crate(&mut self, cx: &EarlyContext, krate: &Crate) { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { let metadata = match cargo_metadata::metadata_deps(None, true) { Ok(metadata) => metadata, Err(_) => { diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index 26837313a06..0413f1ab603 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -1,8 +1,9 @@ use rustc::hir; use rustc::hir::intravisit; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty; -use crate::utils::{higher, in_external_macro, span_lint}; +use crate::utils::{higher, span_lint}; /// **What it does:** Checks for instances of `mut mut` references. /// @@ -49,7 +50,7 @@ pub struct MutVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { - if in_external_macro(self.cx, expr.span) { + if in_external_macro(self.cx.sess(), expr.span) { return; } @@ -62,8 +63,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 +88,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 +96,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, diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 4e9c5c815cc..de4c5444440 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::ty::{self, Ty}; use rustc::ty::subst::Subst; use rustc::hir::*; @@ -36,7 +37,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 +45,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 +70,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, diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index e5679bb7ba5..50ef9f268f2 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -3,6 +3,7 @@ //! This lint is **warn** by default use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use rustc::ty::{self, Ty}; use rustc::hir::Expr; use syntax::ast; @@ -79,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic { } } -fn get_atomic_name(ty: Ty) -> Option<(&'static str)> { +fn get_atomic_name(ty: Ty<'_>) -> Option<(&'static str)> { match ty.sty { ty::TyBool => Some("AtomicBool"), ty::TyUint(_) => Some("AtomicUsize"), diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 885cb4b72cb..559aa74f9a2 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -3,6 +3,7 @@ //! This lint is **warn** by default use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use syntax::ast::LitKind; use syntax::codemap::Spanned; @@ -60,7 +61,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 +81,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 +106,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 +124,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 +185,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 +200,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, }, diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 84d5292d8c5..7986b43919c 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -3,7 +3,9 @@ //! This lint is **warn** by default use rustc::lint::*; -use rustc::hir::{BindingAnnotation, Expr, ExprAddrOf, MutImmutable, Pat, PatKind}; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; +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 +42,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 { diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index 91cc01891a9..1679a9007b4 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -3,6 +3,8 @@ //! This lint is **warn** by default use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::{BindingAnnotation, MutImmutable, Pat, PatKind}; use crate::utils::{in_macro, snippet, span_lint_and_then}; diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 3258bcd069a..60ab0eaae02 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -28,6 +28,7 @@ //! //! This lint is **warn** by default. use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast; use syntax::codemap::{original_sp, DUMMY_SP}; use std::borrow::Cow; @@ -109,7 +110,7 @@ impl LintPass for NeedlessContinue { } impl EarlyLintPass for NeedlessContinue { - fn check_expr(&mut self, ctx: &EarlyContext, expr: &ast::Expr) { + fn check_expr(&mut self, ctx: &EarlyContext<'_>, expr: &ast::Expr) { if !in_macro(expr.span) { check_and_warn(ctx, expr); } @@ -264,7 +265,7 @@ const DROP_ELSE_BLOCK_MSG: &str = "Consider dropping the else clause, and moving block, like so:\n"; -fn emit_warning<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str, typ: LintType) { +fn emit_warning<'a>(ctx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str, typ: LintType) { // snip is the whole *help* message that appears after the warning. // message is the warning message. // expr is the expression which the lint warning message refers to. @@ -283,7 +284,7 @@ fn emit_warning<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str, typ: L span_help_and_lint(ctx, NEEDLESS_CONTINUE, expr.span, message, &snip); } -fn suggestion_snippet_for_continue_inside_if<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str) -> String { +fn suggestion_snippet_for_continue_inside_if<'a>(ctx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str) -> String { let cond_code = snippet(ctx, data.if_cond.span, ".."); let if_code = format!("if {} {{\n continue;\n}}\n", cond_code); @@ -300,7 +301,7 @@ fn suggestion_snippet_for_continue_inside_if<'a>(ctx: &EarlyContext, data: &'a L ret } -fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str) -> String { +fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str) -> String { let cond_code = snippet(ctx, data.if_cond.span, ".."); let mut if_code = format!("if {} {{\n", cond_code); @@ -331,7 +332,7 @@ fn suggestion_snippet_for_continue_inside_else<'a>(ctx: &EarlyContext, data: &'a ret } -fn check_and_warn<'a>(ctx: &EarlyContext, expr: &'a ast::Expr) { +fn check_and_warn<'a>(ctx: &EarlyContext<'_>, expr: &'a ast::Expr) { with_loop_block(expr, |loop_block| { for (i, stmt) in loop_block.stmts.iter().enumerate() { with_if_expr(stmt, |if_expr, cond, then_block, else_expr| { diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index bdef092b533..82e85f3453a 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -1,7 +1,10 @@ +use matches::matches; use rustc::hir::*; use rustc::hir::map::*; use rustc::hir::intravisit::FnKind; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, RegionKind, TypeFoldable}; use rustc::traits; use rustc::middle::expr_use_visitor as euv; @@ -88,8 +91,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; } @@ -201,7 +204,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { } // Dereference suggestion - let sugg = |db: &mut DiagnosticBuilder| { + let sugg = |db: &mut DiagnosticBuilder<'_>| { if let ty::TypeVariants::TyAdt(def, ..) = ty.sty { if let Some(span) = cx.tcx.hir.span_if_local(def.did) { if cx.param_env.can_type_implement_copy(cx.tcx, ty).is_ok() { @@ -215,7 +218,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 +342,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 +353,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) @@ -393,7 +396,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'tcx> { } } - fn borrow(&mut self, _: NodeId, _: Span, _: &mc::cmt_<'tcx>, _: ty::Region, _: ty::BorrowKind, _: euv::LoanCause) {} + fn borrow(&mut self, _: NodeId, _: Span, _: &mc::cmt_<'tcx>, _: ty::Region<'_>, _: ty::BorrowKind, _: euv::LoanCause) {} fn mutate(&mut self, _: NodeId, _: Span, _: &mc::cmt_<'tcx>, _: euv::MutateMode) {} diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 87b92a53dd0..52c4c6e5237 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -1,6 +1,7 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; 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 +33,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() { diff --git a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index cae88263111..02007e2de43 100644 --- a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -1,7 +1,9 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; -use crate::utils::{self, paths, span_lint, in_external_macro}; +use crate::utils::{self, paths, span_lint}; /// **What it does:** /// Checks for the usage of negated comparison operators on types which only implement @@ -22,16 +24,16 @@ use crate::utils::{self, paths, span_lint, in_external_macro}; /// // 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! { @@ -53,10 +55,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { 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 !in_external_macro(cx.sess(), expr.span); + 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 { diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index efcc1695eb6..c056ff46178 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::codemap::{Span, Spanned}; use crate::consts::{self, Constant}; @@ -33,20 +35,20 @@ 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), _ => (), } } } } -fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) { +fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr, exp: &Expr) { if_chain! { - if 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(); diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 3f7cbaa6ca1..eeb131959e9 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -1,10 +1,12 @@ use rustc::hir::def_id::DefId; use rustc::hir; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use syntax::codemap::Span; use crate::utils::paths; -use crate::utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint_and_then}; +use crate::utils::{get_trait_def_id, implements_trait, return_ty, same_tys, span_lint_and_then}; use crate::utils::sugg::DiagnosticBuilderExt; /// **What it does:** Checks for types with a `fn new() -> Self` method and no @@ -89,11 +91,11 @@ 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); - if in_external_macro(cx, impl_item.span) { + if in_external_macro(cx.sess(), impl_item.span) { return; } if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { @@ -155,7 +157,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { } } -fn create_new_without_default_suggest_msg(ty: Ty) -> String { +fn create_new_without_default_suggest_msg(ty: Ty<'_>) -> String { #[cfg_attr(rustfmt, rustfmt_skip)] format!( "impl Default for {} {{ diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 8d351f87421..cacb5d6a9ff 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -1,6 +1,7 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; 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; @@ -40,31 +41,31 @@ declare_clippy_lint! { "outer expressions with no effect" } -fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool { +fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { if in_macro(expr.span) { 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 +76,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 +98,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) { @@ -127,24 +128,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } -fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Expr>> { +fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<Vec<&'a Expr>> { if in_macro(expr.span) { 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 +157,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 +170,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 { diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 47c84fec6ae..f2c9210aae4 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -3,6 +3,7 @@ //! This lint is **deny** by default. use rustc::lint::{LateContext, LateLintPass, Lint, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::hir::def::Def; use rustc::ty::{self, TypeFlags}; @@ -164,7 +165,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 +183,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 +191,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 +214,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. diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index b49e3f87ec9..e9688262c2a 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Span; use syntax::symbol::LocalInternedString; use syntax::ast::*; @@ -311,13 +312,13 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> { } impl EarlyLintPass for NonExpressiveNames { - fn check_item(&mut self, cx: &EarlyContext, item: &Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { if let ItemKind::Fn(ref decl, _, _, ref blk) = item.node { do_check(self, cx, &item.attrs, decl, blk); } } - fn check_impl_item(&mut self, cx: &EarlyContext, item: &ImplItem) { + fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &ImplItem) { if let ImplItemKind::Method(ref sig, ref blk) = item.node { do_check(self, cx, &item.attrs, &sig.decl, blk); } @@ -325,7 +326,7 @@ impl EarlyLintPass for NonExpressiveNames { } -fn do_check(lint: &mut NonExpressiveNames, cx: &EarlyContext, attrs: &[Attribute], decl: &FnDecl, blk: &Block) { +fn do_check(lint: &mut NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) { if !attr::contains_name(attrs, "test") { let mut visitor = SimilarNamesLocalVisitor { names: Vec::new(), diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs index a2573b91f96..2a7f71c7145 100644 --- a/clippy_lints/src/ok_if_let.rs +++ b/clippy_lints/src/ok_if_let.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; use crate::utils::{match_type, method_chain_args, paths, snippet, span_help_and_lint}; @@ -44,9 +46,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; diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index fbece822659..effeb88d0cf 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -1,5 +1,6 @@ -use rustc::hir::{Expr, ExprLit, ExprMethodCall}; +use rustc::hir::{Expr, ExprKind}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::LitKind; use syntax::codemap::{Span, Spanned}; use crate::utils::{match_type, paths, span_lint, walk_ptrs_ty}; @@ -33,7 +34,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(); @@ -60,14 +61,14 @@ enum OpenOption { Append, } -fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOption, Argument)>) { - if let ExprMethodCall(ref path, _, ref arguments) = argument.node { +fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr, options: &mut Vec<(OpenOption, Argument)>) { + 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), .. @@ -111,7 +112,7 @@ fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOp } } -fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span: Span) { +fn check_open_options(cx: &LateContext<'_, '_>, options: &[(OpenOption, Argument)], span: Span) { let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false); let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) = (false, false, false, false, false); diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index 3a95471d0a2..5714bdb521c 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -1,6 +1,8 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; -use crate::utils::span_lint; +use crate::utils::{span_lint, SpanlessEq}; /// **What it does:** Detects classic underflow/overflow checks. /// @@ -31,24 +33,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 +60,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."); } diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index f00a15dd401..e603773f7ba 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast::LitKind; use syntax::ptr::P; use syntax::ext::quote::rt::Span; @@ -52,10 +54,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; @@ -84,9 +86,9 @@ fn get_outer_span(expr: &Expr) -> Span { } } -fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext) { +fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext<'_, '_>) { if_chain! { - if 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("}}", ""); diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 1d9260e2aa7..675d014c527 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; use crate::utils::{is_automatically_derived, span_lint}; @@ -38,7 +40,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; diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 7f5dd2abc0e..6a0f4f147b7 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use syntax::codemap::Spanned; use crate::utils::{in_macro, snippet, span_lint_and_sugg}; @@ -36,7 +37,7 @@ impl LintPass for Precedence { } impl EarlyLintPass for Precedence { - fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if in_macro(expr.span) { return; } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 68cecc8de67..ea2d07df455 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -5,6 +5,8 @@ use rustc::hir::*; use rustc::hir::map::NodeItem; use rustc::hir::QPath; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use syntax::ast::NodeId; use syntax::codemap::Span; @@ -103,7 +105,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 +113,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 +133,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, @@ -144,7 +146,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass { } } -fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<BodyId>) { +fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<BodyId>) { let fn_def_id = cx.tcx.hir.local_def_id(fn_id); let sig = cx.tcx.fn_sig(fn_def_id); let fn_ty = sig.skip_binder(); @@ -159,7 +161,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 +221,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 +275,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 +283,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); } } diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index d12f6ddd15a..630dd1b57be 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; use rustc::hir::def::Def; use crate::utils::sugg::Sugg; @@ -50,10 +52,10 @@ 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) { + 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); @@ -79,25 +81,25 @@ impl QuestionMarkPass { } } - fn is_option(cx: &LateContext, expression: &Expr) -> bool { + fn is_option(cx: &LateContext<'_, '_>, expression: &Expr) -> bool { let expr_ty = cx.tables.expr_ty(expression); match_type(cx, expr_ty, &OPTION) } - fn expression_returns_none(cx: &LateContext, expression: &Expr) -> bool { + 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 +115,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 { diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 6ec624d26e9..fd303bb6ab4 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -1,9 +1,11 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; 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 +90,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 +109,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, @@ -174,7 +176,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -fn has_step_by(cx: &LateContext, expr: &Expr) -> bool { +fn has_step_by(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { // No need for walk_ptrs_ty here because step_by moves self, so it // can't be called on a borrowed range. let ty = cx.tables.expr_ty_adjusted(expr); @@ -184,7 +186,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 +199,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, } } diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index e63e978e26b..4f28d36e2a8 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::{in_macro, is_range_expression, match_var, span_lint_and_sugg}; @@ -43,7 +44,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; diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index d8179816236..f349f46d926 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -1,5 +1,7 @@ use syntax::ast::{Expr, ExprKind, UnOp}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use crate::utils::{snippet, span_lint_and_sugg}; /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. @@ -37,7 +39,7 @@ fn without_parens(mut e: &Expr) -> &Expr { } impl EarlyLintPass for Pass { - fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) { if_chain! { if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node; if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node; @@ -82,7 +84,7 @@ impl LintPass for DerefPass { } impl EarlyLintPass for DerefPass { - fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) { if_chain! { if let ExprKind::Field(ref object, ref field_name) = e.node; if let ExprKind::Paren(ref parened) = object.node; diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 6395125578c..39b7888dcc6 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -1,6 +1,8 @@ use regex_syntax; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use std::collections::HashSet; use syntax::ast::{LitKind, NodeId, StrStyle}; use syntax::codemap::{BytePos, Span}; @@ -108,8 +110,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 +178,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 +194,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 }; diff --git a/clippy_lints/src/replace_consts.rs b/clippy_lints/src/replace_consts.rs index d6d9125a49c..b9a4c6ebb19 100644 --- a/clippy_lints/src/replace_consts.rs +++ b/clippy_lints/src/replace_consts.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir; use rustc::hir::def::Def; use crate::utils::{match_def_path, span_lint_and_sugg}; @@ -37,7 +39,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 { diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 03a5d58a3ee..0ede1bc9727 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,9 +1,11 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use syntax::ast; use syntax::codemap::Span; use syntax::visit::FnKind; -use crate::utils::{in_external_macro, in_macro, match_path_ast, snippet_opt, span_lint_and_then, span_note_and_lint}; +use crate::utils::{in_macro, match_path_ast, snippet_opt, span_lint_and_then, span_note_and_lint}; /// **What it does:** Checks for return statements at the end of a block. /// @@ -47,7 +49,7 @@ pub struct ReturnPass; impl ReturnPass { // Check the final stmt or expr in a block for unnecessary return. - fn check_block_return(&mut self, cx: &EarlyContext, block: &ast::Block) { + fn check_block_return(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) { if let Some(stmt) = block.stmts.last() { match stmt.node { ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => { @@ -59,7 +61,7 @@ impl ReturnPass { } // Check a the final expression in a block if it's a return. - fn check_final_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr, span: Option<Span>) { + fn check_final_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr, span: Option<Span>) { match expr.node { // simple return is always "bad" ast::ExprKind::Ret(Some(ref inner)) => { @@ -87,8 +89,8 @@ impl ReturnPass { } } - fn emit_return_lint(&mut self, cx: &EarlyContext, ret_span: Span, inner_span: Span) { - if in_external_macro(cx, inner_span) || in_macro(inner_span) { + fn emit_return_lint(&mut self, cx: &EarlyContext<'_>, ret_span: Span, inner_span: Span) { + if in_external_macro(cx.sess(), inner_span) || in_macro(inner_span) { return; } span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded return statement", |db| { @@ -99,7 +101,7 @@ impl ReturnPass { } // Check for "let x = EXPR; x" - fn check_let_return(&mut self, cx: &EarlyContext, block: &ast::Block) { + fn check_let_return(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) { let mut it = block.stmts.iter(); // we need both a let-binding stmt and an expr @@ -115,7 +117,7 @@ impl ReturnPass { if let ast::PatKind::Ident(_, ident, _) = local.pat.node; if let ast::ExprKind::Path(_, ref path) = retexpr.node; if match_path_ast(path, &[&ident.as_str()]); - if !in_external_macro(cx, initexpr.span); + if !in_external_macro(cx.sess(), initexpr.span); then { span_note_and_lint(cx, LET_AND_RETURN, @@ -136,14 +138,14 @@ impl LintPass for ReturnPass { } impl EarlyLintPass for ReturnPass { - fn check_fn(&mut self, cx: &EarlyContext, kind: FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { + fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) { match kind { FnKind::ItemFn(.., block) | FnKind::Method(.., block) => self.check_block_return(cx, block), FnKind::Closure(body) => self.check_final_expr(cx, body, Some(body.span)), } } - fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) { + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) { self.check_let_return(cx, block); } } diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs index a4bdd89a037..ce326ea72ca 100644 --- a/clippy_lints/src/serde_api.rs +++ b/clippy_lints/src/serde_api.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use crate::utils::{get_trait_def_id, paths, span_lint}; @@ -29,7 +30,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 { diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index d37023e4f8c..aab578d6344 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -1,10 +1,11 @@ use crate::reexport::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use rustc::hir::intravisit::FnKind; use rustc::ty; use syntax::codemap::Span; -use crate::utils::{contains_name, higher, in_external_macro, iter_input_pats, snippet, span_lint_and_then}; +use crate::utils::{contains_name, higher, iter_input_pats, snippet, span_lint_and_then}; /// **What it does:** Checks for bindings that shadow other bindings already in /// scope, while just changing reference level or mutability. @@ -89,7 +90,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { _: Span, _: NodeId, ) { - if in_external_macro(cx, body.value.span) { + if in_external_macro(cx.sess(), body.value.span) { return; } check_fn(cx, decl, body); @@ -110,8 +111,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 { @@ -121,13 +122,13 @@ fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block, binding } fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings: &mut Vec<(Name, Span)>) { - if in_external_macro(cx, decl.span) { + if in_external_macro(cx.sess(), decl.span) { return; } 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, @@ -147,7 +148,7 @@ fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings: } } -fn is_binding(cx: &LateContext, pat_id: HirId) -> bool { +fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool { let var_ty = cx.tables.node_id_to_type(pat_id); match var_ty.sty { ty::TyAdt(..) => false, @@ -185,7 +186,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 +206,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 +221,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); @@ -302,31 +303,31 @@ fn lint_shadow<'a, 'tcx: 'a>( } fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings: &mut Vec<(Name, Span)>) { - if in_external_macro(cx, expr.span) { + if in_external_macro(cx.sess(), expr.span) { 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 +348,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, } } diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 62cd5de68f0..a13f864c5ce 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -1,5 +1,6 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::codemap::Spanned; use crate::utils::SpanlessEq; use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty}; @@ -82,12 +83,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 +103,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, @@ -116,14 +117,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { } } -fn is_string(cx: &LateContext, e: &Expr) -> bool { +fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool { match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING) } -fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { +fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool { 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 +149,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( diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index e3ccfec4685..b0a8a2d0061 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use syntax::ast; @@ -59,10 +61,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 +78,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 +101,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 +136,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( @@ -142,11 +163,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl { } fn check_binop<'a>( - cx: &LateContext, + 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 +188,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 +206,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 }, _ => {}, diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 1037a1bc632..38369d05676 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -1,5 +1,8 @@ +use matches::matches; use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty; use crate::utils::{differing_macro_contexts, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty, SpanlessEq}; use crate::utils::sugg::Sugg; @@ -57,23 +60,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Swap { } /// Implementation of the `MANUAL_SWAP` lint. -fn check_manual_swap(cx: &LateContext, block: &Block) { +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(); @@ -81,12 +84,12 @@ fn check_manual_swap(cx: &LateContext, block: &Block) { if SpanlessEq::new(cx).ignore_fn().eq_expr(rhs1, lhs2); then { fn check_for_slice<'a>( - cx: &LateContext, + cx: &LateContext<'_, '_>, 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)); @@ -142,14 +145,14 @@ fn check_manual_swap(cx: &LateContext, block: &Block) { } /// Implementation of the `ALMOST_SWAPPED` lint. -fn check_suspicious_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 { diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index cd13ab0d51f..56e705ad0a7 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -1,5 +1,6 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; -use rustc::hir::{Expr, ExprAssign, ExprField, ExprStruct, ExprTup}; +use rustc::{declare_lint, lint_array}; +use rustc::hir::{Expr, ExprKind}; use crate::utils::is_adjusted; use crate::utils::span_lint; @@ -23,7 +24,7 @@ declare_clippy_lint! { fn is_temporary(expr: &Expr) -> bool { match expr.node { - ExprStruct(..) | ExprTup(..) => true, + ExprKind::Struct(..) | ExprKind::Tup(..) => true, _ => false, } } @@ -39,8 +40,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"); } diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index c2e981979a1..403aeb47402 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use rustc::hir::*; use std::borrow::Cow; @@ -215,8 +217,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]); @@ -452,7 +454,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { /// the type's `ToString` implementation. In weird cases it could lead to types /// with invalid `'_` /// lifetime, but it should be rare. -fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String { +fn get_type_snippet(cx: &LateContext<'_, '_>, path: &QPath, to_ref_ty: Ty<'_>) -> String { let seg = last_path_segment(path); if_chain! { if let Some(ref params) = seg.args; @@ -461,7 +463,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(); } diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 8d0ddbec988..6a048b19213 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -1,9 +1,12 @@ use std::cmp; +use matches::matches; use rustc::hir::*; use rustc::hir::map::*; use rustc::hir::intravisit::FnKind; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::TypeVariants; use rustc::session::config::Config as SessionConfig; use rustc_target::spec::abi::Abi; @@ -28,6 +31,12 @@ use crate::utils::{in_macro, is_copy, is_self, span_lint_and_sugg, snippet}; /// The configuration option `trivial_copy_size_limit` can be set to override /// this limit for a project. /// +/// This lint attempts to allow passing arguments by reference if a reference +/// to that argument is returned. This is implemented by comparing the lifetime +/// of the argument and return value for equality. However, this can cause +/// false positives in cases involving multiple lifetimes that are bounded by +/// each other. +/// /// **Example:** /// ```rust /// fn foo(v: &u32) { @@ -100,8 +109,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; } @@ -112,6 +121,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { let fn_sig = cx.tcx.fn_sig(fn_def_id); let fn_sig = cx.tcx.erase_late_bound_regions(&fn_sig); + // Use lifetimes to determine if we're returning a reference to the + // argument. In that case we can't switch to pass-by-value as the + // argument will not live long enough. + let output_lt = if let TypeVariants::TyRef(output_lt, _, _) = fn_sig.output().sty { + Some(output_lt) + } else { + None + }; + for ((input, &ty), arg) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments) { // All spans generated from a proc-macro invocation are the same... if span == input.span { @@ -119,11 +137,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { } if_chain! { - if let TypeVariants::TyRef(_, ty, Mutability::MutImmutable) = ty.sty; + if let TypeVariants::TyRef(input_lt, ty, Mutability::MutImmutable) = ty.sty; + if Some(input_lt) != output_lt; 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() diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 61d496c1f0d..d016afb4908 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -3,6 +3,8 @@ use rustc::hir; use rustc::hir::*; use rustc::hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty, TyCtxt, TypeckTables}; use rustc::ty::layout::LayoutOf; use rustc_typeck::hir_ty_to_ty; @@ -12,7 +14,7 @@ use std::borrow::Cow; use syntax::ast::{FloatTy, IntTy, UintTy}; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; -use crate::utils::{comparisons, differing_macro_contexts, higher, in_constant, in_external_macro, in_macro, last_path_segment, match_def_path, match_path, +use crate::utils::{comparisons, differing_macro_contexts, higher, in_constant, in_macro, last_path_segment, match_def_path, match_path, match_type, multispan_sugg, opt_def_id, same_tys, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, clip, unsext, sext, int_bits}; use crate::utils::paths; @@ -136,10 +138,10 @@ impl LintPass for TypePass { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass { - fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Body, _: Span, id: NodeId) { + fn check_fn(&mut self, cx: &LateContext<'_, '_>, _: FnKind<'_>, decl: &FnDecl, _: &Body, _: Span, id: NodeId) { // skip trait implementations, see #605 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; } } @@ -147,11 +149,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass { check_fn_decl(cx, decl); } - fn check_struct_field(&mut self, cx: &LateContext, field: &StructField) { + fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &StructField) { check_ty(cx, &field.ty, false); } - fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) { + fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, item: &TraitItem) { match item.node { TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => check_ty(cx, ty, false), TraitItemKind::Method(ref sig, _) => check_fn_decl(cx, &sig.decl), @@ -159,14 +161,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass { } } - fn check_local(&mut self, cx: &LateContext, local: &Local) { + fn check_local(&mut self, cx: &LateContext<'_, '_>, local: &Local) { if let Some(ref ty) = local.ty { check_ty(cx, ty, true); } } } -fn check_fn_decl(cx: &LateContext, decl: &FnDecl) { +fn check_fn_decl(cx: &LateContext<'_, '_>, decl: &FnDecl) { for input in &decl.inputs { check_ty(cx, input, false); } @@ -177,7 +179,7 @@ fn check_fn_decl(cx: &LateContext, decl: &FnDecl) { } /// Check if `qpath` has last segment with type parameter matching `path` -fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool { +fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath, path: &[&str]) -> bool { let last = last_path_segment(qpath); if_chain! { if let Some(ref params) = last.args; @@ -186,7 +188,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 { @@ -201,12 +203,12 @@ fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool /// /// The parameter `is_local` distinguishes the context of the type; types from /// local bindings should only be checked for the `BORROWED_BOX` lint. -fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { +fn check_ty(cx: &LateContext<'_, '_>, ast_ty: &hir::Ty, is_local: bool) { if in_macro(ast_ty.span) { 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,19 +284,19 @@ 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); }, _ => {}, } } -fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifetime, mut_ty: &MutTy) { +fn check_ty_rptr(cx: &LateContext<'_, '_>, ast_ty: &hir::Ty, is_local: bool, lt: &Lifetime, mut_ty: &MutTy) { match mut_ty.ty.node { - 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 +345,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. @@ -376,10 +378,10 @@ declare_clippy_lint! { "creating a let binding to a value of unit type, which usually can't be used afterwards" } -fn check_let_unit(cx: &LateContext, decl: &Decl) { - if let DeclLocal(ref local) = decl.node { +fn check_let_unit(cx: &LateContext<'_, '_>, decl: &Decl) { + 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) { + if in_external_macro(cx.sess(), decl.span) || in_macro(local.pat.span) { return; } if higher::is_from_for_desugar(decl) { @@ -446,11 +448,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 +503,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,14 +541,14 @@ 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 } } -fn is_unit(ty: Ty) -> bool { +fn is_unit(ty: Ty<'_>) -> bool { match ty.sty { ty::TyTuple(slice) if slice.is_empty() => true, _ => false, @@ -555,7 +557,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, } } @@ -751,7 +753,7 @@ declare_clippy_lint! { /// Returns the size in bits of an integral type. /// Will return 0 if the type is not an int or uint variant -fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 { +fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_, '_, '_>) -> u64 { match typ.sty { ty::TyInt(i) => match i { IntTy::Isize => tcx.data_layout.pointer_size.bits(), @@ -773,14 +775,14 @@ fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 { } } -fn is_isize_or_usize(typ: Ty) -> bool { +fn is_isize_or_usize(typ: Ty<'_>) -> bool { match typ.sty { ty::TyInt(IntTy::Isize) | ty::TyUint(UintTy::Usize) => true, _ => false, } } -fn span_precision_loss_lint(cx: &LateContext, expr: &Expr, cast_from: Ty, cast_to_f64: bool) { +fn span_precision_loss_lint(cx: &LateContext<'_, '_>, expr: &Expr, cast_from: Ty<'_>, cast_to_f64: bool) { let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; let arch_dependent_str = "on targets with 64-bit wide pointers "; @@ -812,7 +814,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; } @@ -820,7 +822,7 @@ fn should_strip_parens(op: &Expr, snip: &str) -> bool { false } -fn span_lossless_lint(cx: &LateContext, expr: &Expr, op: &Expr, cast_from: Ty, cast_to: Ty) { +fn span_lossless_lint(cx: &LateContext<'_, '_>, expr: &Expr, op: &Expr, cast_from: Ty<'_>, cast_to: Ty<'_>) { // Do not suggest using From in consts/statics until it is valid to do so (see #2267). if in_constant(cx, expr.id) { return } // The suggestion is to use a function call, so if the original expression @@ -852,7 +854,7 @@ enum ArchSuffix { None, } -fn check_truncation_and_wrapping(cx: &LateContext, expr: &Expr, cast_from: Ty, cast_to: Ty) { +fn check_truncation_and_wrapping(cx: &LateContext<'_, '_>, expr: &Expr, cast_from: Ty<'_>, cast_to: Ty<'_>) { let arch_64_suffix = " on targets with 64-bit wide pointers"; let arch_32_suffix = " on targets with 32-bit wide pointers"; let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); @@ -923,7 +925,7 @@ fn check_truncation_and_wrapping(cx: &LateContext, expr: &Expr, cast_from: Ty, c } } -fn check_lossless(cx: &LateContext, expr: &Expr, op: &Expr, cast_from: Ty, cast_to: Ty) { +fn check_lossless(cx: &LateContext<'_, '_>, expr: &Expr, op: &Expr, cast_from: Ty<'_>, cast_to: Ty<'_>) { let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); @@ -951,13 +953,13 @@ 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(_) => {}, - _ => if cast_from.sty == cast_to.sty && !in_external_macro(cx, expr.span) { + _ => if cast_from.sty == cast_to.sty && !in_external_macro(cx.sess(), expr.span) { span_lint( cx, UNNECESSARY_CAST, @@ -967,7 +969,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass { }, } } - if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) { + if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { match (cast_from.is_integral(), cast_to.is_integral()) { (true, false) => { let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); @@ -1141,7 +1143,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 _ => (), } @@ -1181,7 +1183,7 @@ impl<'a, 'tcx> TypeComplexityPass { } } - fn check_type(&self, cx: &LateContext, ty: &hir::Ty) { + fn check_type(&self, cx: &LateContext<'_, '_>, ty: &hir::Ty) { if in_macro(ty.span) { return; } @@ -1214,15 +1216,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 +1291,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 +1364,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 +1376,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 +1455,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 \ @@ -1560,11 +1562,11 @@ impl Ord for FullInt { } -fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(FullInt, FullInt)> { +fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<(FullInt, FullInt)> { 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 @@ -1626,8 +1628,8 @@ 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 { +fn err_upcast_comparison(cx: &LateContext<'_, '_>, span: Span, expr: &Expr, always: bool) { + if let ExprKind::Cast(ref cast_val, _) = expr.node { span_lint( cx, INVALID_UPCAST_COMPARISONS, @@ -1693,7 +1695,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 @@ -1748,11 +1750,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher { fn suggestion<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, - db: &mut DiagnosticBuilder, + db: &mut DiagnosticBuilder<'_>, generics_span: Span, generics_suggestion_span: Span, - target: &ImplicitHasherType, - vis: ImplicitHasherConstructorVisitor, + target: &ImplicitHasherType<'_>, + vis: ImplicitHasherConstructorVisitor<'_, '_, '_>, ) { let generics_snip = snippet(cx, generics_span, ""); // trim `<` `>` @@ -1797,7 +1799,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 +1831,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 +1880,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 +1986,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; diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index 0cb192e89b2..0549e774fb5 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir::*; use syntax::ast::{LitKind, NodeId}; use syntax::codemap::Span; @@ -71,7 +72,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) } @@ -93,7 +94,7 @@ fn escape<T: Iterator<Item = char>>(s: T) -> String { result } -fn check_str(cx: &LateContext, span: Span, id: NodeId) { +fn check_str(cx: &LateContext<'_, '_>, span: Span, id: NodeId) { let string = snippet(cx, span, ""); if string.contains('\u{200B}') { span_help_and_lint( diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs index a1f31770ec0..2f8b3ab836d 100644 --- a/clippy_lints/src/unsafe_removed_from_name.rs +++ b/clippy_lints/src/unsafe_removed_from_name.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use syntax::ast::*; use syntax::codemap::Span; use syntax::symbol::LocalInternedString; @@ -34,14 +35,14 @@ impl LintPass for UnsafeNameRemoval { } impl EarlyLintPass for UnsafeNameRemoval { - fn check_item(&mut self, cx: &EarlyContext, item: &Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { if let ItemKind::Use(ref use_tree) = item.node { check_use_tree(use_tree, cx, item.span); } } } -fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext, span: Span) { +fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) { match use_tree.kind { UseTreeKind::Simple(Some(new_name), ..) => { let old_name = use_tree @@ -62,7 +63,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext, span: Span) { } } -fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext, span: Span) { +fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, span: Span) { let old_str = old_name.name.as_str(); let new_str = new_name.name.as_str(); if contains_unsafe(&old_str) && !contains_unsafe(&new_str) { diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index 316415d73ad..a9a7e102ab2 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir; use crate::utils::{is_try, match_qpath, match_trait_method, paths, span_lint}; @@ -38,16 +39,16 @@ impl LintPass for UnusedIoAmount { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { - fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { + fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) { let expr = match s.node { - 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 +58,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); }, @@ -69,8 +70,8 @@ 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 { +fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr, expr: &hir::Expr) { + 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( diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index 5c5550ed30f..1681a303fd3 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -1,4 +1,5 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir; use rustc::hir::intravisit::{walk_expr, walk_fn, FnKind, NestedVisitorMap, Visitor}; use std::collections::HashMap; @@ -69,10 +70,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); }, _ => (), diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index b8e34cc66e1..6cafcaeffe9 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -1,4 +1,6 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use crate::utils::{in_macro, match_type, paths, span_lint_and_then, usage::is_potentially_mutated}; use rustc::hir::intravisit::*; @@ -78,21 +80,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 +133,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 +142,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() diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 10b69852ba5..2ea4497a0d1 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -1,4 +1,6 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; use rustc::hir::intravisit::{walk_path, NestedVisitorMap, Visitor}; use crate::utils::{in_macro, span_lint_and_then}; @@ -55,8 +57,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { return; } if_chain! { - if let ItemImpl(.., ref item_type, ref 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 { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 520c30b03c0..4310325475a 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -4,8 +4,9 @@ #![allow(print_stdout, use_debug)] use rustc::lint::*; +use rustc::{declare_lint, lint_array}; 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 +33,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 +193,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 +211,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 +223,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 +236,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 +278,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 +314,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 +324,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 +332,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 +356,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 +381,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 +400,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 +409,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 +433,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 +446,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 +473,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 +589,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 +613,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 +675,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; diff --git a/clippy_lints/src/utils/comparisons.rs b/clippy_lints/src/utils/comparisons.rs index 5cb9b50a79d..35f41d400ad 100644 --- a/clippy_lints/src/utils/comparisons.rs +++ b/clippy_lints/src/utils/comparisons.rs @@ -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, } } diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 05abdd2f13c..a27013344d8 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -2,6 +2,7 @@ #![deny(missing_docs_in_private_items)] +use lazy_static::lazy_static; use std::{env, fmt, fs, io, path}; use std::io::Read; use syntax::{ast, codemap}; @@ -51,7 +52,7 @@ pub enum Error { } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { Error::Io(ref err) => err.fmt(f), Error::Toml(ref err) => err.fmt(f), @@ -86,10 +87,10 @@ macro_rules! define_Conf { // #[allow(rust_2018_idioms)] mod helpers { + use serde_derive::Deserialize; /// Type used to store lint configuration. #[derive(Deserialize)] - #[serde(rename_all="kebab-case")] - #[serde(deny_unknown_fields)] + #[serde(rename_all="kebab-case", deny_unknown_fields)] pub struct Conf { $(#[$doc] #[serde(default=$rust_name_str)] #[serde(with=$rust_name_str)] pub $rust_name: define_Conf!(TY $($ty)+),)+ diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 69f1792012a..3931f6c55f9 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -3,32 +3,33 @@ #![deny(missing_docs_in_private_items)] +use if_chain::if_chain; use rustc::{hir, ty}; use rustc::lint::LateContext; 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 +88,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 +99,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 +112,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 +155,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 +172,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 +186,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)); } @@ -211,10 +212,10 @@ pub enum VecArgs<'a> { /// Returns the arguments of the `vec!` macro if this expression was expanded /// from `vec!`. -pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e>> { +pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr) -> Option<VecArgs<'e>> { if_chain! { - if 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 +226,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)); } diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index f95fb046b49..2c5995f1327 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -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); }, diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index b23464c80de..b6c241a6825 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -3,6 +3,7 @@ //! checks for attributes use rustc::lint::*; +use rustc::{declare_lint, lint_array}; use rustc::hir; use rustc::hir::print; use syntax::ast::Attribute; @@ -51,14 +52,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { return; } println!("impl item `{}`", item.ident.name); - match item.vis { - hir::Visibility::Public => println!("public"), - hir::Visibility::Crate(_) => println!("visible crate wide"), - hir::Visibility::Restricted { ref path, .. } => println!( + match item.vis.node { + hir::VisibilityKind::Public => println!("public"), + hir::VisibilityKind::Crate(_) => println!("visible crate wide"), + hir::VisibilityKind::Restricted { ref path, .. } => println!( "visible in module `{}`", print::to_string(print::NO_ANN, |s| s.print_path(path, false)) ), - hir::Visibility::Inherited => println!("visibility inherited from outer item"), + hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), } if item.defaultness.is_default() { println!("default"); @@ -70,6 +71,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { }, hir::ImplItemKind::Method(..) => println!("method"), hir::ImplItemKind::Type(_) => println!("associated type"), + hir::ImplItemKind::Existential(_) => println!("existential type"), } } // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx @@ -122,8 +124,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 @@ -139,9 +141,9 @@ fn has_attr(attrs: &[Attribute]) -> bool { get_attr(attrs, "dump").count() > 0 } -fn print_decl(cx: &LateContext, decl: &hir::Decl) { +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,27 +152,27 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) { print_expr(cx, e, 0); } }, - hir::DeclItem(_) => println!("item decl"), + hir::DeclKind::Item(_) => println!("item decl"), } } -fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { +fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); 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 +181,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 +202,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 +230,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 +270,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 +320,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 +332,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); @@ -340,20 +342,20 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { } } -fn print_item(cx: &LateContext, item: &hir::Item) { +fn print_item(cx: &LateContext<'_, '_>, item: &hir::Item) { let did = cx.tcx.hir.local_def_id(item.id); println!("item `{}`", item.name); - match item.vis { - hir::Visibility::Public => println!("public"), - hir::Visibility::Crate(_) => println!("visible crate wide"), - hir::Visibility::Restricted { ref path, .. } => println!( + match item.vis.node { + hir::VisibilityKind::Public => println!("public"), + hir::VisibilityKind::Crate(_) => println!("visible crate wide"), + hir::VisibilityKind::Restricted { ref path, .. } => println!( "visible in module `{}`", print::to_string(print::NO_ANN, |s| s.print_path(path, false)) ), - hir::Visibility::Inherited => println!("visibility inherited from outer 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 +369,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,19 +402,19 @@ 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"); }, } } -fn print_pat(cx: &LateContext, pat: &hir::Pat, indent: usize) { +fn print_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); match pat.node { diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index b1b65698eb9..32aee099177 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -1,5 +1,7 @@ use rustc::lint::*; +use rustc::{declare_lint, lint_array}; 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; @@ -62,7 +64,7 @@ impl LintPass for Clippy { } impl EarlyLintPass for Clippy { - fn check_crate(&mut self, cx: &EarlyContext, krate: &AstCrate) { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &AstCrate) { if let Some(utils) = krate .module .items @@ -117,15 +119,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 == Visibility::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 +164,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 +172,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 +181,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 diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 6765d9afb66..0b2103ca7ea 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1,4 +1,6 @@ use crate::reexport::*; +use matches::matches; +use if_chain::if_chain; use rustc::hir; use rustc::hir::*; use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; @@ -17,7 +19,7 @@ use std::str::FromStr; use std::rc::Rc; use syntax::ast::{self, LitKind}; use syntax::attr; -use syntax::codemap::{CompilerDesugaringKind, ExpnFormat, ExpnInfo, Span, DUMMY_SP}; +use syntax::codemap::{CompilerDesugaringKind, ExpnFormat, Span, DUMMY_SP}; use syntax::errors::DiagnosticBuilder; use syntax::ptr::P; use syntax::symbol::keywords; @@ -46,7 +48,7 @@ pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { rhs.ctxt() != lhs.ctxt() } -pub fn in_constant(cx: &LateContext, id: NodeId) -> bool { +pub fn in_constant(cx: &LateContext<'_, '_>, id: NodeId) -> bool { let parent_id = cx.tcx.hir.get_parent(id); match cx.tcx.hir.body_owner_kind(parent_id) { hir::BodyOwnerKind::Fn => false, @@ -75,36 +77,6 @@ pub fn is_range_expression(span: Span) -> bool { }) } -/// Returns true if the macro that expanded the crate was outside of the -/// current crate or was a -/// compiler plugin. -pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { - /// Invokes `in_macro` with the expansion info of the given span slightly - /// heavy, try to use - /// this after other checks have already happened. - fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, info: &ExpnInfo) -> bool { - // no ExpnInfo = no macro - if let ExpnFormat::MacroAttribute(..) = info.format { - // these are all plugins - return true; - } - // no span for the callee = external macro - info.def_site.map_or(true, |span| { - // no snippet = external macro or compiler-builtin expansion - cx.sess() - .codemap() - .span_to_snippet(span) - .ok() - .map_or(true, |code| !code.starts_with("macro_rules")) - }) - } - - span.ctxt() - .outer() - .expn_info() - .map_or(false, |info| in_macro_ext(cx, &info)) -} - /// Check if a `DefId`'s path matches the given absolute type path usage. /// /// # Examples @@ -113,7 +85,7 @@ pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { /// ``` /// /// See also the `paths` module. -pub fn match_def_path(tcx: TyCtxt, def_id: DefId, path: &[&str]) -> bool { +pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool { use syntax::symbol; struct AbsolutePathBuffer { @@ -143,7 +115,7 @@ pub fn match_def_path(tcx: TyCtxt, def_id: DefId, path: &[&str]) -> bool { } /// Check if type is struct, enum or union type with given def path. -pub fn match_type(cx: &LateContext, ty: Ty, path: &[&str]) -> bool { +pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool { match ty.sty { ty::TyAdt(adt, _) => match_def_path(cx.tcx, adt.did, path), _ => false, @@ -151,7 +123,7 @@ pub fn match_type(cx: &LateContext, ty: Ty, path: &[&str]) -> bool { } /// Check if the method call given in `expr` belongs to given type. -pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { +pub fn match_impl_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool { let method_call = cx.tables.type_dependent_defs()[expr.hir_id]; let trt_id = cx.tcx.impl_of_method(method_call.def_id()); if let Some(trt_id) = trt_id { @@ -162,7 +134,7 @@ pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { } /// Check if the method call given in `expr` belongs to given trait. -pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { +pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool { let method_call = cx.tables.type_dependent_defs()[expr.hir_id]; let trt_id = cx.tcx.trait_of_item(method_call.def_id()); if let Some(trt_id) = trt_id { @@ -174,7 +146,7 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool /// Check if an expression references a variable of the given name. pub fn match_var(expr: &Expr, var: Name) -> bool { - if let ExprPath(QPath::Resolved(None, ref path)) = expr.node { + if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.node { if path.segments.len() == 1 && path.segments[0].ident.name == var { return true; } @@ -210,7 +182,7 @@ pub fn match_qpath(path: &QPath, segments: &[&str]) -> bool { match *path { QPath::Resolved(_, ref path) => match_path(path, segments), QPath::TypeRelative(ref ty, ref segment) => match ty.node { - TyPath(ref inner_path) => { + TyKind::Path(ref inner_path) => { !segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)]) && segment.ident.name == segments[segments.len() - 1] }, @@ -242,7 +214,7 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool { } /// Get the definition associated to a path. -pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<def::Def> { +pub fn path_to_def(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<def::Def> { let crates = cx.tcx.crates(); let krate = crates .iter() @@ -278,7 +250,7 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<def::Def> { } /// Convenience function to get the `DefId` of a trait by path. -pub fn get_trait_def_id(cx: &LateContext, path: &[&str]) -> Option<DefId> { +pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<DefId> { let def = match path_to_def(cx, path) { Some(def) => def, None => return None, @@ -306,7 +278,7 @@ pub fn implements_trait<'a, 'tcx>( } /// Check whether this type implements Drop. -pub fn has_drop(cx: &LateContext, expr: &Expr) -> bool { +pub fn has_drop(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { let struct_ty = cx.tables.expr_ty(expr); match struct_ty.ty_adt_def() { Some(def) => def.has_dtor(cx.tcx), @@ -315,7 +287,7 @@ pub fn has_drop(cx: &LateContext, expr: &Expr) -> bool { } /// Resolve the definition of a node from its `HirId`. -pub fn resolve_node(cx: &LateContext, qpath: &QPath, id: HirId) -> def::Def { +pub fn resolve_node(cx: &LateContext<'_, '_>, qpath: &QPath, id: HirId) -> def::Def { cx.tables.qpath_def(qpath, id) } @@ -330,7 +302,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a let mut matched = Vec::with_capacity(methods.len()); for method_name in methods.iter().rev() { // method chains are stored last -> first - if let ExprMethodCall(ref path, _, ref args) = current.node { + if let ExprKind::MethodCall(ref path, _, ref args) = current.node { if path.ident.name == *method_name { if args.iter().any(|e| in_macro(e.span)) { return None; @@ -350,7 +322,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a /// Get the name of the item the expression is in, if available. -pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> { +pub fn get_item_name(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Name> { let parent_id = cx.tcx.hir.get_parent(expr.id); match cx.tcx.hir.find(parent_id) { Some(Node::NodeItem(&Item { ref name, .. })) => Some(*name), @@ -435,7 +407,7 @@ pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span { Span::new(*line_start, span.hi(), span.ctxt()) } -/// Like `snippet_block`, but add braces if the expr is not an `ExprBlock`. +/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. /// Also takes an `Option<String>` which can be put inside the braces. pub fn expr_block<'a, 'b, T: LintContext<'b>>( cx: &T, @@ -445,7 +417,7 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>( ) -> Cow<'a, str> { let code = snippet_block(cx, expr.span, default); let string = option.unwrap_or_default(); - if let ExprBlock(_, _) = expr.node { + if let ExprKind::Block(_, _) = expr.node { Cow::Owned(format!("{}{}", code, string)) } else if string.is_empty() { Cow::Owned(format!("{{ {} }}", code)) @@ -456,13 +428,13 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>( /// Trim indentation from a multiline string with possibility of ignoring the /// first line. -pub fn trim_multiline(s: Cow<str>, ignore_first: bool) -> Cow<str> { +pub fn trim_multiline(s: Cow<'_, str>, ignore_first: bool) -> Cow<'_, str> { let s_space = trim_multiline_inner(s, ignore_first, ' '); let s_tab = trim_multiline_inner(s_space, ignore_first, '\t'); trim_multiline_inner(s_tab, ignore_first, ' ') } -fn trim_multiline_inner(s: Cow<str>, ignore_first: bool, ch: char) -> Cow<str> { +fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, ch: char) -> Cow<'_, str> { let x = s.lines() .skip(ignore_first as usize) .filter_map(|l| { @@ -500,7 +472,7 @@ fn trim_multiline_inner(s: Cow<str>, ignore_first: bool, ch: char) -> Cow<str> { } /// Get a parent expressions if any – this is useful to constrain a lint. -pub fn get_parent_expr<'c>(cx: &'c LateContext, e: &Expr) -> Option<&'c Expr> { +pub fn get_parent_expr<'c>(cx: &'c LateContext<'_, '_>, e: &Expr) -> Option<&'c Expr> { let map = &cx.tcx.hir; let node_id: NodeId = e.id; let parent_id: NodeId = map.get_parent_node(node_id); @@ -524,13 +496,13 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI match node { Node::NodeBlock(block) => Some(block), Node::NodeItem(&Item { - node: ItemFn(_, _, _, eid), + node: ItemKind::Fn(_, _, _, eid), .. }) | Node::NodeImplItem(&ImplItem { node: ImplItemKind::Method(_, eid), .. }) => match cx.tcx.hir.body(eid).value.node { - ExprBlock(ref block, _) => Some(block), + ExprKind::Block(ref block, _) => Some(block), _ => None, }, _ => None, @@ -640,7 +612,7 @@ pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>( /// appear once per /// replacement. In human-readable format though, it only appears once before /// the whole suggestion. -pub fn multispan_sugg<I>(db: &mut DiagnosticBuilder, help_msg: String, sugg: I) +pub fn multispan_sugg<I>(db: &mut DiagnosticBuilder<'_>, help_msg: String, sugg: I) where I: IntoIterator<Item = (Span, String)>, { @@ -667,13 +639,13 @@ where /// Return the base type for HIR references and pointers. pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty { match ty.node { - TyPtr(ref mut_ty) | TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty), + TyKind::Ptr(ref mut_ty) | TyKind::Rptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty), _ => ty, } } /// Return the base type for references and raw pointers. -pub fn walk_ptrs_ty(ty: Ty) -> Ty { +pub fn walk_ptrs_ty(ty: Ty<'_>) -> Ty<'_> { match ty.sty { ty::TyRef(_, ty, _) => walk_ptrs_ty(ty), _ => ty, @@ -682,8 +654,8 @@ pub fn walk_ptrs_ty(ty: Ty) -> Ty { /// Return the base type for references and raw pointers, and count reference /// depth. -pub fn walk_ptrs_ty_depth(ty: Ty) -> (Ty, usize) { - fn inner(ty: Ty, depth: usize) -> (Ty, usize) { +pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) { + fn inner(ty: Ty<'_>, depth: usize) -> (Ty<'_>, usize) { match ty.sty { ty::TyRef(_, ty, _) => inner(ty, depth + 1), _ => (ty, depth), @@ -695,7 +667,7 @@ pub fn walk_ptrs_ty_depth(ty: Ty) -> (Ty, usize) { /// Check whether the given expression is a constant literal of the given value. pub fn is_integer_literal(expr: &Expr, value: u128) -> bool { // FIXME: use constant folding - if let ExprLit(ref spanned) = expr.node { + if let ExprKind::Lit(ref spanned) = expr.node { if let LitKind::Int(v, _) = spanned.node { return v == value; } @@ -703,7 +675,7 @@ pub fn is_integer_literal(expr: &Expr, value: u128) -> bool { false } -pub fn is_adjusted(cx: &LateContext, e: &Expr) -> bool { +pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr) -> bool { cx.tables.adjustments().get(e.hir_id).is_some() } @@ -896,15 +868,15 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { } /// Return whether a pattern is refutable. -pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { - fn is_enum_variant(cx: &LateContext, qpath: &QPath, id: HirId) -> bool { +pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat) -> bool { + fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath, id: HirId) -> bool { matches!( cx.tables.qpath_def(qpath, id), def::Def::Variant(..) | def::Def::VariantCtor(..) ) } - fn are_refutable<'a, I: Iterator<Item = &'a Pat>>(cx: &LateContext, mut i: I) -> bool { + fn are_refutable<'a, I: Iterator<Item = &'a Pat>>(cx: &LateContext<'_, '_>, mut i: I) -> bool { i.any(|pat| is_refutable(cx, pat)) } @@ -945,7 +917,7 @@ pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool { /// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return /// themselves. pub fn remove_blocks(expr: &Expr) -> &Expr { - if let ExprBlock(ref block, _) = expr.node { + if let ExprKind::Block(ref block, _) = expr.node { if block.stmts.is_empty() { if let Some(ref expr) = block.expr { remove_blocks(expr) @@ -982,6 +954,7 @@ pub fn opt_def_id(def: Def) -> Option<DefId> { Def::AssociatedConst(id) | Def::Macro(id, ..) | Def::Existential(id) | + Def::AssociatedExistential(id) | Def::GlobalAsm(id) => Some(id), Def::Upvar(..) | Def::Local(_) | Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None, @@ -998,7 +971,7 @@ pub fn is_self(slf: &Arg) -> bool { pub fn is_self_ty(slf: &hir::Ty) -> bool { if_chain! { - if let TyPath(ref qp) = slf.node; + if let TyKind::Path(ref qp) = slf.node; if let QPath::Resolved(None, ref path) = *qp; if let Def::SelfTy(..) = path.def; then { @@ -1020,7 +993,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pats[0].node; if match_qpath(path, &paths::RESULT_OK[1..]); if let PatKind::Binding(_, defid, _, None) = pat[0].node; - if let ExprPath(QPath::Resolved(None, ref path)) = arm.body.node; + if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.node; if let Def::Local(lid) = path.def; if lid == defid; then { @@ -1038,7 +1011,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } } - if let ExprMatch(_, ref arms, ref source) = expr.node { + if let ExprKind::Match(_, ref arms, ref source) = expr.node { // desugared from a `?` operator if let MatchSource::TryDesugar = *source { return Some(expr); @@ -1062,7 +1035,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { /// Returns true if the lint is allowed in the current context /// /// Useful for skipping long running code when it's unnecessary -pub fn is_allowed(cx: &LateContext, lint: &'static Lint, id: NodeId) -> bool { +pub fn is_allowed(cx: &LateContext<'_, '_>, lint: &'static Lint, id: NodeId) -> bool { cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow } @@ -1082,24 +1055,24 @@ pub fn get_arg_ident(pat: &Pat) -> Option<ast::Ident> { } } -pub fn int_bits(tcx: TyCtxt, ity: ast::IntTy) -> u64 { +pub fn int_bits(tcx: TyCtxt<'_, '_, '_>, ity: ast::IntTy) -> u64 { layout::Integer::from_attr(tcx, attr::IntType::SignedInt(ity)).size().bits() } /// Turn a constant int byte representation into an i128 -pub fn sext(tcx: TyCtxt, u: u128, ity: ast::IntTy) -> i128 { +pub fn sext(tcx: TyCtxt<'_, '_, '_>, u: u128, ity: ast::IntTy) -> i128 { let amt = 128 - int_bits(tcx, ity); ((u as i128) << amt) >> amt } /// clip unused bytes -pub fn unsext(tcx: TyCtxt, u: i128, ity: ast::IntTy) -> u128 { +pub fn unsext(tcx: TyCtxt<'_, '_, '_>, u: i128, ity: ast::IntTy) -> u128 { let amt = 128 - int_bits(tcx, ity); ((u as u128) << amt) >> amt } /// clip unused bytes -pub fn clip(tcx: TyCtxt, u: u128, ity: ast::UintTy) -> u128 { +pub fn clip(tcx: TyCtxt<'_, '_, '_>, u: u128, ity: ast::UintTy) -> u128 { let bits = layout::Integer::from_attr(tcx, attr::IntType::UnsignedInt(ity)).size().bits(); let amt = 128 - bits; (u << amt) >> amt @@ -1138,7 +1111,7 @@ pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> { without } -pub fn any_parent_is_automatically_derived(tcx: TyCtxt, node: NodeId) -> bool { +pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_, '_, '_>, node: NodeId) -> bool { let map = &tcx.hir; let mut prev_enclosing_node = None; let mut enclosing_node = node; diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 7606f4f8471..4d89f8ddffb 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -2,18 +2,18 @@ //! about. pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"]; -pub const ARC: [&str; 3] = ["alloc", "arc", "Arc"]; +pub const ARC: [&str; 3] = ["alloc", "sync", "Arc"]; pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"]; pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; -pub const BINARY_HEAP: [&str; 3] = ["alloc", "binary_heap", "BinaryHeap"]; +pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"]; pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; pub const BOX: [&str; 3] = ["std", "boxed", "Box"]; pub const BOX_NEW: [&str; 4] = ["std", "boxed", "Box", "new"]; -pub const BTREEMAP: [&str; 4] = ["alloc", "btree", "map", "BTreeMap"]; -pub const BTREEMAP_ENTRY: [&str; 4] = ["alloc", "btree", "map", "Entry"]; -pub const BTREESET: [&str; 4] = ["alloc", "btree", "set", "BTreeSet"]; +pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"]; +pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"]; +pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"]; pub const CLONE: [&str; 4] = ["core", "clone", "Clone", "clone"]; pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"]; pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"]; @@ -47,7 +47,7 @@ pub const IO_PRINT: [&str; 4] = ["std", "io", "stdio", "_print"]; pub const IO_READ: [&str; 3] = ["std", "io", "Read"]; pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"]; pub const ITERATOR: [&str; 4] = ["core", "iter", "iterator", "Iterator"]; -pub const LINKED_LIST: [&str; 3] = ["alloc", "linked_list", "LinkedList"]; +pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"]; pub const LINT: [&str; 2] = ["lint", "Lint"]; pub const LINT_ARRAY: [&str; 2] = ["lint", "LintArray"]; pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"]; @@ -101,7 +101,7 @@ pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"]; pub const TRY_INTO_RESULT: [&str; 4] = ["std", "ops", "Try", "into_result"]; pub const UNINIT: [&str; 4] = ["core", "intrinsics", "", "uninit"]; pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"]; -pub const VEC_DEQUE: [&str; 3] = ["alloc", "vec_deque", "VecDeque"]; +pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"]; pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"]; -pub const WEAK_ARC: [&str; 3] = ["alloc", "arc", "Weak"]; +pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"]; pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; diff --git a/clippy_lints/src/utils/ptr.rs b/clippy_lints/src/utils/ptr.rs index 09ec90ac63f..1a20eb01015 100644 --- a/clippy_lints/src/utils/ptr.rs +++ b/clippy_lints/src/utils/ptr.rs @@ -7,7 +7,7 @@ use syntax::codemap::Span; use crate::utils::{get_pat_name, match_var, snippet}; pub fn get_spans( - cx: &LateContext, + cx: &LateContext<'_, '_>, opt_body_id: Option<BodyId>, idx: usize, replacements: &'static [(&'static str, &'static str)], @@ -54,7 +54,7 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> { if self.abort { return; } - if let ExprMethodCall(ref seg, _, ref args) = expr.node { + if let ExprKind::MethodCall(ref seg, _, ref args) = expr.node { if args.len() == 1 && match_var(&args[0], self.name) { if seg.ident.name == "capacity" { self.abort = true; diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index eb2197a5891..91fd5ec874a 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -3,6 +3,7 @@ // currently ignores lifetimes and generics #![allow(use_self)] +use matches::matches; use rustc::hir; use rustc::lint::{EarlyContext, LateContext, LintContext}; use rustc_errors; @@ -31,8 +32,8 @@ pub enum Sugg<'a> { /// Literal constant `1`, for convenience. pub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("1")); -impl<'a> Display for Sugg<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { +impl Display for Sugg<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match *self { Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) | Sugg::BinOp(_, ref s) => s.fmt(f), } @@ -42,51 +43,51 @@ impl<'a> Display for Sugg<'a> { #[allow(wrong_self_convention)] // ok, because of the function `as_ty` method impl<'a> Sugg<'a> { /// Prepare a suggestion from an expression. - pub fn hir_opt(cx: &LateContext, expr: &hir::Expr) -> Option<Self> { + pub fn hir_opt(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<Self> { snippet_opt(cx, expr.span).map(|snippet| { let snippet = Cow::Owned(snippet); match expr.node { - hir::ExprAddrOf(..) | - hir::ExprBox(..) | - hir::ExprClosure(.., _) | - hir::ExprIf(..) | - hir::ExprUnary(..) | - hir::ExprMatch(..) => Sugg::MaybeParen(snippet), - hir::ExprContinue(..) | - hir::ExprYield(..) | - hir::ExprArray(..) | - hir::ExprBlock(..) | - hir::ExprBreak(..) | - hir::ExprCall(..) | - hir::ExprField(..) | - hir::ExprIndex(..) | - hir::ExprInlineAsm(..) | - hir::ExprLit(..) | - hir::ExprLoop(..) | - hir::ExprMethodCall(..) | - hir::ExprPath(..) | - hir::ExprRepeat(..) | - hir::ExprRet(..) | - hir::ExprStruct(..) | - hir::ExprTup(..) | - hir::ExprWhile(..) => Sugg::NonParen(snippet), - hir::ExprAssign(..) => Sugg::BinOp(AssocOp::Assign, snippet), - hir::ExprAssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet), - hir::ExprBinary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet), - hir::ExprCast(..) => Sugg::BinOp(AssocOp::As, snippet), - hir::ExprType(..) => Sugg::BinOp(AssocOp::Colon, snippet), + hir::ExprKind::AddrOf(..) | + hir::ExprKind::Box(..) | + hir::ExprKind::Closure(.., _) | + hir::ExprKind::If(..) | + hir::ExprKind::Unary(..) | + hir::ExprKind::Match(..) => Sugg::MaybeParen(snippet), + hir::ExprKind::Continue(..) | + hir::ExprKind::Yield(..) | + hir::ExprKind::Array(..) | + hir::ExprKind::Block(..) | + hir::ExprKind::Break(..) | + hir::ExprKind::Call(..) | + hir::ExprKind::Field(..) | + hir::ExprKind::Index(..) | + hir::ExprKind::InlineAsm(..) | + hir::ExprKind::Lit(..) | + hir::ExprKind::Loop(..) | + hir::ExprKind::MethodCall(..) | + hir::ExprKind::Path(..) | + hir::ExprKind::Repeat(..) | + hir::ExprKind::Ret(..) | + hir::ExprKind::Struct(..) | + hir::ExprKind::Tup(..) | + hir::ExprKind::While(..) => Sugg::NonParen(snippet), + hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet), + hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet), + hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet), + hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet), + hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet), } }) } /// Convenience function around `hir_opt` for suggestions with a default /// text. - pub fn hir(cx: &LateContext, expr: &hir::Expr, default: &'a str) -> Self { + pub fn hir(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str) -> Self { Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default))) } /// Prepare a suggestion from an expression. - pub fn ast(cx: &EarlyContext, expr: &ast::Expr, default: &'a str) -> Self { + pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self { use syntax::ast::RangeLimits; let snippet = snippet(cx, expr.span, default); @@ -240,7 +241,7 @@ impl<T> ParenHelper<T> { } impl<T: Display> Display for ParenHelper<T> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { if self.paren { write!(f, "({})", self.wrapped) } else { @@ -254,7 +255,7 @@ impl<T: Display> Display for ParenHelper<T> { /// For convenience, the operator is taken as a string because all unary /// operators have the same /// precedence. -pub fn make_unop(op: &str, expr: Sugg) -> Sugg<'static> { +pub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> { Sugg::MaybeParen(format!("{}{}", op, expr.maybe_par()).into()) } @@ -263,7 +264,7 @@ pub fn make_unop(op: &str, expr: Sugg) -> Sugg<'static> { /// Precedence of shift operator relative to other arithmetic operation is /// often confusing so /// parenthesis will always be added for a mix of these. -pub fn make_assoc(op: AssocOp, lhs: &Sugg, rhs: &Sugg) -> Sugg<'static> { +pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> { /// Whether the operator is a shift operator `<<` or `>>`. fn is_shift(op: &AssocOp) -> bool { matches!(*op, AssocOp::ShiftLeft | AssocOp::ShiftRight) @@ -334,7 +335,7 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg, rhs: &Sugg) -> Sugg<'static> { } /// Convinience wrapper arround `make_assoc` and `AssocOp::from_ast_binop`. -pub fn make_binop(op: ast::BinOpKind, lhs: &Sugg, rhs: &Sugg) -> Sugg<'static> { +pub fn make_binop(op: ast::BinOpKind, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> { make_assoc(AssocOp::from_ast_binop(op), lhs, rhs) } @@ -382,21 +383,29 @@ fn associativity(op: &AssocOp) -> Associativity { /// Convert a `hir::BinOp` to the corresponding assigning binary operator. fn hirbinop2assignop(op: hir::BinOp) -> AssocOp { - use rustc::hir::BinOp_::*; use syntax::parse::token::BinOpToken::*; AssocOp::AssignOp(match op.node { - BiAdd => Plus, - BiBitAnd => And, - BiBitOr => Or, - BiBitXor => Caret, - BiDiv => Slash, - BiMul => Star, - BiRem => Percent, - BiShl => Shl, - BiShr => Shr, - BiSub => Minus, - BiAnd | BiEq | BiGe | BiGt | BiLe | BiLt | BiNe | BiOr => panic!("This operator does not exist"), + hir::BinOpKind::Add => Plus, + hir::BinOpKind::BitAnd => And, + hir::BinOpKind::BitOr => Or, + hir::BinOpKind::BitXor => Caret, + hir::BinOpKind::Div => Slash, + hir::BinOpKind::Mul => Star, + hir::BinOpKind::Rem => Percent, + hir::BinOpKind::Shl => Shl, + hir::BinOpKind::Shr => Shr, + hir::BinOpKind::Sub => Minus, + + | hir::BinOpKind::And + | hir::BinOpKind::Eq + | hir::BinOpKind::Ge + | hir::BinOpKind::Gt + | hir::BinOpKind::Le + | hir::BinOpKind::Lt + | hir::BinOpKind::Ne + | hir::BinOpKind::Or + => panic!("This operator does not exist"), }) } diff --git a/clippy_lints/src/utils/usage.rs b/clippy_lints/src/utils/usage.rs index 6d75dfb486d..43e492bfb4e 100644 --- a/clippy_lints/src/utils/usage.rs +++ b/clippy_lints/src/utils/usage.rs @@ -44,7 +44,7 @@ struct MutVarsDelegate { } impl<'tcx> MutVarsDelegate { - fn update(&mut self, cat: &'tcx Categorization) { + fn update(&mut self, cat: &'tcx Categorization<'_>) { match *cat { Categorization::Local(id) => { self.used_mutably.insert(id); @@ -68,7 +68,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate { fn consume_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: ConsumeMode) {} - fn borrow(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, _: ty::Region, bk: ty::BorrowKind, _: LoanCause) { + fn borrow(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, _: ty::Region<'_>, bk: ty::BorrowKind, _: LoanCause) { if let ty::BorrowKind::MutBorrow = bk { self.update(&cmt.cat) } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 0d8997f4f36..cea3307a827 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -1,5 +1,7 @@ use rustc::hir::*; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::ty::{self, Ty}; use syntax::codemap::Span; use crate::utils::{higher, is_copy, snippet, span_lint_and_sugg}; @@ -37,7 +39,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if_chain! { if let ty::TyRef(_, ty, _) = cx.tables.expr_ty_adjusted(expr).sty; if let ty::TySlice(..) = ty.sty; - if let ExprAddrOf(_, ref addressee) = expr.node; + if let ExprKind::AddrOf(_, ref addressee) = expr.node; if let Some(vec_args) = higher::vec_macro(cx, addressee); then { check_vec_macro(cx, &vec_args, expr.span); @@ -92,7 +94,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA } /// Return the item type of the vector (ie. the `T` in `Vec<T>`). -fn vec_type(ty: Ty) -> Ty { +fn vec_type(ty: Ty<'_>) -> Ty<'_> { if let ty::TyAdt(_, substs) = ty.sty { substs.type_at(0) } else { diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 86c95dbcc56..a019e23a301 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -1,13 +1,9 @@ -use rustc::hir::map::Node::{NodeImplItem, NodeItem}; -use rustc::hir::*; use rustc::lint::*; -use std::ops::Deref; -use syntax::ast::LitKind; -use syntax::ptr; -use syntax::symbol::LocalInternedString; -use syntax_pos::Span; -use crate::utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint, span_lint_and_sugg}; -use crate::utils::{opt_def_id, paths, last_path_segment}; +use rustc::{declare_lint, lint_array}; +use syntax::ast::*; +use syntax::tokenstream::{ThinTokenStream, TokenStream}; +use syntax::parse::{token, parser}; +use crate::utils::{span_lint, span_lint_and_sugg}; /// **What it does:** This lint warns when you use `println!("")` to /// print a newline. @@ -171,317 +167,149 @@ impl LintPass for Pass { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - match expr.node { - // print!() - ExprCall(ref fun, ref args) => { - if_chain! { - if let ExprPath(ref qpath) = fun.node; - if let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)); - then { - check_print_variants(cx, expr, fun_id, args); - } +impl EarlyLintPass for Pass { + fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &Mac) { + if mac.node.path == "println" { + span_lint(cx, PRINT_STDOUT, mac.span, "use of `println!`"); + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false) { + if fmtstr == "" { + span_lint_and_sugg( + cx, + PRINTLN_EMPTY_STRING, + mac.span, + "using `println!(\"\")`", + "replace it with", + "println!()".to_string(), + ); } - }, - // write!() - ExprMethodCall(ref fun, _, ref args) => { - if fun.ident.name == "write_fmt" { - check_write_variants(cx, expr, args); + } + } else if mac.node.path == "print" { + span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`"); + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false) { + if fmtstr.ends_with("\\n") { + span_lint(cx, PRINT_WITH_NEWLINE, mac.span, + "using `print!()` with a format string that ends in a \ + newline, consider using `println!()` instead"); } - }, - _ => (), + } + } else if mac.node.path == "write" { + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true) { + if fmtstr.ends_with("\\n") { + span_lint(cx, WRITE_WITH_NEWLINE, mac.span, + "using `write!()` with a format string that ends in a \ + newline, consider using `writeln!()` instead"); + } + } + } else if mac.node.path == "writeln" { + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true) { + if fmtstr == "" { + span_lint_and_sugg( + cx, + WRITELN_EMPTY_STRING, + mac.span, + "using `writeln!(v, \"\")`", + "replace it with", + "writeln!(v)".to_string(), + ); + } + } } } } -fn check_write_variants<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, write_args: &ptr::P<[Expr]>) { - // `writeln!` uses `write!`. - if let Some(span) = is_expn_of(expr.span, "write") { - let (span, name) = match is_expn_of(span, "writeln") { - Some(span) => (span, "writeln"), - None => (span, "write"), +fn check_tts(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> Option<String> { + let tts = TokenStream::from(tts.clone()); + let mut parser = parser::Parser::new( + &cx.sess.parse_sess, + tts, + None, + false, + false, + ); + if is_write { + // skip the initial write target + parser.parse_expr().map_err(|mut err| err.cancel()).ok()?; + // might be `writeln!(foo)` + parser.expect(&token::Comma).map_err(|mut err| err.cancel()).ok()?; + } + let fmtstr = parser.parse_str().map_err(|mut err| err.cancel()).ok()?.0.to_string(); + use fmt_macros::*; + let tmp = fmtstr.clone(); + let mut args = vec![]; + let mut fmt_parser = Parser::new(&tmp, None); + while let Some(piece) = fmt_parser.next() { + if !fmt_parser.errors.is_empty() { + return None; + } + if let Piece::NextArgument(arg) = piece { + if arg.format.ty == "?" { + // FIXME: modify rustc's fmt string parser to give us the current span + span_lint(cx, USE_DEBUG, parser.prev_span, "use of `Debug`-based formatting"); + } + args.push(arg); + } + } + let lint = if is_write { + WRITE_LITERAL + } else { + PRINT_LITERAL + }; + let mut idx = 0; + loop { + if !parser.eat(&token::Comma) { + assert!(parser.eat(&token::Eof)); + return Some(fmtstr); + } + let expr = parser.parse_expr().map_err(|mut err| err.cancel()).ok()?; + const SIMPLE: FormatSpec<'_> = FormatSpec { + fill: None, + align: AlignUnknown, + flags: 0, + precision: CountImplied, + width: CountImplied, + ty: "", }; - - if_chain! { - // ensure we're calling Arguments::new_v1 or Arguments::new_v1_formatted - if write_args.len() == 2; - if let ExprCall(ref args_fun, ref args_args) = write_args[1].node; - if let ExprPath(ref qpath) = args_fun.node; - if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); - if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1) || - match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED); - then { - // Check for literals in the write!/writeln! args - check_fmt_args_for_literal(cx, args_args, |span| { - span_lint(cx, WRITE_LITERAL, span, "writing a literal with an empty format string"); - }); - - if_chain! { - if args_args.len() >= 2; - if let ExprAddrOf(_, ref match_expr) = args_args[1].node; - if let ExprMatch(ref args, _, _) = match_expr.node; - if let ExprTup(ref args) = args.node; - if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); - then { - match name { - "write" => if has_newline_end(args, fmtstr, fmtlen) { - span_lint(cx, WRITE_WITH_NEWLINE, span, - "using `write!()` with a format string that ends in a \ - newline, consider using `writeln!()` instead"); + match &expr.node { + ExprKind::Lit(_) => { + let mut all_simple = true; + let mut seen = false; + for arg in &args { + match arg.position { + | ArgumentImplicitlyIs(n) + | ArgumentIs(n) + => if n == idx { + all_simple &= arg.format == SIMPLE; + seen = true; + }, + ArgumentNamed(_) => {}, + } + } + if all_simple && seen { + span_lint(cx, lint, expr.span, "literal with an empty format string"); + } + idx += 1; + }, + ExprKind::Assign(lhs, rhs) => { + if let ExprKind::Path(_, p) = &lhs.node { + let mut all_simple = true; + let mut seen = false; + for arg in &args { + match arg.position { + | ArgumentImplicitlyIs(_) + | ArgumentIs(_) + => {}, + ArgumentNamed(name) => if *p == name { + seen = true; + all_simple &= arg.format == SIMPLE; }, - "writeln" => if let Some(final_span) = has_empty_arg(cx, span, fmtstr, fmtlen) { - span_lint_and_sugg( - cx, - WRITE_WITH_NEWLINE, - final_span, - "using `writeln!(v, \"\")`", - "replace it with", - "writeln!(v)".to_string(), - ); - }, - _ => (), } } - } - } - } - } -} - -fn check_print_variants<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'tcx Expr, - fun_id: def_id::DefId, - args: &ptr::P<[Expr]>, -) { - // Search for `std::io::_print(..)` which is unique in a - // `print!` expansion. - if match_def_path(cx.tcx, fun_id, &paths::IO_PRINT) { - if let Some(span) = is_expn_of(expr.span, "print") { - // `println!` uses `print!`. - let (span, name) = match is_expn_of(span, "println") { - Some(span) => (span, "println"), - None => (span, "print"), - }; - - span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name)); - if_chain! { - // ensure we're calling Arguments::new_v1 - if args.len() == 1; - if let ExprCall(ref args_fun, ref args_args) = args[0].node; - then { - // Check for literals in the print!/println! args - check_fmt_args_for_literal(cx, args_args, |span| { - span_lint(cx, PRINT_LITERAL, span, "printing a literal with an empty format string"); - }); - - if_chain! { - if let ExprPath(ref qpath) = args_fun.node; - if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); - if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1); - if args_args.len() == 2; - if let ExprAddrOf(_, ref match_expr) = args_args[1].node; - if let ExprMatch(ref args, _, _) = match_expr.node; - if let ExprTup(ref args) = args.node; - if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); - then { - match name { - "print" => - if has_newline_end(args, fmtstr, fmtlen) { - span_lint(cx, PRINT_WITH_NEWLINE, span, - "using `print!()` with a format string that ends in a \ - newline, consider using `println!()` instead"); - }, - "println" => - if let Some(final_span) = has_empty_arg(cx, span, fmtstr, fmtlen) { - span_lint_and_sugg( - cx, - PRINT_WITH_NEWLINE, - final_span, - "using `println!(\"\")`", - "replace it with", - "println!()".to_string(), - ); - }, - _ => (), - } - } + if all_simple && seen { + span_lint(cx, lint, rhs.span, "literal with an empty format string"); } } - } - } - } - // Search for something like - // `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)` - else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) { - if let ExprPath(ref qpath) = args[1].node { - if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, args[1].hir_id)) { - if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) - && is_expn_of(expr.span, "panic").is_none() - { - span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); - } - } + }, + _ => idx += 1, } } } - -// Check for literals in write!/writeln! and print!/println! args -// ensuring the format string for the literal is `DISPLAY_FMT_METHOD` -// e.g., `writeln!(buf, "... {} ...", "foo")` -// ^ literal in `writeln!` -// e.g., `println!("... {} ...", "foo")` -// ^ literal in `println!` -fn check_fmt_args_for_literal<'a, 'tcx, F>(cx: &LateContext<'a, 'tcx>, args: &HirVec<Expr>, lint_fn: F) -where - F: Fn(Span), -{ - if_chain! { - if args.len() >= 2; - - // the match statement - if let ExprAddrOf(_, ref match_expr) = args[1].node; - if let ExprMatch(ref matchee, ref arms, _) = match_expr.node; - if let ExprTup(ref tup) = matchee.node; - if arms.len() == 1; - if let ExprArray(ref arm_body_exprs) = arms[0].body.node; - then { - // it doesn't matter how many args there are in the `write!`/`writeln!`, - // if there's one literal, we should warn the user - for (idx, tup_arg) in tup.iter().enumerate() { - if_chain! { - // first, make sure we're dealing with a literal (i.e., an ExprLit) - if let ExprAddrOf(_, ref tup_val) = tup_arg.node; - if let ExprLit(_) = tup_val.node; - - // next, check the corresponding match arm body to ensure - // this is DISPLAY_FMT_METHOD - if let ExprCall(_, ref body_args) = arm_body_exprs[idx].node; - if body_args.len() == 2; - if let ExprPath(ref body_qpath) = body_args[1].node; - if let Some(fun_def_id) = opt_def_id(resolve_node(cx, body_qpath, body_args[1].hir_id)); - if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD); - then { - if args.len() == 2 { - lint_fn(tup_val.span); - } - - // ensure the format str has no options (e.g., width, precision, alignment, etc.) - // and is just "{}" - if_chain! { - if args.len() == 3; - if let ExprAddrOf(_, ref format_expr) = args[2].node; - if let ExprArray(ref format_exprs) = format_expr.node; - if format_exprs.len() >= 1; - if let ExprStruct(_, ref fields, _) = format_exprs[idx].node; - if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format"); - if check_unformatted(&format_field.expr); - then { - lint_fn(tup_val.span); - } - } - } - } - } - } - } -} - -/// Check for fmtstr = "... \n" -fn has_newline_end(args: &HirVec<Expr>, fmtstr: LocalInternedString, fmtlen: usize) -> bool { - if_chain! { - // check the final format string part - if let Some('\n') = fmtstr.chars().last(); - - // "foo{}bar" is made into two strings + one argument, - // if the format string starts with `{}` (eg. "{}foo"), - // the string array is prepended an empty string "". - // We only want to check the last string after any `{}`: - if args.len() < fmtlen; - then { - return true - } - } - false -} - -/// Check for writeln!(v, "") / println!("") -fn has_empty_arg<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, fmtstr: LocalInternedString, fmtlen: usize) -> Option<Span> { - if_chain! { - // check that the string is empty - if fmtlen == 1; - if fmtstr.deref() == "\n"; - - // check the presence of that string - if let Ok(snippet) = cx.sess().codemap().span_to_snippet(span); - if snippet.contains("\"\""); - then { - if snippet.ends_with(';') { - return Some(cx.sess().codemap().span_until_char(span, ';')); - } - return Some(span) - } - } - None -} - -/// Returns the slice of format string parts in an `Arguments::new_v1` call. -fn get_argument_fmtstr_parts(expr: &Expr) -> Option<(LocalInternedString, usize)> { - if_chain! { - if let ExprAddrOf(_, ref expr) = expr.node; // &["…", "…", …] - if let ExprArray(ref exprs) = expr.node; - if let Some(expr) = exprs.last(); - if let ExprLit(ref lit) = expr.node; - if let LitKind::Str(ref lit, _) = lit.node; - then { - return Some((lit.as_str(), exprs.len())); - } - } - None -} - -fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool { - let map = &cx.tcx.hir; - - // `fmt` method - if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) { - // `Debug` impl - if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) { - if let ItemImpl(_, _, _, _, Some(ref tr), _, _) = item.node { - return match_path(&tr.path, &["Debug"]); - } - } - } - false -} - -/// Checks if the expression matches -/// ```rust,ignore -/// &[_ { -/// format: _ { -/// width: _::Implied, -/// ... -/// }, -/// ..., -/// }] -/// ``` -pub fn check_unformatted(format_field: &Expr) -> bool { - if_chain! { - if let ExprStruct(_, ref fields, _) = format_field.node; - if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width"); - if let ExprPath(ref qpath) = width_field.expr.node; - if last_path_segment(qpath).ident.name == "Implied"; - if let Some(align_field) = fields.iter().find(|f| f.ident.name == "align"); - if let ExprPath(ref qpath) = align_field.expr.node; - if last_path_segment(qpath).ident.name == "Unknown"; - if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision"); - if let ExprPath(ref qpath_precision) = precision_field.expr.node; - if last_path_segment(qpath_precision).ident.name == "Implied"; - then { - return true; - } - } - - false -} diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index aaba0184845..7c8af7880ba 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -1,5 +1,7 @@ use crate::consts::{constant_simple, Constant}; use rustc::lint::*; +use rustc::{declare_lint, lint_array}; +use if_chain::if_chain; use rustc::hir::*; use crate::utils::span_help_and_lint; @@ -32,8 +34,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { // check for instances of 0.0/0.0 if_chain! { - if let ExprBinary(ref op, ref left, ref right) = expr.node; - if let BinOp_::BiDiv = op.node; + if let ExprKind::Binary(ref op, ref left, ref right) = expr.node; + if let BinOpKind::Div = op.node; // TODO - constant_simple does not fold many operations involving floats. // That's probably fine for this lint - it's pretty unlikely that someone would // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too. diff --git a/mini-macro/src/lib.rs b/mini-macro/src/lib.rs index 9f88de62677..3417e603c12 100644 --- a/mini-macro/src/lib.rs +++ b/mini-macro/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(proc_macro, proc_macro_non_items)] +#![feature(use_extern_macros, proc_macro_quote, proc_macro_non_items)] extern crate proc_macro; use proc_macro::{TokenStream, quote}; diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 00000000000..bf867e0ae5b --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly diff --git a/src/driver.rs b/src/driver.rs index 585edcd82a6..e9e81bb88e3 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -118,6 +118,7 @@ pub fn main() { for (name, to) in lint_groups { ls.register_group(Some(sess), true, name, to); } + clippy_lints::register_pre_expansion_lints(sess, &mut ls); sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes); sess.plugin_attributes.borrow_mut().extend(attributes); diff --git a/src/lib.rs b/src/lib.rs index 6ff15e2cd89..1123c968006 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ use rustc_plugin::Registry; #[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { +pub fn plugin_registrar(reg: &mut Registry<'_>) { reg.sess.lint_store.with_read_lock(|lint_store| { for (lint, _, _) in lint_store.get_lint_groups() { reg.sess diff --git a/tests/ui/author.stdout b/tests/ui/author.stdout index a55b48985ad..b06fb1d21e3 100644 --- a/tests/ui/author.stdout +++ b/tests/ui/author.stdout @@ -1,11 +1,11 @@ if_chain! { - if let Stmt_::StmtDecl(ref decl, _) = stmt.node - if let Decl_::DeclLocal(ref local) = decl.node; + if let StmtKind::Decl(ref decl, _) = stmt.node + if let DeclKind::Local(ref local) = decl.node; if let Some(ref init) = local.init - if let Expr_::ExprCast(ref expr, ref cast_ty) = init.node; - if let Ty_::TyPath(ref qp) = cast_ty.node; + if let ExprKind::Cast(ref expr, ref cast_ty) = init.node; + if let TyKind::Path(ref qp) = cast_ty.node; if match_qpath(qp, &["char"]); - if let Expr_::ExprLit(ref lit) = expr.node; + if let ExprKind::Lit(ref lit) = expr.node; if let LitKind::Int(69, _) = lit.node; if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node; if name.node.as_str() == "x"; diff --git a/tests/ui/author/call.stdout b/tests/ui/author/call.stdout index 3e06bf9ace8..1c25708fb48 100644 --- a/tests/ui/author/call.stdout +++ b/tests/ui/author/call.stdout @@ -1,14 +1,14 @@ if_chain! { - if let Stmt_::StmtDecl(ref decl, _) = stmt.node - if let Decl_::DeclLocal(ref local) = decl.node; + if let StmtKind::Decl(ref decl, _) = stmt.node + if let DeclKind::Local(ref local) = decl.node; if let Some(ref init) = local.init - if let Expr_::ExprCall(ref func, ref args) = init.node; - if let Expr_::ExprPath(ref path) = func.node; + if let ExprKind::Call(ref func, ref args) = init.node; + if let ExprKind::Path(ref path) = func.node; if match_qpath(path, &["{{root}}", "std", "cmp", "min"]); if args.len() == 2; - if let Expr_::ExprLit(ref lit) = args[0].node; + if let ExprKind::Lit(ref lit) = args[0].node; if let LitKind::Int(3, _) = lit.node; - if let Expr_::ExprLit(ref lit1) = args[1].node; + if let ExprKind::Lit(ref lit1) = args[1].node; if let LitKind::Int(4, _) = lit1.node; if let PatKind::Wild = local.pat.node; then { diff --git a/tests/ui/author/for_loop.stdout b/tests/ui/author/for_loop.stdout index 69bc6d7a025..b99e8e0ade5 100644 --- a/tests/ui/author/for_loop.stdout +++ b/tests/ui/author/for_loop.stdout @@ -1,60 +1,60 @@ if_chain! { - if let Expr_::ExprBlock(ref block) = expr.node; - if let Stmt_::StmtDecl(ref decl, _) = block.node - if let Decl_::DeclLocal(ref local) = decl.node; + if let ExprKind::Block(ref block) = expr.node; + if let StmtKind::Decl(ref decl, _) = block.node + if let DeclKind::Local(ref local) = decl.node; if let Some(ref init) = local.init - if let Expr_::ExprMatch(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node; - if let Expr_::ExprCall(ref func, ref args) = expr.node; - if let Expr_::ExprPath(ref path) = func.node; + if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node; + if let ExprKind::Call(ref func, ref args) = expr.node; + if let ExprKind::Path(ref path) = func.node; if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]); if args.len() == 1; - if let Expr_::ExprStruct(ref path1, ref fields, None) = args[0].node; + if let ExprKind::Struct(ref path1, ref fields, None) = args[0].node; if match_qpath(path1, &["{{root}}", "std", "ops", "Range"]); if fields.len() == 2; // unimplemented: field checks if arms.len() == 1; - if let Expr_::ExprLoop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node; - if let Stmt_::StmtDecl(ref decl1, _) = body.node - if let Decl_::DeclLocal(ref local1) = decl1.node; + if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node; + if let StmtKind::Decl(ref decl1, _) = body.node + if let DeclKind::Local(ref local1) = decl1.node; if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local1.pat.node; if name.node.as_str() == "__next"; - if let Stmt_::StmtExpr(ref e, _) = local1.pat.node - if let Expr_::ExprMatch(ref expr1, ref arms1, MatchSource::ForLoopDesugar) = e.node; - if let Expr_::ExprCall(ref func1, ref args1) = expr1.node; - if let Expr_::ExprPath(ref path2) = func1.node; + if let StmtKind::Expr(ref e, _) = local1.pat.node + if let ExprKind::Match(ref expr1, ref arms1, MatchSource::ForLoopDesugar) = e.node; + if let ExprKind::Call(ref func1, ref args1) = expr1.node; + if let ExprKind::Path(ref path2) = func1.node; if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]); if args1.len() == 1; - if let Expr_::ExprAddrOf(MutMutable, ref inner) = args1[0].node; - if let Expr_::ExprPath(ref path3) = inner.node; + if let ExprKind::AddrOf(MutMutable, ref inner) = args1[0].node; + if let ExprKind::Path(ref path3) = inner.node; if match_qpath(path3, &["iter"]); if arms1.len() == 2; - if let Expr_::ExprAssign(ref target, ref value) = arms1[0].body.node; - if let Expr_::ExprPath(ref path4) = target.node; + if let ExprKind::Assign(ref target, ref value) = arms1[0].body.node; + if let ExprKind::Path(ref path4) = target.node; if match_qpath(path4, &["__next"]); - if let Expr_::ExprPath(ref path5) = value.node; + if let ExprKind::Path(ref path5) = value.node; if match_qpath(path5, &["val"]); if arms1[0].pats.len() == 1; if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pats[0].node; if match_qpath(path6, &["{{root}}", "std", "option", "Option", "Some"]); if fields1.len() == 1; // unimplemented: field checks - if let Expr_::ExprBreak(ref destination, None) = arms1[1].body.node; + if let ExprKind::Break(ref destination, None) = arms1[1].body.node; if arms1[1].pats.len() == 1; if let PatKind::Path(ref path7) = arms1[1].pats[0].node; if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]); - if let Stmt_::StmtDecl(ref decl2, _) = path7.node - if let Decl_::DeclLocal(ref local2) = decl2.node; + if let StmtKind::Decl(ref decl2, _) = path7.node + if let DeclKind::Local(ref local2) = decl2.node; if let Some(ref init1) = local2.init - if let Expr_::ExprPath(ref path8) = init1.node; + if let ExprKind::Path(ref path8) = init1.node; if match_qpath(path8, &["__next"]); if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local2.pat.node; if name1.node.as_str() == "y"; - if let Stmt_::StmtExpr(ref e1, _) = local2.pat.node - if let Expr_::ExprBlock(ref block1) = e1.node; - if let Stmt_::StmtDecl(ref decl3, _) = block1.node - if let Decl_::DeclLocal(ref local3) = decl3.node; + if let StmtKind::Expr(ref e1, _) = local2.pat.node + if let ExprKind::Block(ref block1) = e1.node; + if let StmtKind::Decl(ref decl3, _) = block1.node + if let DeclKind::Local(ref local3) = decl3.node; if let Some(ref init2) = local3.init - if let Expr_::ExprPath(ref path9) = init2.node; + if let ExprKind::Path(ref path9) = init2.node; if match_qpath(path9, &["y"]); if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local3.pat.node; if name2.node.as_str() == "z"; @@ -63,7 +63,7 @@ if_chain! { if name3.node.as_str() == "iter"; if let PatKind::Binding(BindingAnnotation::Unannotated, _, name4, None) = local.pat.node; if name4.node.as_str() == "_result"; - if let Expr_::ExprPath(ref path10) = local.pat.node; + if let ExprKind::Path(ref path10) = local.pat.node; if match_qpath(path10, &["_result"]); then { // report your lint here diff --git a/tests/ui/author/matches.stout b/tests/ui/author/matches.stout index db7de5a2ca5..94b25aefabe 100644 --- a/tests/ui/author/matches.stout +++ b/tests/ui/author/matches.stout @@ -1,32 +1,32 @@ if_chain! { - if let Stmt_::StmtDecl(ref decl, _) = stmt.node - if let Decl_::DeclLocal(ref local) = decl.node; + if let StmtKind::Decl(ref decl, _) = stmt.node + if let DeclKind::Local(ref local) = decl.node; if let Some(ref init) = local.init - if let Expr_::ExprMatch(ref expr, ref arms, MatchSource::Normal) = init.node; - if let Expr_::ExprLit(ref lit) = expr.node; + if let ExprKind::Match(ref expr, ref arms, MatchSource::Normal) = init.node; + if let ExprKind::Lit(ref lit) = expr.node; if let LitKind::Int(42, _) = lit.node; if arms.len() == 3; - if let Expr_::ExprLit(ref lit1) = arms[0].body.node; + if let ExprKind::Lit(ref lit1) = arms[0].body.node; if let LitKind::Int(5, _) = lit1.node; if arms[0].pats.len() == 1; if let PatKind::Lit(ref lit_expr) = arms[0].pats[0].node - if let Expr_::ExprLit(ref lit2) = lit_expr.node; + if let ExprKind::Lit(ref lit2) = lit_expr.node; if let LitKind::Int(16, _) = lit2.node; - if let Expr_::ExprBlock(ref block) = arms[1].body.node; - if let Stmt_::StmtDecl(ref decl1, _) = block.node - if let Decl_::DeclLocal(ref local1) = decl1.node; + if let ExprKind::Block(ref block) = arms[1].body.node; + if let StmtKind::Decl(ref decl1, _) = block.node + if let DeclKind::Local(ref local1) = decl1.node; if let Some(ref init1) = local1.init - if let Expr_::ExprLit(ref lit3) = init1.node; + if let ExprKind::Lit(ref lit3) = init1.node; if let LitKind::Int(3, _) = lit3.node; if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.node; if name.node.as_str() == "x"; - if let Expr_::ExprPath(ref path) = local1.pat.node; + if let ExprKind::Path(ref path) = local1.pat.node; if match_qpath(path, &["x"]); if arms[1].pats.len() == 1; if let PatKind::Lit(ref lit_expr1) = arms[1].pats[0].node - if let Expr_::ExprLit(ref lit4) = lit_expr1.node; + if let ExprKind::Lit(ref lit4) = lit_expr1.node; if let LitKind::Int(17, _) = lit4.node; - if let Expr_::ExprLit(ref lit5) = arms[2].body.node; + if let ExprKind::Lit(ref lit5) = arms[2].body.node; if let LitKind::Int(1, _) = lit5.node; if arms[2].pats.len() == 1; if let PatKind::Wild = arms[2].pats[0].node; diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index aa62ccbd0e5..6bbc0aebf9c 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -1,4 +1,4 @@ -error: lint str_to_string has been removed: using `str::to_string` is common even today and specialization will likely happen soon +error: lint `str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:4:8 | 4 | #[warn(str_to_string)] @@ -6,25 +6,25 @@ error: lint str_to_string has been removed: using `str::to_string` is common eve | = note: `-D renamed-and-removed-lints` implied by `-D warnings` -error: lint string_to_string has been removed: using `string::to_string` is common even today and specialization will likely happen soon +error: lint `string_to_string` has been removed: `using `string::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:6:8 | 6 | #[warn(string_to_string)] | ^^^^^^^^^^^^^^^^ -error: lint unstable_as_slice has been removed: `Vec::as_slice` has been stabilized in 1.7 +error: lint `unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7` --> $DIR/deprecated.rs:8:8 | 8 | #[warn(unstable_as_slice)] | ^^^^^^^^^^^^^^^^^ -error: lint unstable_as_mut_slice has been removed: `Vec::as_mut_slice` has been stabilized in 1.7 +error: lint `unstable_as_mut_slice` has been removed: ``Vec::as_mut_slice` has been stabilized in 1.7` --> $DIR/deprecated.rs:10:8 | 10 | #[warn(unstable_as_mut_slice)] | ^^^^^^^^^^^^^^^^^^^^^ -error: lint misaligned_transmute has been removed: this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr +error: lint `misaligned_transmute` has been removed: `this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr` --> $DIR/deprecated.rs:12:8 | 12 | #[warn(misaligned_transmute)] diff --git a/tests/ui/dlist.rs b/tests/ui/dlist.rs index a4fab5735e2..1318ed78717 100644 --- a/tests/ui/dlist.rs +++ b/tests/ui/dlist.rs @@ -6,7 +6,7 @@ #![allow(dead_code, needless_pass_by_value)] extern crate alloc; -use alloc::linked_list::LinkedList; +use alloc::collections::linked_list::LinkedList; trait Foo { type Baz = LinkedList<u8>; diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index c17639aaf04..88f24d27dbc 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -22,7 +22,7 @@ fn main() { const BAD64_3: f64 = 0.100_000_000_000_000_000_1; // Literal as param - println!("{}", 8.888_888_888_888_888_888_888); + println!("{:?}", 8.888_888_888_888_888_888_888); // // TODO add inferred type tests for f32 // Locals diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index a167deac038..295846e9d7e 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -43,10 +43,10 @@ error: float has excessive precision | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` error: float has excessive precision - --> $DIR/excessive_precision.rs:25:20 + --> $DIR/excessive_precision.rs:25:22 | -25 | println!("{}", 8.888_888_888_888_888_888_888); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` +25 | println!("{:?}", 8.888_888_888_888_888_888_888); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` error: float has excessive precision --> $DIR/excessive_precision.rs:36:22 diff --git a/tests/ui/matches.stderr b/tests/ui/matches.stderr index e0afc939b42..6554b6d3449 100644 --- a/tests/ui/matches.stderr +++ b/tests/ui/matches.stderr @@ -26,6 +26,23 @@ help: instead of prefixing all patterns with `&`, you can dereference the expres 32 | None => println!("none"), | +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:40:5 + | +40 | / match tup { +41 | | &(v, 1) => println!("{}", v), +42 | | _ => println!("none"), +43 | | } + | |_____^ +help: try this + | +40 | if let &(v, 1) = tup { +41 | # [ cfg ( not ( stage0 ) ) ] { +42 | ( $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ) ; } # [ +43 | cfg ( stage0 ) ] { print ! ( "{}/n" , format_args ! ( $ ( $ arg ) * ) ) } } else { +44 | ( $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ) ; } + | + error: you don't need to add `&` to all patterns --> $DIR/matches.rs:40:5 | @@ -350,5 +367,5 @@ error: use as_mut() instead 221 | | }; | |_____^ help: try this: `mut_owned.as_mut()` -error: aborting due to 25 previous errors +error: aborting due to 26 previous errors diff --git a/tests/ui/missing_inline.rs b/tests/ui/missing_inline.rs new file mode 100644 index 00000000000..38f59033071 --- /dev/null +++ b/tests/ui/missing_inline.rs @@ -0,0 +1,72 @@ +/* This file incorporates work covered by the following copyright and + * permission notice: + * Copyright 2013 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or + * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license + * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ +#![warn(missing_inline_in_public_items)] +#![crate_type = "dylib"] +// When denying at the crate level, be sure to not get random warnings from the +// injected intrinsics by the compiler. +#![allow(dead_code, non_snake_case)] + +type Typedef = String; +pub type PubTypedef = String; + +struct Foo {} // ok +pub struct PubFoo { } // ok +enum FooE {} // ok +pub enum PubFooE {} // ok + +mod module {} // ok +pub mod pub_module {} // ok + +fn foo() {} +pub fn pub_foo() {} // missing #[inline] +#[inline] pub fn pub_foo_inline() {} // ok +#[inline(always)] pub fn pub_foo_inline_always() {} // ok + +#[allow(missing_inline_in_public_items)] +pub fn pub_foo_no_inline() {} + +trait Bar { + fn Bar_a(); // ok + fn Bar_b() {} // ok +} + + +pub trait PubBar { + fn PubBar_a(); // ok + fn PubBar_b() {} // missing #[inline] + #[inline] fn PubBar_c() {} // ok +} + +// none of these need inline because Foo is not exported +impl PubBar for Foo { + fn PubBar_a() {} // ok + fn PubBar_b() {} // ok + fn PubBar_c() {} // ok +} + +// all of these need inline because PubFoo is exported +impl PubBar for PubFoo { + fn PubBar_a() {} // missing #[inline] + fn PubBar_b() {} // missing #[inline] + fn PubBar_c() {} // missing #[inline] +} + +// do not need inline because Foo is not exported +impl Foo { + fn FooImpl() {} // ok +} + +// need inline because PubFoo is exported +impl PubFoo { + pub fn PubFooImpl() {} // missing #[inline] +} diff --git a/tests/ui/missing_inline.stderr b/tests/ui/missing_inline.stderr new file mode 100644 index 00000000000..fe343742708 --- /dev/null +++ b/tests/ui/missing_inline.stderr @@ -0,0 +1,40 @@ +error: missing `#[inline]` for a function + --> $DIR/missing_inline.rs:31:1 + | +31 | pub fn pub_foo() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `-D missing-inline-in-public-items` implied by `-D warnings` + +error: missing `#[inline]` for a default trait method + --> $DIR/missing_inline.rs:46:5 + | +46 | fn PubBar_b() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^ + +error: missing `#[inline]` for a method + --> $DIR/missing_inline.rs:59:5 + | +59 | fn PubBar_a() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^ + +error: missing `#[inline]` for a method + --> $DIR/missing_inline.rs:60:5 + | +60 | fn PubBar_b() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^ + +error: missing `#[inline]` for a method + --> $DIR/missing_inline.rs:61:5 + | +61 | fn PubBar_c() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^ + +error: missing `#[inline]` for a method + --> $DIR/missing_inline.rs:71:5 + | +71 | pub fn PubFooImpl() {} // missing #[inline] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr index 4b95a1a9e70..c63b493db8d 100644 --- a/tests/ui/non_expressive_names.stderr +++ b/tests/ui/non_expressive_names.stderr @@ -1,3 +1,23 @@ +error: using `println!("")` + --> $DIR/non_expressive_names.rs:60:14 + | +60 | _ => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + | + = note: `-D println-empty-string` implied by `-D warnings` + +error: using `println!("")` + --> $DIR/non_expressive_names.rs:128:18 + | +128 | 1 => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + +error: using `println!("")` + --> $DIR/non_expressive_names.rs:132:18 + | +132 | 1 => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + error: binding's name is too similar to existing binding --> $DIR/non_expressive_names.rs:18:9 | @@ -167,5 +187,5 @@ error: consider choosing a more descriptive name 151 | let __1___2 = 12; | ^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/print.stderr b/tests/ui/print.stderr index 457ed38a1b5..f2d2afd9bf7 100644 --- a/tests/ui/print.stderr +++ b/tests/ui/print.stderr @@ -1,16 +1,22 @@ error: use of `Debug`-based formatting - --> $DIR/print.rs:13:27 + --> $DIR/print.rs:13:19 | 13 | write!(f, "{:?}", 43.1415) - | ^^^^^^^ + | ^^^^^^ | = note: `-D use-debug` implied by `-D warnings` +error: use of `Debug`-based formatting + --> $DIR/print.rs:20:19 + | +20 | write!(f, "{:?}", 42.718) + | ^^^^^^ + error: use of `println!` --> $DIR/print.rs:25:5 | 25 | println!("Hello"); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: `-D print-stdout` implied by `-D warnings` @@ -18,37 +24,37 @@ error: use of `print!` --> $DIR/print.rs:26:5 | 26 | print!("Hello"); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:28:5 | 28 | print!("Hello {}", "World"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:30:5 | 30 | print!("Hello {:?}", "World"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> $DIR/print.rs:30:26 + --> $DIR/print.rs:30:12 | 30 | print!("Hello {:?}", "World"); - | ^^^^^^^ + | ^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:32:5 | 32 | print!("Hello {:#?}", "#orld"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> $DIR/print.rs:32:27 + --> $DIR/print.rs:32:12 | 32 | print!("Hello {:#?}", "#orld"); - | ^^^^^^^ + | ^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index d1e4b49cbdd..39e0387cb5e 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -1,4 +1,4 @@ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:23:71 | 23 | println!("{} of {:b} people know binary, the other half doesn't", 1, 2); @@ -6,79 +6,79 @@ error: printing a literal with an empty format string | = note: `-D print-literal` implied by `-D warnings` -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:24:24 | 24 | print!("Hello {}", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:25:36 | 25 | println!("Hello {} {}", world, "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:26:26 | 26 | println!("Hello {}", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:27:30 | 27 | println!("10 / 4 is {}", 2.5); | ^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:28:28 | 28 | println!("2 + 1 = {}", 3); | ^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:33:25 | 33 | println!("{0} {1}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:33:34 | 33 | println!("{0} {1}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:34:25 | 34 | println!("{1} {0}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:34:34 | 34 | println!("{1} {0}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:37:33 | 37 | println!("{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:37:46 | 37 | println!("{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:38:33 | 38 | println!("{bar} {foo}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:38:46 | 38 | println!("{bar} {foo}", foo="hello", bar="world"); diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr index 5f2013e728e..181f16b5cb7 100644 --- a/tests/ui/print_with_newline.stderr +++ b/tests/ui/print_with_newline.stderr @@ -2,9 +2,27 @@ error: using `print!()` with a format string that ends in a newline, consider us --> $DIR/print_with_newline.rs:7:5 | 7 | print!("Hello/n"); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: `-D print-with-newline` implied by `-D warnings` -error: aborting due to previous error +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:8:5 + | +8 | print!("Hello {}/n", "world"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:9:5 + | +9 | print!("Hello {} {}/n/n", "world", "#2"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:10:5 + | +10 | print!("{}/n", 1265); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/tests/ui/println_empty_string.stderr b/tests/ui/println_empty_string.stderr index 1148a4496a5..cff3f988052 100644 --- a/tests/ui/println_empty_string.stderr +++ b/tests/ui/println_empty_string.stderr @@ -4,7 +4,7 @@ error: using `println!("")` 3 | println!(""); | ^^^^^^^^^^^^ help: replace it with: `println!()` | - = note: `-D print-with-newline` implied by `-D warnings` + = note: `-D println-empty-string` implied by `-D warnings` error: using `println!("")` --> $DIR/println_empty_string.rs:6:14 diff --git a/tests/ui/suspicious_arithmetic_impl.rs b/tests/ui/suspicious_arithmetic_impl.rs index d5982efe12f..9f6fce2495a 100644 --- a/tests/ui/suspicious_arithmetic_impl.rs +++ b/tests/ui/suspicious_arithmetic_impl.rs @@ -25,7 +25,7 @@ impl Mul for Foo { type Output = Foo; fn mul(self, other: Foo) -> Foo { - Foo(self.0 * other.0 % 42) // OK: BiRem part of BiExpr as parent node + Foo(self.0 * other.0 % 42) // OK: BinOpKind::Rem part of BiExpr as parent node } } @@ -33,7 +33,7 @@ impl Sub for Foo { type Output = Foo; fn sub(self, other: Self) -> Self { - Foo(self.0 * other.0 - 42) // OK: BiMul part of BiExpr as child node + Foo(self.0 * other.0 - 42) // OK: BinOpKind::Mul part of BiExpr as child node } } @@ -41,7 +41,7 @@ impl Div for Foo { type Output = Foo; fn div(self, other: Self) -> Self { - Foo(do_nothing(self.0 + other.0) / 42) // OK: BiAdd part of BiExpr as child node + Foo(do_nothing(self.0 + other.0) / 42) // OK: BinOpKind::Add part of BiExpr as child node } } diff --git a/tests/ui/trailing_zeros.stdout b/tests/ui/trailing_zeros.stdout index 145c102ed95..b311604c0c8 100644 --- a/tests/ui/trailing_zeros.stdout +++ b/tests/ui/trailing_zeros.stdout @@ -1,13 +1,13 @@ if_chain! { - if let Expr_::ExprBinary(ref op, ref left, ref right) = expr.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_::ExprPath(ref path) = left1.node; + if let ExprKind::Binary(ref op, ref left, ref right) = expr.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::Path(ref path) = left1.node; if match_qpath(path, &["x"]); - if let Expr_::ExprLit(ref lit) = right1.node; + if let ExprKind::Lit(ref lit) = right1.node; if let LitKind::Int(15, _) = 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; then { // report your lint here diff --git a/tests/ui/trivially_copy_pass_by_ref.rs b/tests/ui/trivially_copy_pass_by_ref.rs index aba4aa5ea32..c6773add244 100644 --- a/tests/ui/trivially_copy_pass_by_ref.rs +++ b/tests/ui/trivially_copy_pass_by_ref.rs @@ -11,6 +11,15 @@ type Baz = u32; fn good(a: &mut u32, b: u32, c: &Bar) { } +fn good_return_implicit_lt_ref(foo: &Foo) -> &u32 { + &foo.0 +} + +#[allow(needless_lifetimes)] +fn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 { + &foo.0 +} + fn bad(x: &u32, y: &Foo, z: &Baz) { } @@ -46,6 +55,8 @@ fn main() { let (mut foo, bar) = (Foo(0), Bar([0; 24])); let (mut a, b, c, x, y, z) = (0, 0, Bar([0; 24]), 0, Foo(0), 0); good(&mut a, b, &c); + good_return_implicit_lt_ref(&y); + good_return_explicit_lt_ref(&y); bad(&x, &y, &z); foo.good(&mut a, b, &c); foo.good2(); diff --git a/tests/ui/trivially_copy_pass_by_ref.stderr b/tests/ui/trivially_copy_pass_by_ref.stderr index c6ab968a7c5..db25cc5a020 100644 --- a/tests/ui/trivially_copy_pass_by_ref.stderr +++ b/tests/ui/trivially_copy_pass_by_ref.stderr @@ -1,81 +1,81 @@ error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:14:11 + --> $DIR/trivially_copy_pass_by_ref.rs:23:11 | -14 | fn bad(x: &u32, y: &Foo, z: &Baz) { +23 | fn bad(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `u32` | = note: `-D trivially-copy-pass-by-ref` implied by `-D warnings` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:14:20 + --> $DIR/trivially_copy_pass_by_ref.rs:23:20 | -14 | fn bad(x: &u32, y: &Foo, z: &Baz) { +23 | fn bad(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Foo` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:14:29 + --> $DIR/trivially_copy_pass_by_ref.rs:23:29 | -14 | fn bad(x: &u32, y: &Foo, z: &Baz) { +23 | fn bad(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Baz` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:24:12 + --> $DIR/trivially_copy_pass_by_ref.rs:33:12 | -24 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { +33 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { | ^^^^^ help: consider passing by value instead: `self` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:24:22 + --> $DIR/trivially_copy_pass_by_ref.rs:33:22 | -24 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { +33 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `u32` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:24:31 + --> $DIR/trivially_copy_pass_by_ref.rs:33:31 | -24 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { +33 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Foo` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:24:40 + --> $DIR/trivially_copy_pass_by_ref.rs:33:40 | -24 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { +33 | fn bad(&self, x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Baz` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:27:16 + --> $DIR/trivially_copy_pass_by_ref.rs:36:16 | -27 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +36 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `u32` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:27:25 + --> $DIR/trivially_copy_pass_by_ref.rs:36:25 | -27 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +36 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Foo` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:27:34 + --> $DIR/trivially_copy_pass_by_ref.rs:36:34 | -27 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +36 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Baz` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:41:16 + --> $DIR/trivially_copy_pass_by_ref.rs:50:16 | -41 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +50 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `u32` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:41:25 + --> $DIR/trivially_copy_pass_by_ref.rs:50:25 | -41 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +50 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Foo` error: this argument is passed by reference, but would be more efficient if passed by value - --> $DIR/trivially_copy_pass_by_ref.rs:41:34 + --> $DIR/trivially_copy_pass_by_ref.rs:50:34 | -41 | fn bad2(x: &u32, y: &Foo, z: &Baz) { +50 | fn bad2(x: &u32, y: &Foo, z: &Baz) { | ^^^^ help: consider passing by value instead: `Baz` error: aborting due to 13 previous errors diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs index 217e886c8be..68c7d2007a6 100644 --- a/tests/ui/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -6,6 +6,8 @@ #[cfg_attr(feature = "cargo-clippy", allow(dead_code, unused_extern_crates))] #[cfg_attr(feature = "cargo-clippy", allow(dead_code, unused_extern_crates))] +#[allow(unused_imports)] +#[macro_use] extern crate clippy_lints; // don't lint on unused_import for `use` items diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 323a83e244a..70855ef8187 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -1,4 +1,4 @@ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:26:79 | 26 | writeln!(&mut v, "{} of {:b} people know binary, the other half doesn't", 1, 2); @@ -6,79 +6,79 @@ error: writing a literal with an empty format string | = note: `-D write-literal` implied by `-D warnings` -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:27:32 | 27 | write!(&mut v, "Hello {}", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:28:44 | 28 | writeln!(&mut v, "Hello {} {}", world, "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:29:34 | 29 | writeln!(&mut v, "Hello {}", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:30:38 | 30 | writeln!(&mut v, "10 / 4 is {}", 2.5); | ^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:31:36 | 31 | writeln!(&mut v, "2 + 1 = {}", 3); | ^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:36:33 | 36 | writeln!(&mut v, "{0} {1}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:36:42 | 36 | writeln!(&mut v, "{0} {1}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:37:33 | 37 | writeln!(&mut v, "{1} {0}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:37:42 | 37 | writeln!(&mut v, "{1} {0}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:40:41 | 40 | writeln!(&mut v, "{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:40:54 | 40 | writeln!(&mut v, "{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:41:41 | 41 | writeln!(&mut v, "{bar} {foo}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:41:54 | 41 | writeln!(&mut v, "{bar} {foo}", foo="hello", bar="world"); diff --git a/tests/ui/write_with_newline.stderr b/tests/ui/write_with_newline.stderr index 37f03afb016..7bb9b99731f 100644 --- a/tests/ui/write_with_newline.stderr +++ b/tests/ui/write_with_newline.stderr @@ -2,7 +2,7 @@ error: using `write!()` with a format string that ends in a newline, consider us --> $DIR/write_with_newline.rs:10:5 | 10 | write!(&mut v, "Hello/n"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D write-with-newline` implied by `-D warnings` @@ -10,19 +10,19 @@ error: using `write!()` with a format string that ends in a newline, consider us --> $DIR/write_with_newline.rs:11:5 | 11 | write!(&mut v, "Hello {}/n", "world"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `write!()` with a format string that ends in a newline, consider using `writeln!()` instead --> $DIR/write_with_newline.rs:12:5 | 12 | write!(&mut v, "Hello {} {}/n/n", "world", "#2"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `write!()` with a format string that ends in a newline, consider using `writeln!()` instead --> $DIR/write_with_newline.rs:13:5 | 13 | write!(&mut v, "{}/n", 1265); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/writeln_empty_string.stderr b/tests/ui/writeln_empty_string.stderr index b4649384865..16a8e0a203d 100644 --- a/tests/ui/writeln_empty_string.stderr +++ b/tests/ui/writeln_empty_string.stderr @@ -4,7 +4,7 @@ error: using `writeln!(v, "")` 9 | writeln!(&mut v, ""); | ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(v)` | - = note: `-D write-with-newline` implied by `-D warnings` + = note: `-D writeln-empty-string` implied by `-D warnings` error: aborting due to previous error diff --git a/util/gh-pages/index.html b/util/gh-pages/index.html index 6892857af4e..0088ecc3d89 100644 --- a/util/gh-pages/index.html +++ b/util/gh-pages/index.html @@ -14,6 +14,9 @@ .form-inline .checkbox { margin-right: 0.6em } + .panel-heading { pointer: cursor; } + .panel-heading:hover { background-color: #eee; } + .panel-title { display: flex; } .panel-title .label { display: inline-block; } diff --git a/util/lintlib.py b/util/lintlib.py index 4323ef5c3e7..00826805e16 100644 --- a/util/lintlib.py +++ b/util/lintlib.py @@ -44,7 +44,7 @@ def parse_lints(lints, filepath): last_comment.append(line[3:]) elif line.startswith("declare_lint!"): import sys - print "don't use `declare_lint!` in clippy, use `declare_clippy_lint!` instead" + print "don't use `declare_lint!` in Clippy, use `declare_clippy_lint!` instead" sys.exit(42) elif line.startswith("declare_clippy_lint!"): comment = False diff --git a/util/update_lints.py b/util/update_lints.py index 6ee14cfcb12..70d49f940ee 100755 --- a/util/update_lints.py +++ b/util/update_lints.py @@ -192,8 +192,8 @@ def main(print_only=False, check=False): # update the links in the CHANGELOG changed |= replace_region( 'CHANGELOG.md', - "<!-- begin autogenerated links to wiki -->", - "<!-- end autogenerated links to wiki -->", + "<!-- begin autogenerated links to lint list -->", + "<!-- end autogenerated links to lint list -->", lambda: ["[`{0}`]: {1}#{0}\n".format(l[1], docs_link) for l in sorted(all_lints + deprecated_lints, key=lambda l: l[1])],