1
Fork 0

Merge commit '0e87918536' into clippyup

This commit is contained in:
flip1995 2021-03-25 19:29:11 +01:00
parent e06731bb28
commit 9f6b5de7de
412 changed files with 5715 additions and 2849 deletions

View file

@ -2103,6 +2103,7 @@ Released 2018-09-13
[`if_let_some_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_some_result [`if_let_some_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_some_result
[`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else [`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else
[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else [`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else
[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond [`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond
[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone [`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone
[`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher [`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher

View file

@ -18,11 +18,13 @@ All contributors are expected to follow the [Rust Code of Conduct].
- [Finding something to fix/improve](#finding-something-to-fiximprove) - [Finding something to fix/improve](#finding-something-to-fiximprove)
- [Writing code](#writing-code) - [Writing code](#writing-code)
- [Getting code-completion for rustc internals to work](#getting-code-completion-for-rustc-internals-to-work) - [Getting code-completion for rustc internals to work](#getting-code-completion-for-rustc-internals-to-work)
- [IntelliJ Rust](#intellij-rust)
- [Rust Analyzer](#rust-analyzer)
- [How Clippy works](#how-clippy-works) - [How Clippy works](#how-clippy-works)
- [Syncing changes between Clippy and `rust-lang/rust`](#syncing-changes-between-clippy-and-rust-langrust) - [Syncing changes between Clippy and [`rust-lang/rust`]](#syncing-changes-between-clippy-and-rust-langrust)
- [Patching git-subtree to work with big repos](#patching-git-subtree-to-work-with-big-repos) - [Patching git-subtree to work with big repos](#patching-git-subtree-to-work-with-big-repos)
- [Performing the sync from `rust-lang/rust` to Clippy](#performing-the-sync-from-rust-langrust-to-clippy) - [Performing the sync from [`rust-lang/rust`] to Clippy](#performing-the-sync-from-rust-langrust-to-clippy)
- [Performing the sync from Clippy to `rust-lang/rust`](#performing-the-sync-from-clippy-to-rust-langrust) - [Performing the sync from Clippy to [`rust-lang/rust`]](#performing-the-sync-from-clippy-to-rust-langrust)
- [Defining remotes](#defining-remotes) - [Defining remotes](#defining-remotes)
- [Issue and PR triage](#issue-and-pr-triage) - [Issue and PR triage](#issue-and-pr-triage)
- [Bors and Homu](#bors-and-homu) - [Bors and Homu](#bors-and-homu)
@ -105,21 +107,41 @@ quick read.
## Getting code-completion for rustc internals to work ## Getting code-completion for rustc internals to work
Unfortunately, [`rust-analyzer`][ra_homepage] does not (yet?) understand how Clippy uses compiler-internals ### IntelliJ Rust
Unfortunately, [`IntelliJ Rust`][IntelliJ_rust_homepage] does not (yet?) understand how Clippy uses compiler-internals
using `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not using `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not
available via a `rustup` component at the time of writing. available via a `rustup` component at the time of writing.
To work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via To work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via
`git clone https://github.com/rust-lang/rust/`. `git clone https://github.com/rust-lang/rust/`.
Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies
which rust-analyzer will be able to understand. which `IntelliJ Rust` will be able to understand.
Run `cargo dev ra_setup --repo-path <repo-path>` where `<repo-path>` is an absolute path to the rustc repo Run `cargo dev ide_setup --repo-path <repo-path>` where `<repo-path>` is a path to the rustc repo
you just cloned. you just cloned.
The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to
Clippys `Cargo.toml`s and should allow rust-analyzer to understand most of the types that Clippy uses. Clippys `Cargo.toml`s and should allow rust-analyzer to understand most of the types that Clippy uses.
Just make sure to remove the dependencies again before finally making a pull request! Just make sure to remove the dependencies again before finally making a pull request!
[ra_homepage]: https://rust-analyzer.github.io/
[rustc_repo]: https://github.com/rust-lang/rust/ [rustc_repo]: https://github.com/rust-lang/rust/
[IntelliJ_rust_homepage]: https://intellij-rust.github.io/
### Rust Analyzer
As of [#6869][6869], [`rust-analyzer`][ra_homepage] can understand that Clippy uses compiler-internals
using `extern crate` when `package.metadata.rust-analyzer.rustc_private` is set to `true` in Clippys `Cargo.toml.`
You will required a `nightly` toolchain with the `rustc-dev` component installed.
Make sure that in the `rust-analyzer` configuration, you set
```
{ "rust-analyzer.rustcSource": "discover" }
```
and
```
{ "rust-analyzer.updates.channel": "nightly" }
```
You should be able to see information on things like `Expr` or `EarlyContext` now if you hover them, also
a lot more type hints.
This will work with `rust-analyzer 2021-03-15` shipped in nightly `1.52.0-nightly (107896c32 2021-03-15)` or later.
[ra_homepage]: https://rust-analyzer.github.io/
[6869]: https://github.com/rust-lang/rust-clippy/pull/6869
## How Clippy works ## How Clippy works

View file

@ -1,6 +1,6 @@
[package] [package]
name = "clippy" name = "clippy"
version = "0.1.52" version = "0.1.53"
authors = ["The Rust Clippy Developers"] authors = ["The Rust Clippy Developers"]
description = "A bunch of helpful lints to avoid common pitfalls in Rust" description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy" repository = "https://github.com/rust-lang/rust-clippy"
@ -37,6 +37,8 @@ clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
derive-new = "0.5" derive-new = "0.5"
regex = "1.4" regex = "1.4"
quote = "1"
syn = { version = "1", features = ["full"] }
# A noop dependency that changes in the Rust repository, it's a bit of a hack. # A noop dependency that changes in the Rust repository, it's a bit of a hack.
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

View file

@ -90,7 +90,7 @@ pub fn run(check: bool, verbose: bool) {
}, },
CliError::RaSetupActive => { CliError::RaSetupActive => {
eprintln!( eprintln!(
"error: a local rustc repo is enabled as path dependency via `cargo dev ra_setup`. "error: a local rustc repo is enabled as path dependency via `cargo dev ide_setup`.
Not formatting because that would format the local repo as well! Not formatting because that would format the local repo as well!
Please revert the changes to Cargo.tomls first." Please revert the changes to Cargo.tomls first."
); );

View file

@ -55,7 +55,7 @@ fn inject_deps_into_manifest(
// do not inject deps if we have aleady done so // do not inject deps if we have aleady done so
if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") { if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
eprintln!( eprintln!(
"cargo dev ra_setup: warning: deps already found inside {}, doing nothing.", "cargo dev ide_setup: warning: deps already found inside {}, doing nothing.",
manifest_path manifest_path
); );
return Ok(()); return Ok(());

View file

@ -12,8 +12,8 @@ use walkdir::WalkDir;
pub mod bless; pub mod bless;
pub mod fmt; pub mod fmt;
pub mod ide_setup;
pub mod new_lint; pub mod new_lint;
pub mod ra_setup;
pub mod serve; pub mod serve;
pub mod stderr_length_check; pub mod stderr_length_check;
pub mod update_lints; pub mod update_lints;

View file

@ -1,7 +1,7 @@
#![cfg_attr(feature = "deny-warnings", deny(warnings))] #![cfg_attr(feature = "deny-warnings", deny(warnings))]
use clap::{App, Arg, ArgMatches, SubCommand}; use clap::{App, Arg, ArgMatches, SubCommand};
use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints}; use clippy_dev::{bless, fmt, ide_setup, new_lint, serve, stderr_length_check, update_lints};
fn main() { fn main() {
let matches = get_clap_config(); let matches = get_clap_config();
@ -34,7 +34,7 @@ fn main() {
("limit_stderr_length", _) => { ("limit_stderr_length", _) => {
stderr_length_check::check(); stderr_length_check::check();
}, },
("ra_setup", Some(matches)) => ra_setup::run(matches.value_of("rustc-repo-path")), ("ide_setup", Some(matches)) => ide_setup::run(matches.value_of("rustc-repo-path")),
("serve", Some(matches)) => { ("serve", Some(matches)) => {
let port = matches.value_of("port").unwrap().parse().unwrap(); let port = matches.value_of("port").unwrap().parse().unwrap();
let lint = matches.value_of("lint"); let lint = matches.value_of("lint");
@ -138,8 +138,8 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
.about("Ensures that stderr files do not grow longer than a certain amount of lines."), .about("Ensures that stderr files do not grow longer than a certain amount of lines."),
) )
.subcommand( .subcommand(
SubCommand::with_name("ra_setup") SubCommand::with_name("ide_setup")
.about("Alter dependencies so rust-analyzer can find rustc internals") .about("Alter dependencies so Intellij Rust can find rustc internals")
.arg( .arg(
Arg::with_name("rustc-repo-path") Arg::with_name("rustc-repo-path")
.long("repo-path") .long("repo-path")

View file

@ -1,7 +1,7 @@
[package] [package]
name = "clippy_lints" name = "clippy_lints"
# begin automatic update # begin automatic update
version = "0.1.52" version = "0.1.53"
# end automatic update # end automatic update
authors = ["The Rust Clippy Developers"] authors = ["The Rust Clippy Developers"]
description = "A bunch of helpful lints to avoid common pitfalls in Rust" description = "A bunch of helpful lints to avoid common pitfalls in Rust"
@ -20,7 +20,6 @@ pulldown-cmark = { version = "0.8", default-features = false }
quine-mc_cluskey = "0.2.2" quine-mc_cluskey = "0.2.2"
regex-syntax = "0.6" regex-syntax = "0.6"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
smallvec = { version = "1", features = ["union"] }
toml = "0.5.3" toml = "0.5.3"
unicode-normalization = "0.1" unicode-normalization = "0.1"
semver = "0.11" semver = "0.11"
@ -28,8 +27,6 @@ rustc-semver = "1.1.0"
# NOTE: cargo requires serde feat in its url dep # NOTE: cargo requires serde feat in its url dep
# see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864> # see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
url = { version = "2.1.0", features = ["serde"] } url = { version = "2.1.0", features = ["serde"] }
quote = "1"
syn = { version = "1", features = ["full"] }
[features] [features]
deny-warnings = [] deny-warnings = []

View file

@ -1,4 +1,4 @@
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,5 +1,5 @@
use crate::consts::constant_simple; use crate::consts::constant_simple;
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};

View file

@ -1,10 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{Expr, ExprKind}; use rustc_ast::ast::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::span_lint_and_help;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `as` conversions. /// **What it does:** Checks for usage of `as` conversions.
/// ///

View file

@ -1,6 +1,6 @@
use std::fmt; use std::fmt;
use crate::utils::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions}; use rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions};
use rustc_lint::{EarlyContext, EarlyLintPass, Lint}; use rustc_lint::{EarlyContext, EarlyLintPass, Lint};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};

View file

@ -1,5 +1,7 @@
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, snippet_opt, span_lint_and_help}; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet_opt;
use clippy_utils::{is_direct_expn_of, is_expn_of, match_panic_call};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, UnOp}; use rustc_hir::{Expr, ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,7 +1,8 @@
use crate::utils::{ use clippy_utils::diagnostics::span_lint_and_then;
eq_expr_value, get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, use clippy_utils::source::snippet_opt;
}; use clippy_utils::ty::implements_trait;
use crate::utils::{higher, sugg}; use clippy_utils::{eq_expr_value, get_trait_def_id, trait_ref_of_method};
use clippy_utils::{higher, paths, sugg};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -92,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for AssignOps {
$($trait_name:ident),+) => { $($trait_name:ident),+) => {
match $op { match $op {
$(hir::BinOpKind::$trait_name => { $(hir::BinOpKind::$trait_name => {
let [krate, module] = crate::utils::paths::OPS_MODULE; let [krate, module] = paths::OPS_MODULE;
let path: [&str; 3] = [krate, module, concat!(stringify!($trait_name), "Assign")]; let path: [&str; 3] = [krate, module, concat!(stringify!($trait_name), "Assign")];
let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) { let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) {
trait_id trait_id

View file

@ -1,4 +1,6 @@
use crate::utils::{implements_trait, snippet, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath}; use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,4 +1,5 @@
use crate::utils::{match_def_path, span_lint_and_help}; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::match_def_path;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};

View file

@ -1,9 +1,8 @@
//! checks for attributes //! checks for attributes
use crate::utils::{ use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
first_line_of_span, is_present_in_source, match_panic_def_id, snippet_opt, span_lint, span_lint_and_help, use clippy_utils::match_panic_def_id;
span_lint_and_sugg, span_lint_and_then, without_block_comments, use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -431,7 +430,7 @@ fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_
|stmt| match &stmt.kind { |stmt| match &stmt.kind {
StmtKind::Local(_) => true, StmtKind::Local(_) => true,
StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr), StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
_ => false, StmtKind::Item(_) => false,
}, },
) )
} }
@ -565,7 +564,7 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) {
// check for `rustfmt_skip` and `rustfmt::skip` // check for `rustfmt_skip` and `rustfmt::skip`
if let Some(skip_item) = &items[1].meta_item(); if let Some(skip_item) = &items[1].meta_item();
if skip_item.has_name(sym!(rustfmt_skip)) || if skip_item.has_name(sym!(rustfmt_skip)) ||
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip); skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym::skip;
// Only lint outer attributes, because custom inner attributes are unstable // Only lint outer attributes, because custom inner attributes are unstable
// Tracking issue: https://github.com/rust-lang/rust/issues/54726 // Tracking issue: https://github.com/rust-lang/rust/issues/54726
if let AttrStyle::Outer = attr.style; if let AttrStyle::Outer = attr.style;
@ -614,7 +613,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
} }
} }
}, },
_ => {}, MetaItemKind::NameValue(..) => {},
} }
} }
} }

View file

@ -1,4 +1,5 @@
use crate::utils::{match_def_path, paths, span_lint_and_note}; use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::{match_def_path, paths};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind}; use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,6 +1,6 @@
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::sugg::Sugg; use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use crate::utils::{span_lint, span_lint_and_then}; use clippy_utils::sugg::Sugg;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,4 +1,4 @@
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{Pat, PatKind}; use rustc_hir::{Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,7 +1,7 @@
use crate::utils::{ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
differing_macro_contexts, get_parent_expr, get_trait_def_id, implements_trait, paths, use clippy_utils::source::snippet_block_with_applicability;
snippet_block_with_applicability, span_lint, span_lint_and_sugg, use clippy_utils::ty::implements_trait;
}; use clippy_utils::{differing_macro_contexts, get_parent_expr};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
@ -10,6 +10,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `if` conditions that use blocks containing an /// **What it does:** Checks for `if` conditions that use blocks containing an
@ -61,7 +62,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
if let Some(parent) = get_parent_expr(self.cx, expr); if let Some(parent) = get_parent_expr(self.cx, expr);
if let ExprKind::MethodCall(_, _, args, _) = parent.kind; if let ExprKind::MethodCall(_, _, args, _) = parent.kind;
let caller = self.cx.typeck_results().expr_ty(&args[0]); let caller = self.cx.typeck_results().expr_ty(&args[0]);
if let Some(iter_id) = get_trait_def_id(self.cx, &paths::ITERATOR); if let Some(iter_id) = self.cx.tcx.get_diagnostic_item(sym::Iterator);
if implements_trait(self.cx, caller, iter_id, &[]); if implements_trait(self.cx, caller, iter_id, &[]);
then { then {
return; return;

View file

@ -1,7 +1,7 @@
use crate::utils::{ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
eq_expr_value, get_trait_def_id, implements_trait, in_macro, is_type_diagnostic_item, paths, snippet_opt, use clippy_utils::source::snippet_opt;
span_lint_and_sugg, span_lint_and_then, use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
}; use clippy_utils::{eq_expr_value, get_trait_def_id, in_macro, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,6 +1,7 @@
use crate::utils::{ use clippy_utils::diagnostics::span_lint_and_sugg;
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability, span_lint_and_sugg, use clippy_utils::source::snippet_with_applicability;
}; use clippy_utils::ty::match_type;
use clippy_utils::{contains_name, get_pat_name, paths, single_segment_path};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp}; use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp};

View file

@ -2,7 +2,8 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::utils::{run_lints, span_lint}; use clippy_utils::diagnostics::span_lint;
use clippy_utils::run_lints;
use rustc_hir::{hir_id::CRATE_HIR_ID, Crate}; use rustc_hir::{hir_id::CRATE_HIR_ID, Crate};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};

View file

@ -1,4 +1,4 @@
use crate::utils::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind, PathSegment}; use rustc_hir::{Expr, ExprKind, PathSegment};

View file

@ -1,10 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::in_constant;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_isize_or_usize;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_middle::ty::{self, FloatTy, Ty};
use crate::utils::{in_constant, is_isize_or_usize, snippet_opt, span_lint_and_sugg};
use super::{utils, CAST_LOSSLESS}; use super::{utils, CAST_LOSSLESS};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_isize_or_usize;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_middle::ty::{self, FloatTy, Ty};
use crate::utils::{is_isize_or_usize, span_lint};
use super::{utils, CAST_POSSIBLE_TRUNCATION}; use super::{utils, CAST_POSSIBLE_TRUNCATION};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_isize_or_usize;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use crate::utils::{is_isize_or_usize, span_lint};
use super::{utils, CAST_POSSIBLE_WRAP}; use super::{utils, CAST_POSSIBLE_WRAP};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_isize_or_usize;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_middle::ty::{self, FloatTy, Ty};
use crate::utils::{is_isize_or_usize, span_lint};
use super::{utils, CAST_PRECISION_LOSS}; use super::{utils, CAST_PRECISION_LOSS};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,13 +1,12 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::is_hir_ty_cfg_dependant;
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, GenericArg}; use rustc_hir::{Expr, ExprKind, GenericArg};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_target::abi::LayoutOf; use rustc_target::abi::LayoutOf;
use if_chain::if_chain;
use crate::utils::{is_hir_ty_cfg_dependant, span_lint};
use super::CAST_PTR_ALIGNMENT; use super::CAST_PTR_ALIGNMENT;
pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {

View file

@ -1,11 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp}; use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
use if_chain::if_chain;
use crate::utils::span_lint;
use super::CAST_REF_TO_MUT; use super::CAST_REF_TO_MUT;
pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {

View file

@ -1,12 +1,11 @@
use crate::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::{method_chain_args, sext};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use if_chain::if_chain;
use crate::consts::{constant, Constant};
use crate::utils::{method_chain_args, sext, span_lint};
use super::CAST_SIGN_LOSS; use super::CAST_SIGN_LOSS;
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,13 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use if_chain::if_chain;
use rustc_ast::LitKind; use rustc_ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, UintTy}; use rustc_middle::ty::{self, UintTy};
use if_chain::if_chain;
use crate::utils::{snippet_with_applicability, span_lint_and_then};
use super::CHAR_LIT_AS_U8; use super::CHAR_LIT_AS_U8;
pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty, UintTy}; use rustc_middle::ty::{self, Ty, UintTy};
use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
use super::{utils, FN_TO_NUMERIC_CAST}; use super::{utils, FN_TO_NUMERIC_CAST};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
use super::{utils, FN_TO_NUMERIC_CAST_WITH_TRUNCATION}; use super::{utils, FN_TO_NUMERIC_CAST_WITH_TRUNCATION};
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {

View file

@ -12,14 +12,13 @@ mod ptr_as_ptr;
mod unnecessary_cast; mod unnecessary_cast;
mod utils; mod utils;
use clippy_utils::is_hir_ty_cfg_dependant;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_semver::RustcVersion; use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use crate::utils::is_hir_ty_cfg_dependant;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts from any numerical to a float type where /// **What it does:** Checks for casts from any numerical to a float type where
/// the receiving type cannot store all values from the original type without /// the receiving type cannot store all values from the original type without

View file

@ -1,16 +1,15 @@
use std::borrow::Cow; use std::borrow::Cow;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::meets_msrv;
use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, TyKind}; use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, TypeAndMut}; use rustc_middle::ty::{self, TypeAndMut};
use rustc_semver::RustcVersion; use rustc_semver::RustcVersion;
use if_chain::if_chain;
use crate::utils::sugg::Sugg;
use crate::utils::{meets_msrv, span_lint_and_sugg};
use super::PTR_AS_PTR; use super::PTR_AS_PTR;
const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0);

View file

@ -1,3 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::numeric_literal::NumericLiteral;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Lit, UnOp}; use rustc_hir::{Expr, ExprKind, Lit, UnOp};
@ -5,10 +9,6 @@ use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, FloatTy, InferTy, Ty}; use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
use if_chain::if_chain;
use crate::utils::{numeric_literal::NumericLiteral, snippet_opt, span_lint, span_lint_and_sugg};
use super::UNNECESSARY_CAST; use super::UNNECESSARY_CAST;
pub(super) fn check( pub(super) fn check(
@ -44,9 +44,18 @@ pub(super) fn check(
lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to);
}, },
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {}, LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {},
LitKind::Int(_, LitIntType::Signed(_) | LitIntType::Unsigned(_))
| LitKind::Float(_, LitFloatType::Suffixed(_))
if cast_from.kind() == cast_to.kind() =>
{
if let Some(src) = snippet_opt(cx, lit.span) {
let num_lit = NumericLiteral::from_lit_kind(&src, &lit.node).unwrap();
lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);
}
},
_ => { _ => {
if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
span_lint( span_lint_and_sugg(
cx, cx,
UNNECESSARY_CAST, UNNECESSARY_CAST,
expr.span, expr.span,
@ -54,6 +63,9 @@ pub(super) fn check(
"casting to the same type is unnecessary (`{}` -> `{}`)", "casting to the same type is unnecessary (`{}` -> `{}`)",
cast_from, cast_to cast_from, cast_to
), ),
"try",
literal_str,
Applicability::MachineApplicable,
); );
return true; return true;
} }

View file

@ -1,5 +1,8 @@
//! lint on manually implemented checked conversions that could be transformed into `try_from` //! lint on manually implemented checked conversions that could be transformed into `try_from`
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{meets_msrv, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -9,8 +12,6 @@ use rustc_middle::lint::in_external_macro;
use rustc_semver::RustcVersion; use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use crate::utils::{meets_msrv, snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
const CHECKED_CONVERSIONS_MSRV: RustcVersion = RustcVersion::new(1, 34, 0); const CHECKED_CONVERSIONS_MSRV: RustcVersion = RustcVersion::new(1, 34, 0);
declare_clippy_lint! { declare_clippy_lint! {

View file

@ -1,5 +1,9 @@
//! calculate cognitive complexity and warn about overly complex functions //! calculate cognitive complexity and warn about overly complex functions
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::LimitStack;
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;
use rustc_hir::intravisit::{walk_expr, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_expr, FnKind, NestedVisitorMap, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId};
@ -9,8 +13,6 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::{sym, BytePos}; use rustc_span::{sym, BytePos};
use crate::utils::{is_type_diagnostic_item, snippet_opt, span_lint_and_help, LimitStack};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for methods with high cognitive complexity. /// **What it does:** Checks for methods with high cognitive complexity.
/// ///

View file

@ -12,15 +12,15 @@
//! //!
//! This lint is **warn** by default //! This lint is **warn** by default
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet_block, snippet_block_with_applicability};
use clippy_utils::sugg::Sugg;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast; use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::sugg::Sugg;
use crate::utils::{snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then};
use rustc_errors::Applicability;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for nested `if` statements which can be collapsed /// **What it does:** Checks for nested `if` statements which can be collapsed
/// by `&&`-combining their conditions. /// by `&&`-combining their conditions.

View file

@ -1,5 +1,6 @@
use crate::utils::visitors::LocalUsedVisitor; use clippy_utils::diagnostics::span_lint_and_then;
use crate::utils::{path_to_local, span_lint_and_then, SpanlessEq}; use clippy_utils::visitors::LocalUsedVisitor;
use clippy_utils::{path_to_local, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind, QPath, StmtKind, UnOp}; use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind, QPath, StmtKind, UnOp};

View file

@ -1,6 +1,6 @@
use crate::utils::{ use clippy_utils::diagnostics::span_lint_and_help;
get_trait_def_id, if_sequence, implements_trait, parent_node_is_if_expr, paths, span_lint_and_help, SpanlessEq, use clippy_utils::ty::implements_trait;
}; use clippy_utils::{get_trait_def_id, if_sequence, parent_node_is_if_expr, paths, SpanlessEq};
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};

View file

@ -1,5 +1,6 @@
use crate::utils::{eq_expr_value, in_macro, search_same, SpanlessEq, SpanlessHash}; use clippy_utils::diagnostics::span_lint_and_note;
use crate::utils::{get_parent_expr, if_sequence, span_lint_and_note}; use clippy_utils::{eq_expr_value, in_macro, search_same, SpanlessEq, SpanlessHash};
use clippy_utils::{get_parent_expr, if_sequence};
use rustc_hir::{Block, Expr, ExprKind}; use rustc_hir::{Block, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};

View file

@ -1,7 +1,11 @@
use crate::utils::{is_copy, match_path, paths, span_lint_and_note}; use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::ty::is_copy;
use rustc_hir::{Impl, Item, ItemKind}; use rustc_hir::{Impl, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
use if_chain::if_chain;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for types that implement `Copy` as well as /// **What it does:** Checks for types that implement `Copy` as well as
@ -33,14 +37,16 @@ declare_lint_pass!(CopyIterator => [COPY_ITERATOR]);
impl<'tcx> LateLintPass<'tcx> for CopyIterator { impl<'tcx> LateLintPass<'tcx> for CopyIterator {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Impl(Impl { if_chain! {
of_trait: Some(ref trait_ref), if let ItemKind::Impl(Impl {
.. of_trait: Some(ref trait_ref),
}) = item.kind ..
{ }) = item.kind;
let ty = cx.tcx.type_of(item.def_id); let ty = cx.tcx.type_of(item.def_id);
if is_copy(cx, ty);
if is_copy(cx, ty) && match_path(&trait_ref.path, &paths::ITERATOR) { if let Some(trait_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);
then {
span_lint_and_note( span_lint_and_note(
cx, cx,
COPY_ITERATOR, COPY_ITERATOR,

View file

@ -1,4 +1,6 @@
use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};

View file

@ -1,4 +1,5 @@
use crate::utils::{snippet_opt, span_lint_and_help, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::snippet_opt;
use rustc_ast::ast; use rustc_ast::ast;
use rustc_ast::tokenstream::TokenStream; use rustc_ast::tokenstream::TokenStream;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,7 +1,6 @@
use crate::utils::{ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
any_parent_is_automatically_derived, contains_name, match_def_path, paths, snippet_with_macro_callsite, use clippy_utils::source::snippet_with_macro_callsite;
}; use clippy_utils::{any_parent_is_automatically_derived, contains_name, match_def_path, paths};
use crate::utils::{span_lint_and_note, span_lint_and_sugg};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -105,6 +104,7 @@ impl LateLintPass<'_> for Default {
} }
} }
#[allow(clippy::too_many_lines)]
fn check_block<'tcx>(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) { fn check_block<'tcx>(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
// start from the `let mut _ = _::default();` and look at all the following // start from the `let mut _ = _::default();` and look at all the following
// statements, see if they re-assign the fields of the binding // statements, see if they re-assign the fields of the binding
@ -198,6 +198,24 @@ impl LateLintPass<'_> for Default {
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", "); .join(", ");
// give correct suggestion if generics are involved (see #6944)
let binding_type = if_chain! {
if let ty::Adt(adt_def, substs) = binding_type.kind();
if !substs.is_empty();
let adt_def_ty_name = cx.tcx.item_name(adt_def.did);
let generic_args = substs.iter().collect::<Vec<_>>();
let tys_str = generic_args
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", ");
then {
format!("{}::<{}>", adt_def_ty_name, &tys_str)
} else {
binding_type.to_string()
}
};
let sugg = if ext_with_default { let sugg = if ext_with_default {
if field_list.is_empty() { if field_list.is_empty() {
format!("{}::default()", binding_type) format!("{}::default()", binding_type)

View file

@ -1,3 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use if_chain::if_chain;
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind}; use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{ use rustc_hir::{
@ -11,10 +14,6 @@ use rustc_middle::{
}; };
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use if_chain::if_chain;
use crate::utils::{snippet, span_lint_and_sugg};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type /// **What it does:** Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
/// inference. /// inference.

View file

@ -1,11 +1,14 @@
use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use if_chain::if_chain; use clippy_utils::source::snippet_with_context;
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX, PREC_PREFIX}; use clippy_utils::ty::peel_mid_ty_refs;
use clippy_utils::{get_parent_node, in_macro, is_allowed};
use rustc_ast::util::parser::PREC_PREFIX;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, UnOp};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_middle::ty::{self, Ty, TyCtxt, TyS, TypeckResults};
use rustc_span::source_map::Span; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for explicit `deref()` or `deref_mut()` method calls. /// **What it does:** Checks for explicit `deref()` or `deref_mut()` method calls.
@ -34,76 +37,265 @@ declare_clippy_lint! {
"Explicit use of deref or deref_mut method while not in a method chain." "Explicit use of deref or deref_mut method while not in a method chain."
} }
declare_lint_pass!(Dereferencing => [ impl_lint_pass!(Dereferencing => [
EXPLICIT_DEREF_METHODS EXPLICIT_DEREF_METHODS,
]); ]);
#[derive(Default)]
pub struct Dereferencing {
state: Option<(State, StateData)>,
// While parsing a `deref` method call in ufcs form, the path to the function is itself an
// expression. This is to store the id of that expression so it can be skipped when
// `check_expr` is called for it.
skip_expr: Option<HirId>,
}
struct StateData {
/// Span of the top level expression
span: Span,
/// The required mutability
target_mut: Mutability,
}
enum State {
// Any number of deref method calls.
DerefMethod {
// The number of calls in a sequence which changed the referenced type
ty_changed_count: usize,
is_final_ufcs: bool,
},
}
// A reference operation considered by this lint pass
enum RefOp {
Method(Mutability),
Deref,
AddrOf,
}
impl<'tcx> LateLintPass<'tcx> for Dereferencing { impl<'tcx> LateLintPass<'tcx> for Dereferencing {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! { // Skip path expressions from deref calls. e.g. `Deref::deref(e)`
if !expr.span.from_expansion(); if Some(expr.hir_id) == self.skip_expr.take() {
if let ExprKind::MethodCall(ref method_name, _, ref args, _) = &expr.kind; return;
if args.len() == 1; }
then { // Stop processing sub expressions when a macro call is seen
if let Some(parent_expr) = get_parent_expr(cx, expr) { if in_macro(expr.span) {
// Check if we have the whole call chain here if let Some((state, data)) = self.state.take() {
if let ExprKind::MethodCall(..) = parent_expr.kind { report(cx, expr, state, data);
return;
}
// Check for Expr that we don't want to be linted
let precedence = parent_expr.precedence();
match precedence {
// Lint a Call is ok though
ExprPrecedence::Call | ExprPrecedence::AddrOf => (),
_ => {
if precedence.order() >= PREC_PREFIX && precedence.order() <= PREC_POSTFIX {
return;
}
}
}
}
let name = method_name.ident.as_str();
lint_deref(cx, &*name, &args[0], args[0].span, expr.span);
} }
return;
}
let typeck = cx.typeck_results();
let (kind, sub_expr) = if let Some(x) = try_parse_ref_op(cx.tcx, typeck, expr) {
x
} else {
// The whole chain of reference operations has been seen
if let Some((state, data)) = self.state.take() {
report(cx, expr, state, data);
}
return;
};
match (self.state.take(), kind) {
(None, kind) => {
let parent = get_parent_node(cx.tcx, expr.hir_id);
let expr_ty = typeck.expr_ty(expr);
match kind {
RefOp::Method(target_mut)
if !is_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)
&& is_linted_explicit_deref_position(parent, expr.hir_id, expr.span) =>
{
self.state = Some((
State::DerefMethod {
ty_changed_count: if deref_method_same_type(expr_ty, typeck.expr_ty(sub_expr)) {
0
} else {
1
},
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
},
StateData {
span: expr.span,
target_mut,
},
));
}
_ => (),
}
},
(Some((State::DerefMethod { ty_changed_count, .. }, data)), RefOp::Method(_)) => {
self.state = Some((
State::DerefMethod {
ty_changed_count: if deref_method_same_type(typeck.expr_ty(expr), typeck.expr_ty(sub_expr)) {
ty_changed_count
} else {
ty_changed_count + 1
},
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
},
data,
));
},
(Some((state, data)), _) => report(cx, expr, state, data),
} }
} }
} }
fn lint_deref(cx: &LateContext<'_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) { fn try_parse_ref_op(
match method_name { tcx: TyCtxt<'tcx>,
"deref" => { typeck: &'tcx TypeckResults<'_>,
let impls_deref_trait = cx.tcx.lang_items().deref_trait().map_or(false, |id| { expr: &'tcx Expr<'_>,
implements_trait(cx, cx.typeck_results().expr_ty(&call_expr), id, &[]) ) -> Option<(RefOp, &'tcx Expr<'tcx>)> {
}); let (def_id, arg) = match expr.kind {
if impls_deref_trait { ExprKind::MethodCall(_, _, [arg], _) => (typeck.type_dependent_def_id(expr.hir_id)?, arg),
span_lint_and_sugg( ExprKind::Call(
cx, Expr {
EXPLICIT_DEREF_METHODS, kind: ExprKind::Path(path),
expr_span, hir_id,
"explicit deref method call", ..
"try this", },
format!("&*{}", &snippet(cx, var_span, "..")), [arg],
Applicability::MachineApplicable, ) => (typeck.qpath_res(path, *hir_id).opt_def_id()?, arg),
); ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_unsafe_ptr() => {
} return Some((RefOp::Deref, sub_expr));
},
ExprKind::AddrOf(BorrowKind::Ref, _, sub_expr) => return Some((RefOp::AddrOf, sub_expr)),
_ => return None,
};
if tcx.is_diagnostic_item(sym::deref_method, def_id) {
Some((RefOp::Method(Mutability::Not), arg))
} else if tcx.trait_of_item(def_id)? == tcx.lang_items().deref_mut_trait()? {
Some((RefOp::Method(Mutability::Mut), arg))
} else {
None
}
}
// Checks whether the type for a deref call actually changed the type, not just the mutability of
// the reference.
fn deref_method_same_type(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
match (result_ty.kind(), arg_ty.kind()) {
(ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => TyS::same_type(result_ty, arg_ty),
// The result type for a deref method is always a reference
// Not matching the previous pattern means the argument type is not a reference
// This means that the type did change
_ => false,
}
}
// Checks whether the parent node is a suitable context for switching from a deref method to the
// deref operator.
fn is_linted_explicit_deref_position(parent: Option<Node<'_>>, child_id: HirId, child_span: Span) -> bool {
let parent = match parent {
Some(Node::Expr(e)) if e.span.ctxt() == child_span.ctxt() => e,
_ => return true,
};
match parent.kind {
// Leave deref calls in the middle of a method chain.
// e.g. x.deref().foo()
ExprKind::MethodCall(_, _, [self_arg, ..], _) if self_arg.hir_id == child_id => false,
// Leave deref calls resulting in a called function
// e.g. (x.deref())()
ExprKind::Call(func_expr, _) if func_expr.hir_id == child_id => false,
// Makes an ugly suggestion
// e.g. *x.deref() => *&*x
ExprKind::Unary(UnOp::Deref, _)
// Postfix expressions would require parens
| ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
| ExprKind::Field(..)
| ExprKind::Index(..)
| ExprKind::Err => false,
ExprKind::Box(..)
| ExprKind::ConstBlock(..)
| ExprKind::Array(_)
| ExprKind::Call(..)
| ExprKind::MethodCall(..)
| ExprKind::Tup(..)
| ExprKind::Binary(..)
| ExprKind::Unary(..)
| ExprKind::Lit(..)
| ExprKind::Cast(..)
| ExprKind::Type(..)
| ExprKind::DropTemps(..)
| ExprKind::If(..)
| ExprKind::Loop(..)
| ExprKind::Match(..)
| ExprKind::Closure(..)
| ExprKind::Block(..)
| ExprKind::Assign(..)
| ExprKind::AssignOp(..)
| ExprKind::Path(..)
| ExprKind::AddrOf(..)
| ExprKind::Break(..)
| ExprKind::Continue(..)
| ExprKind::Ret(..)
| ExprKind::InlineAsm(..)
| ExprKind::LlvmInlineAsm(..)
| ExprKind::Struct(..)
| ExprKind::Repeat(..)
| ExprKind::Yield(..) => true,
}
}
#[allow(clippy::needless_pass_by_value)]
fn report(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data: StateData) {
match state {
State::DerefMethod {
ty_changed_count,
is_final_ufcs,
} => {
let mut app = Applicability::MachineApplicable;
let (expr_str, expr_is_macro_call) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app);
let ty = cx.typeck_results().expr_ty(expr);
let (_, ref_count) = peel_mid_ty_refs(ty);
let deref_str = if ty_changed_count >= ref_count && ref_count != 0 {
// a deref call changing &T -> &U requires two deref operators the first time
// this occurs. One to remove the reference, a second to call the deref impl.
"*".repeat(ty_changed_count + 1)
} else {
"*".repeat(ty_changed_count)
};
let addr_of_str = if ty_changed_count < ref_count {
// Check if a reborrow from &mut T -> &T is required.
if data.target_mut == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
"&*"
} else {
""
}
} else if data.target_mut == Mutability::Mut {
"&mut "
} else {
"&"
};
let expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX {
format!("({})", expr_str)
} else {
expr_str.into_owned()
};
span_lint_and_sugg(
cx,
EXPLICIT_DEREF_METHODS,
data.span,
match data.target_mut {
Mutability::Not => "explicit `deref` method call",
Mutability::Mut => "explicit `deref_mut` method call",
},
"try this",
format!("{}{}{}", addr_of_str, deref_str, expr_str),
app,
);
}, },
"deref_mut" => {
let impls_deref_mut_trait = cx.tcx.lang_items().deref_mut_trait().map_or(false, |id| {
implements_trait(cx, cx.typeck_results().expr_ty(&call_expr), id, &[])
});
if impls_deref_mut_trait {
span_lint_and_sugg(
cx,
EXPLICIT_DEREF_METHODS,
expr_span,
"explicit deref_mut method call",
"try this",
format!("&mut *{}", &snippet(cx, var_span, "..")),
Applicability::MachineApplicable,
);
}
},
_ => (),
} }
} }

View file

@ -1,8 +1,7 @@
use crate::utils::paths; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_then};
use crate::utils::{ use clippy_utils::paths;
get_trait_def_id, is_allowed, is_automatically_derived, is_copy, match_def_path, span_lint_and_help, use clippy_utils::ty::is_copy;
span_lint_and_note, span_lint_and_then, use clippy_utils::{get_trait_def_id, is_allowed, is_automatically_derived, match_def_path};
};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, NestedVisitorMap, Visitor};

View file

@ -1,4 +1,5 @@
use crate::utils::{fn_def_id, span_lint}; use clippy_utils::diagnostics::span_lint;
use clippy_utils::fn_def_id;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::Expr; use rustc_hir::Expr;

View file

@ -1,7 +1,6 @@
use crate::utils::{ use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
implements_trait, is_entrypoint_fn, is_expn_of, is_type_diagnostic_item, match_panic_def_id, method_chain_args, use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
return_ty, span_lint, span_lint_and_note, use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
};
use if_chain::if_chain; use if_chain::if_chain;
use itertools::Itertools; use itertools::Itertools;
use rustc_ast::ast::{Async, AttrKind, Attribute, FnKind, FnRetTy, ItemKind}; use rustc_ast::ast::{Async, AttrKind, Attribute, FnKind, FnRetTy, ItemKind};
@ -584,7 +583,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
let returns_nothing = match &sig.decl.output { let returns_nothing = match &sig.decl.output {
FnRetTy::Default(..) => true, FnRetTy::Default(..) => true,
FnRetTy::Ty(ty) if ty.kind.is_unit() => true, FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
_ => false, FnRetTy::Ty(_) => false,
}; };
if returns_nothing && !is_async && !block.stmts.is_empty() { if returns_nothing && !is_async && !block.stmts.is_empty() {

View file

@ -1,13 +1,14 @@
//! Lint on unnecessary double comparisons. Some examples: //! Lint on unnecessary double comparisons. Some examples:
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::eq_expr_value;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use crate::utils::{eq_expr_value, snippet_with_applicability, span_lint_and_sugg};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for double comparisons that could be simplified to a single expression. /// **What it does:** Checks for double comparisons that could be simplified to a single expression.
/// ///

View file

@ -1,4 +1,4 @@
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_ast::ast::{Expr, ExprKind}; use rustc_ast::ast::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};

View file

@ -1,4 +1,6 @@
use crate::utils::{is_copy, match_def_path, paths, span_lint_and_note}; use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::ty::is_copy;
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,3 +1,5 @@
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::match_type;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
@ -6,8 +8,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::paths; use clippy_utils::diagnostics::span_lint_and_sugg;
use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg}; use clippy_utils::paths;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds /// **What it does:** Checks for calculation of subsecond microseconds or milliseconds

View file

@ -1,12 +1,11 @@
//! Lint on if expressions with an else if, but without a final else branch. //! Lint on if expressions with an else if, but without a final else branch.
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{Expr, ExprKind}; use rustc_ast::ast::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::span_lint_and_help;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of if expressions with an `else if` branch, /// **What it does:** Checks for usage of if expressions with an `else if` branch,
/// but without a final `else` branch. /// but without a final `else` branch.

View file

@ -1,6 +1,6 @@
//! lint when there is an enum with no variants //! lint when there is an enum with no variants
use crate::utils::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};

View file

@ -1,6 +1,8 @@
use crate::utils::SpanlessEq; use clippy_utils::diagnostics::span_lint_and_then;
use crate::utils::{get_item_name, is_type_diagnostic_item, match_type, paths, snippet, snippet_opt}; use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use crate::utils::{snippet_with_applicability, span_lint_and_then}; use clippy_utils::ty::{is_type_diagnostic_item, match_type};
use clippy_utils::SpanlessEq;
use clippy_utils::{get_item_name, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};

View file

@ -2,7 +2,7 @@
//! don't fit into an `i32` //! don't fit into an `i32`
use crate::consts::{miri_to_const, Constant}; use crate::consts::{miri_to_const, Constant};
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::util::IntTypeExt;

View file

@ -1,7 +1,8 @@
//! lint on enum variants that are prefixed or suffixed by the same characters //! lint on enum variants that are prefixed or suffixed by the same characters
use crate::utils::{camel_case, is_present_in_source}; use clippy_utils::camel_case;
use crate::utils::{span_lint, span_lint_and_help}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
use clippy_utils::source::is_present_in_source;
use rustc_ast::ast::{EnumDef, Item, ItemKind, VisibilityKind}; use rustc_ast::ast::{EnumDef, Item, ItemKind, VisibilityKind};
use rustc_lint::{EarlyContext, EarlyLintPass, Lint}; use rustc_lint::{EarlyContext, EarlyLintPass, Lint};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};

View file

@ -1,7 +1,7 @@
use crate::utils::{ use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, implements_trait, in_macro, is_copy, is_expn_of, use clippy_utils::source::snippet;
multispan_sugg, snippet, span_lint, span_lint_and_then, use clippy_utils::ty::{implements_trait, is_copy};
}; use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind}; use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint;
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use crate::consts::{constant_simple, Constant}; use crate::consts::{constant_simple, Constant};
use crate::utils::span_lint;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for erasing operations, e.g., `x * 0`. /// **What it does:** Checks for erasing operations, e.g., `x * 0`.

View file

@ -1,3 +1,5 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::contains_ty;
use rustc_hir::intravisit; use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node}; use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -11,8 +13,6 @@ use rustc_target::abi::LayoutOf;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use crate::utils::{contains_ty, span_lint};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct BoxedLocal { pub struct BoxedLocal {
pub too_large_for_stack: u64, pub too_large_for_stack: u64,
@ -186,7 +186,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
} }
} }
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) { } fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
} }
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> { impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {

View file

@ -1,3 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::higher;
use clippy_utils::higher::VecArgs;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, type_is_unsafe_function};
use clippy_utils::{is_adjusted, iter_input_pats};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{def_id, Expr, ExprKind, Param, PatKind, QPath}; use rustc_hir::{def_id, Expr, ExprKind, Param, PatKind, QPath};
@ -6,13 +12,6 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::{
implements_trait, is_adjusted, iter_input_pats, snippet_opt, span_lint_and_sugg, span_lint_and_then,
type_is_unsafe_function,
};
use clippy_utils::higher;
use clippy_utils::higher::VecArgs;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for closures which just call another function where /// **What it does:** Checks for closures which just call another function where
/// the function can be called directly. `unsafe` functions or calls where types /// the function can be called directly. `unsafe` functions or calls where types

View file

@ -1,4 +1,5 @@
use crate::utils::{get_parent_expr, path_to_local, path_to_local_id, span_lint, span_lint_and_note}; use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Guard, HirId, Local, Node, Stmt, StmtKind}; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Guard, HirId, Local, Node, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -272,7 +273,7 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt<'_>) -
.init .init
.as_ref() .as_ref()
.map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)), .map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)),
_ => StopEarly::KeepGoing, StmtKind::Item(..) => StopEarly::KeepGoing,
} }
} }

View file

@ -1,7 +1,6 @@
use crate::utils::{attr_by_name, in_macro, match_path_ast, span_lint_and_help}; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{ use clippy_utils::{attr_by_name, in_macro, match_path_ast};
AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind, use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind};
};
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span; use rustc_span::Span;

View file

@ -1,4 +1,5 @@
use crate::utils::{indent_of, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::indent_of;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};

View file

@ -1,4 +1,5 @@
use crate::utils::{is_entrypoint_fn, match_def_path, paths, span_lint}; use clippy_utils::diagnostics::span_lint;
use clippy_utils::{is_entrypoint_fn, match_def_path, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,4 +1,5 @@
use crate::utils::{is_expn_of, match_function_call, paths, span_lint, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::{is_expn_of, match_function_call, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,4 +1,6 @@
use crate::utils::{is_expn_of, is_type_diagnostic_item, match_panic_def_id, method_chain_args, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{is_expn_of, match_panic_def_id, method_chain_args};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,4 +1,5 @@
use crate::utils::{match_def_path, paths, span_lint_and_then, sugg}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{match_def_path, paths, sugg};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::util::parser::AssocOp; use rustc_ast::util::parser::AssocOp;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,4 +1,5 @@
use crate::utils::{numeric_literal, span_lint_and_sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::numeric_literal;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_ast::ast::{self, LitFloatType, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -2,7 +2,8 @@ use crate::consts::{
constant, constant_simple, Constant, constant, constant_simple, Constant,
Constant::{Int, F32, F64}, Constant::{Int, F32, F64},
}; };
use crate::utils::{eq_expr_value, get_parent_expr, numeric_literal, span_lint_and_sugg, sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{eq_expr_value, get_parent_expr, numeric_literal, sugg};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp};

View file

@ -1,8 +1,8 @@
use crate::utils::paths; use clippy_utils::diagnostics::span_lint_and_then;
use crate::utils::{ use clippy_utils::paths;
is_expn_of, is_type_diagnostic_item, last_path_segment, match_def_path, match_function_call, snippet, snippet_opt, use clippy_utils::source::{snippet, snippet_opt};
span_lint_and_then, use clippy_utils::ty::is_type_diagnostic_item;
}; use clippy_utils::{is_expn_of, last_path_segment, match_def_path, match_function_call};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,4 +1,6 @@
use crate::utils::{differing_macro_contexts, snippet_opt, span_lint_and_help, span_lint_and_note}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
use clippy_utils::differing_macro_contexts;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp}; use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};

View file

@ -1,5 +1,6 @@
use crate::utils::paths::INTO; use clippy_utils::diagnostics::span_lint_and_help;
use crate::utils::{match_def_path, meets_msrv, span_lint_and_help}; use clippy_utils::paths::INTO;
use clippy_utils::{match_def_path, meets_msrv};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};

View file

@ -1,3 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind}; use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
@ -6,10 +9,6 @@ use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use crate::utils::is_type_diagnostic_item;
use crate::utils::span_lint_and_sugg;
use crate::utils::sugg::Sugg;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** /// **What it does:**
/// Checks for function invocations of the form `primitive::from_str_radix(s, 10)` /// Checks for function invocations of the form `primitive::from_str_radix(s, 10)`

View file

@ -1,7 +1,9 @@
use crate::utils::{ use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_then};
attr_by_name, attrs::is_proc_macro, is_must_use_ty, is_trait_impl_item, is_type_diagnostic_item, iter_input_pats, use clippy_utils::source::{snippet, snippet_opt};
match_def_path, must_use_attr, path_to_local, return_ty, snippet, snippet_opt, span_lint, span_lint_and_help, use clippy_utils::ty::{is_must_use_ty, is_type_diagnostic_item, type_is_unsafe_function};
span_lint_and_then, trait_ref_of_method, type_is_unsafe_function, use clippy_utils::{
attr_by_name, attrs::is_proc_macro, is_trait_impl_item, iter_input_pats, match_def_path, must_use_attr,
path_to_local, return_ty, trait_ref_of_method,
}; };
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;

View file

@ -1,4 +1,5 @@
use crate::utils; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::return_ty;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, HirId}; use rustc_hir::{Body, FnDecl, HirId};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -61,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
if let FnKind::Closure = kind { if let FnKind::Closure = kind {
return; return;
} }
let ret_ty = utils::return_ty(cx, hir_id); let ret_ty = return_ty(cx, hir_id);
if let Opaque(id, subst) = *ret_ty.kind() { if let Opaque(id, subst) = *ret_ty.kind() {
let preds = cx.tcx.explicit_item_bounds(id); let preds = cx.tcx.explicit_item_bounds(id);
let mut is_future = false; let mut is_future = false;
@ -84,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
fulfillment_cx.select_all_or_error(&infcx) fulfillment_cx.select_all_or_error(&infcx)
}); });
if let Err(send_errors) = send_result { if let Err(send_errors) = send_result {
utils::span_lint_and_then( span_lint_and_then(
cx, cx,
FUTURE_NOT_SEND, FUTURE_NOT_SEND,
span, span,

View file

@ -1,6 +1,9 @@
//! lint on using `x.get(x.len() - 1)` instead of `x.last()` //! lint on using `x.get(x.len() - 1)` instead of `x.last()`
use crate::utils::{is_type_diagnostic_item, snippet_with_applicability, span_lint_and_sugg, SpanlessEq}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::SpanlessEq;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,3 +1,4 @@
use clippy_utils::source::snippet;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -6,7 +7,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use crate::consts::{constant_simple, Constant}; use crate::consts::{constant_simple, Constant};
use crate::utils::{clip, snippet, span_lint, unsext}; use clippy_utils::diagnostics::span_lint;
use clippy_utils::{clip, unsext};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for identity operations, e.g., `x + 0`. /// **What it does:** Checks for identity operations, e.g., `x + 0`.

View file

@ -1,4 +1,6 @@
use crate::utils::{is_type_diagnostic_item, span_lint_and_help, SpanlessEq}; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::SpanlessEq;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::intravisit::{self as visit, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self as visit, NestedVisitorMap, Visitor};
use rustc_hir::{Expr, ExprKind, MatchSource}; use rustc_hir::{Expr, ExprKind, MatchSource};

View file

@ -1,4 +1,7 @@
use crate::utils::{is_type_diagnostic_item, method_chain_args, snippet_with_applicability, span_lint_and_sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::method_chain_args;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, MatchSource, PatKind, QPath}; use rustc_hir::{Expr, ExprKind, MatchSource, PatKind, QPath};

View file

@ -1,13 +1,12 @@
//! lint on if branches that could be swapped so no `!` operation is necessary //! lint on if branches that could be swapped so no `!` operation is necessary
//! on the condition //! on the condition
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_ast::ast::{BinOpKind, Expr, ExprKind, UnOp};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::span_lint_and_help;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an /// **What it does:** Checks for usage of `!` or `!=` in an if condition with an
/// else branch. /// else branch.

View file

@ -0,0 +1,117 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::{match_qpath, meets_msrv, parent_node_is_if_expr};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
const IF_THEN_SOME_ELSE_NONE_MSRV: RustcVersion = RustcVersion::new(1, 50, 0);
declare_clippy_lint! {
/// **What it does:** Checks for if-else that could be written to `bool::then`.
///
/// **Why is this bad?** Looks a little redundant. Using `bool::then` helps it have less lines of code.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// # let v = vec![0];
/// let a = if v.is_empty() {
/// println!("true!");
/// Some(42)
/// } else {
/// None
/// };
/// ```
///
/// Could be written:
///
/// ```rust
/// # let v = vec![0];
/// let a = v.is_empty().then(|| {
/// println!("true!");
/// 42
/// });
/// ```
pub IF_THEN_SOME_ELSE_NONE,
restriction,
"Finds if-else that could be written using `bool::then`"
}
pub struct IfThenSomeElseNone {
msrv: Option<RustcVersion>,
}
impl IfThenSomeElseNone {
#[must_use]
pub fn new(msrv: Option<RustcVersion>) -> Self {
Self { msrv }
}
}
impl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);
impl LateLintPass<'_> for IfThenSomeElseNone {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) {
if !meets_msrv(self.msrv.as_ref(), &IF_THEN_SOME_ELSE_NONE_MSRV) {
return;
}
if in_external_macro(cx.sess(), expr.span) {
return;
}
// We only care about the top-most `if` in the chain
if parent_node_is_if_expr(expr, cx) {
return;
}
if_chain! {
if let ExprKind::If(ref cond, ref then, Some(ref els)) = expr.kind;
if let ExprKind::Block(ref then_block, _) = then.kind;
if let Some(ref then_expr) = then_block.expr;
if let ExprKind::Call(ref then_call, [then_arg]) = then_expr.kind;
if let ExprKind::Path(ref then_call_qpath) = then_call.kind;
if match_qpath(then_call_qpath, &clippy_utils::paths::OPTION_SOME);
if let ExprKind::Block(ref els_block, _) = els.kind;
if els_block.stmts.is_empty();
if let Some(ref els_expr) = els_block.expr;
if let ExprKind::Path(ref els_call_qpath) = els_expr.kind;
if match_qpath(els_call_qpath, &clippy_utils::paths::OPTION_NONE);
then {
let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");
let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
format!("({})", cond_snip)
} else {
cond_snip.into_owned()
};
let arg_snip = snippet_with_macro_callsite(cx, then_arg.span, "");
let closure_body = if then_block.stmts.is_empty() {
arg_snip.into_owned()
} else {
format!("{{ /* snippet */ {} }}", arg_snip)
};
let help = format!(
"consider using `bool::then` like: `{}.then(|| {})`",
cond_snip,
closure_body,
);
span_lint_and_help(
cx,
IF_THEN_SOME_ELSE_NONE,
expr.span,
"this could be simplified with `bool::then`",
None,
&help,
);
}
}
}
extract_msrv_attr!(LateContext);
}

View file

@ -1,4 +1,6 @@
use crate::utils::{match_panic_def_id, snippet_opt, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::match_panic_def_id;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;

View file

@ -1,4 +1,5 @@
use crate::utils::{in_macro, match_qpath, span_lint_and_sugg, SpanlessEq}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{in_macro, match_qpath, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View file

@ -1,3 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{self as hir, ExprKind}; use rustc_hir::{self as hir, ExprKind};
@ -5,13 +8,10 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use if_chain::if_chain;
use crate::utils::{snippet, span_lint_and_sugg};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for struct constructors where the order of the field init /// **What it does:** Checks for struct constructors where all fields are shorthand and
/// shorthand in the constructor is inconsistent with the order in the struct definition. /// the order of the field init shorthand in the constructor is inconsistent
/// with the order in the struct definition.
/// ///
/// **Why is this bad?** Since the order of fields in a constructor doesn't affect the /// **Why is this bad?** Since the order of fields in a constructor doesn't affect the
/// resulted instance as the below example indicates, /// resulted instance as the below example indicates,
@ -25,11 +25,11 @@ declare_clippy_lint! {
/// let x = 1; /// let x = 1;
/// let y = 2; /// let y = 2;
/// ///
/// // This assertion never fails. /// // This assertion never fails:
/// assert_eq!(Foo { x, y }, Foo { y, x }); /// assert_eq!(Foo { x, y }, Foo { y, x });
/// ``` /// ```
/// ///
/// inconsistent order means nothing and just decreases readability and consistency. /// inconsistent order can be confusing and decreases readability and consistency.
/// ///
/// **Known problems:** None. /// **Known problems:** None.
/// ///
@ -42,6 +42,7 @@ declare_clippy_lint! {
/// } /// }
/// let x = 1; /// let x = 1;
/// let y = 2; /// let y = 2;
///
/// Foo { y, x }; /// Foo { y, x };
/// ``` /// ```
/// ///
@ -107,7 +108,7 @@ impl LateLintPass<'_> for InconsistentStructConstructor {
cx, cx,
INCONSISTENT_STRUCT_CONSTRUCTOR, INCONSISTENT_STRUCT_CONSTRUCTOR,
expr.span, expr.span,
"inconsistent struct constructor", "struct constructor field order is inconsistent with struct definition field order",
"try", "try",
sugg, sugg,
Applicability::MachineApplicable, Applicability::MachineApplicable,

View file

@ -1,7 +1,8 @@
//! lint on indexing and slicing operations //! lint on indexing and slicing operations
use crate::consts::{constant, Constant}; use crate::consts::{constant, Constant};
use crate::utils::{higher, span_lint, span_lint_and_help}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
use clippy_utils::higher;
use rustc_ast::ast::RangeLimits; use rustc_ast::ast::RangeLimits;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::{implements_trait, match_type};
use clippy_utils::{get_trait_def_id, higher, match_qpath, paths};
use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_hir::{BorrowKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, match_type, paths, span_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for iteration that is guaranteed to be infinite. /// **What it does:** Checks for iteration that is guaranteed to be infinite.
/// ///

View file

@ -1,6 +1,7 @@
//! lint on inherent implementations //! lint on inherent implementations
use crate::utils::{in_macro, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::in_macro;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{def_id, Crate, Impl, Item, ItemKind}; use rustc_hir::{def_id, Crate, Impl, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,14 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{ImplItem, ImplItemKind}; use rustc_hir::{ImplItem, ImplItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
use crate::utils::{
get_trait_def_id, implements_trait, is_type_diagnostic_item, paths, return_ty, span_lint_and_help,
trait_ref_of_method,
};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`. /// **What it does:** Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.
/// ///

View file

@ -1,7 +1,7 @@
//! checks for `#[inline]` on trait methods without bodies //! checks for `#[inline]` on trait methods without bodies
use crate::utils::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use crate::utils::sugg::DiagnosticBuilderExt; use clippy_utils::sugg::DiagnosticBuilderExt;
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{TraitFn, TraitItem, TraitItemKind}; use rustc_hir::{TraitFn, TraitItem, TraitItemKind};

View file

@ -1,12 +1,12 @@
//! lint on blocks unnecessarily using >= with a + 1 or - 1 //! lint on blocks unnecessarily using >= with a + 1 or - 1
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, Lit, LitKind}; use rustc_ast::ast::{BinOpKind, Expr, ExprKind, Lit, LitKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use crate::utils::{snippet_opt, span_lint_and_sugg};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block /// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
/// ///

View file

@ -1,4 +1,4 @@
use crate::utils::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,6 +1,6 @@
//! lint when items are used after statements //! lint when items are used after statements
use crate::utils::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_ast::ast::{Block, ItemKind, StmtKind}; use rustc_ast::ast::{Block, ItemKind, StmtKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;

View file

@ -1,5 +1,5 @@
use crate::rustc_target::abi::LayoutOf; use crate::rustc_target::abi::LayoutOf;
use crate::utils::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};

View file

@ -1,6 +1,7 @@
//! lint when there is a large size difference between variants on an enum //! lint when there is a large size difference between variants on an enum
use crate::utils::{snippet_opt, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind, VariantData}; use rustc_hir::{Item, ItemKind, VariantData};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

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