Auto merge of #87579 - flip1995:clippyup, r=Manishearth

Update Clippy

r? `@Manishearth`
This commit is contained in:
bors 2021-07-29 15:36:52 +00:00
commit a985d8e6c7
284 changed files with 3439 additions and 3116 deletions

View File

@ -542,7 +542,7 @@ dependencies = [
[[package]] [[package]]
name = "clippy" name = "clippy"
version = "0.1.55" version = "0.1.56"
dependencies = [ dependencies = [
"cargo_metadata 0.12.0", "cargo_metadata 0.12.0",
"clippy_lints", "clippy_lints",
@ -575,7 +575,7 @@ dependencies = [
[[package]] [[package]]
name = "clippy_lints" name = "clippy_lints"
version = "0.1.55" version = "0.1.56"
dependencies = [ dependencies = [
"cargo_metadata 0.12.0", "cargo_metadata 0.12.0",
"clippy_utils", "clippy_utils",
@ -596,7 +596,7 @@ dependencies = [
[[package]] [[package]]
name = "clippy_utils" name = "clippy_utils"
version = "0.1.55" version = "0.1.56"
dependencies = [ dependencies = [
"if_chain", "if_chain",
"itertools 0.9.0", "itertools 0.9.0",

View File

@ -8,13 +8,12 @@ rm -rf out/master/ || exit 0
echo "Making the docs for master" echo "Making the docs for master"
mkdir out/master/ mkdir out/master/
cp util/gh-pages/index.html out/master cp util/gh-pages/index.html out/master
python3 ./util/export.py out/master/lints.json cp util/gh-pages/lints.json out/master
if [[ -n $TAG_NAME ]]; then if [[ -n $TAG_NAME ]]; then
echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it" echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it"
cp -r out/master "out/$TAG_NAME" cp -Tr out/master "out/$TAG_NAME"
rm -f out/stable ln -sf "$TAG_NAME" out/stable
ln -s "$TAG_NAME" out/stable
fi fi
if [[ $BETA = "true" ]]; then if [[ $BETA = "true" ]]; then
@ -28,8 +27,8 @@ cp util/gh-pages/versions.html out/index.html
echo "Making the versions.json file" echo "Making the versions.json file"
python3 ./util/versions.py out python3 ./util/versions.py out
cd out
# Now let's go have some fun with the cloned repo # Now let's go have some fun with the cloned repo
cd out
git config user.name "GHA CI" git config user.name "GHA CI"
git config user.email "gha@ci.invalid" git config user.email "gha@ci.invalid"

View File

@ -39,10 +39,23 @@ jobs:
if: github.ref == 'refs/heads/beta' if: github.ref == 'refs/heads/beta'
run: echo "BETA=true" >> $GITHUB_ENV run: echo "BETA=true" >> $GITHUB_ENV
- name: Use scripts and templates from master branch # We need to check out all files that (transitively) depend on the
# structure of the gh-pages branch, so that we're able to change that
# structure without breaking the deployment.
- name: Use deploy files from master branch
run: | run: |
git fetch --no-tags --prune --depth=1 origin master git fetch --no-tags --prune --depth=1 origin master
git checkout origin/master -- .github/deploy.sh util/gh-pages/ util/*.py git checkout origin/master -- .github/deploy.sh util/versions.py util/gh-pages/versions.html
# Generate lockfile for caching to avoid build problems with cached deps
- name: cargo generate-lockfile
run: cargo generate-lockfile
- name: Cache
uses: Swatinem/rust-cache@v1.3.0
- name: cargo collect-metadata
run: cargo collect-metadata
- name: Deploy - name: Deploy
run: | run: |

View File

@ -2423,7 +2423,6 @@ Released 2018-09-13
<!-- begin autogenerated links to lint list --> <!-- begin autogenerated links to lint list -->
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons [`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped [`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
[`append_instead_of_extend`]: https://rust-lang.github.io/rust-clippy/master/index.html#append_instead_of_extend
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant [`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants [`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
@ -2522,6 +2521,7 @@ Released 2018-09-13
[`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop [`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop
[`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write [`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write
[`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_from_slice [`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_from_slice
[`extend_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_with_drain
[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes [`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from [`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from
[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default [`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
@ -2772,7 +2772,7 @@ Released 2018-09-13
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push [`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some [`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment [`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
[`self_named_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructor [`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned [`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse [`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse [`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse

View File

@ -1,6 +1,6 @@
[package] [package]
name = "clippy" name = "clippy"
version = "0.1.55" version = "0.1.56"
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"

View File

@ -169,14 +169,11 @@ use rustc_session::{{declare_lint_pass, declare_tool_lint}};
{pass_import} {pass_import}
declare_clippy_lint! {{ declare_clippy_lint! {{
/// **What it does:** /// ### What it does
/// ///
/// **Why is this bad?** /// ### Why is this bad?
///
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// // example code where clippy issues a warning /// // example code where clippy issues a warning
/// ``` /// ```

View File

@ -15,8 +15,8 @@ pub fn run(port: u16, lint: Option<&str>) -> ! {
loop { loop {
if mtime("util/gh-pages/lints.json") < mtime("clippy_lints/src") { if mtime("util/gh-pages/lints.json") < mtime("clippy_lints/src") {
Command::new("python3") Command::new("cargo")
.arg("util/export.py") .arg("collect-metadata")
.spawn() .spawn()
.unwrap() .unwrap()
.wait() .wait()

View File

@ -1,7 +1,7 @@
[package] [package]
name = "clippy_lints" name = "clippy_lints"
# begin automatic update # begin automatic update
version = "0.1.55" version = "0.1.56"
# 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"

View File

@ -11,24 +11,26 @@ use clippy_utils::ty::is_isize_or_usize;
use clippy_utils::{clip, int_bits, unsext}; use clippy_utils::{clip, int_bits, unsext};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for comparisons where one side of the relation is /// ### What it does
/// Checks for comparisons where one side of the relation is
/// either the minimum or maximum value for its type and warns if it involves a /// either the minimum or maximum value for its type and warns if it involves a
/// case that is always true or always false. Only integer and boolean types are /// case that is always true or always false. Only integer and boolean types are
/// checked. /// checked.
/// ///
/// **Why is this bad?** An expression like `min <= x` may misleadingly imply /// ### Why is this bad?
/// An expression like `min <= x` may misleadingly imply
/// that it is possible for `x` to be less than the minimum. Expressions like /// that it is possible for `x` to be less than the minimum. Expressions like
/// `max < x` are probably mistakes. /// `max < x` are probably mistakes.
/// ///
/// **Known problems:** For `usize` the size of the current compile target will /// ### Known problems
/// For `usize` the size of the current compile target will
/// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such /// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
/// a comparison to detect target pointer width will trigger this lint. One can /// a comparison to detect target pointer width will trigger this lint. One can
/// use `mem::sizeof` and compare its value or conditional compilation /// use `mem::sizeof` and compare its value or conditional compilation
/// attributes /// attributes
/// like `#[cfg(target_pointer_width = "64")] ..` instead. /// like `#[cfg(target_pointer_width = "64")] ..` instead.
/// ///
/// **Example:** /// ### Example
///
/// ```rust /// ```rust
/// let vec: Vec<isize> = Vec::new(); /// let vec: Vec<isize> = Vec::new();
/// if vec.len() <= 0 {} /// if vec.len() <= 0 {}

View File

@ -7,21 +7,21 @@ use rustc_span::symbol;
use std::f64::consts as f64; use std::f64::consts as f64;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for floating point literals that approximate /// ### What it does
/// Checks for floating point literals that approximate
/// constants which are defined in /// constants which are defined in
/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
/// or /// or
/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
/// respectively, suggesting to use the predefined constant. /// respectively, suggesting to use the predefined constant.
/// ///
/// **Why is this bad?** Usually, the definition in the standard library is more /// ### Why is this bad?
/// Usually, the definition in the standard library is more
/// precise than what people come up with. If you find that your definition is /// precise than what people come up with. If you find that your definition is
/// actually more precise, please [file a Rust /// actually more precise, please [file a Rust
/// issue](https://github.com/rust-lang/rust/issues). /// issue](https://github.com/rust-lang/rust/issues).
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x = 3.14; /// let x = 3.14;
/// let y = 1_f64 / x; /// let y = 1_f64 / x;

View File

@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for integer arithmetic operations which could overflow or panic. /// ### What it does
/// Checks for integer arithmetic operations which could overflow or panic.
/// ///
/// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable /// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
/// of overflowing according to the [Rust /// of overflowing according to the [Rust
@ -14,13 +15,12 @@ declare_clippy_lint! {
/// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is /// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
/// attempted. /// attempted.
/// ///
/// **Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in /// ### Why is this bad?
/// Integer overflow will trigger a panic in debug builds or will wrap in
/// release mode. Division by zero will cause a panic in either mode. In some applications one /// release mode. Division by zero will cause a panic in either mode. In some applications one
/// wants explicitly checked, wrapping or saturating arithmetic. /// wants explicitly checked, wrapping or saturating arithmetic.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let a = 0; /// # let a = 0;
/// a + 1; /// a + 1;
@ -31,14 +31,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for float arithmetic. /// ### What it does
/// Checks for float arithmetic.
/// ///
/// **Why is this bad?** For some embedded systems or kernel development, it /// ### Why is this bad?
/// For some embedded systems or kernel development, it
/// can be useful to rule out floating-point numbers. /// can be useful to rule out floating-point numbers.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let a = 0.0; /// # let a = 0.0;
/// a + 1.0; /// a + 1.0;

View File

@ -5,7 +5,8 @@ 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};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `as` conversions. /// ### What it does
/// Checks for usage of `as` conversions.
/// ///
/// Note that this lint is specialized in linting *every single* use of `as` /// Note that this lint is specialized in linting *every single* use of `as`
/// regardless of whether good alternatives exist or not. /// regardless of whether good alternatives exist or not.
@ -15,14 +16,13 @@ declare_clippy_lint! {
/// There is a good explanation the reason why this lint should work in this way and how it is useful /// There is a good explanation the reason why this lint should work in this way and how it is useful
/// [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122). /// [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).
/// ///
/// **Why is this bad?** `as` conversions will perform many kinds of /// ### Why is this bad?
/// `as` conversions will perform many kinds of
/// conversions, including silently lossy conversions and dangerous coercions. /// conversions, including silently lossy conversions and dangerous coercions.
/// There are cases when it makes sense to use `as`, so the lint is /// There are cases when it makes sense to use `as`, so the lint is
/// Allow by default. /// Allow by default.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// let a: u32; /// let a: u32;
/// ... /// ...

View File

@ -53,14 +53,14 @@ fn check_expr_asm_syntax(lint: &'static Lint, cx: &EarlyContext<'_>, expr: &Expr
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of Intel x86 assembly syntax. /// ### What it does
/// Checks for usage of Intel x86 assembly syntax.
/// ///
/// **Why is this bad?** The lint has been enabled to indicate a preference /// ### Why is this bad?
/// The lint has been enabled to indicate a preference
/// for AT&T x86 assembly syntax. /// for AT&T x86 assembly syntax.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # #![feature(asm)] /// # #![feature(asm)]
@ -89,14 +89,14 @@ impl EarlyLintPass for InlineAsmX86IntelSyntax {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of AT&T x86 assembly syntax. /// ### What it does
/// Checks for usage of AT&T x86 assembly syntax.
/// ///
/// **Why is this bad?** The lint has been enabled to indicate a preference /// ### Why is this bad?
/// The lint has been enabled to indicate a preference
/// for Intel x86 assembly syntax. /// for Intel x86 assembly syntax.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # #![feature(asm)] /// # #![feature(asm)]

View File

@ -8,14 +8,17 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls. /// ### What it does
/// Checks for `assert!(true)` and `assert!(false)` calls.
/// ///
/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a /// ### Why is this bad?
/// Will be optimized out by the compiler or should probably be replaced by a
/// `panic!()` or `unreachable!()` /// `panic!()` or `unreachable!()`
/// ///
/// **Known problems:** None /// ### Known problems
/// None
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// assert!(false) /// assert!(false)
/// assert!(true) /// assert!(true)

View File

@ -12,15 +12,18 @@ use rustc_middle::hir::map::Map;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a` /// ### What it does
/// Checks for `a = a op b` or `a = b commutative_op a`
/// patterns. /// patterns.
/// ///
/// **Why is this bad?** These can be written as the shorter `a op= b`. /// ### Why is this bad?
/// These can be written as the shorter `a op= b`.
/// ///
/// **Known problems:** While forbidden by the spec, `OpAssign` traits may have /// ### Known problems
/// While forbidden by the spec, `OpAssign` traits may have
/// implementations that differ from the regular `Op` impl. /// implementations that differ from the regular `Op` impl.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let mut a = 5; /// let mut a = 5;
/// let b = 0; /// let b = 0;
@ -37,17 +40,20 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns. /// ### What it does
/// Checks for `a op= a op b` or `a op= b op a` patterns.
/// ///
/// **Why is this bad?** Most likely these are bugs where one meant to write `a /// ### Why is this bad?
/// Most likely these are bugs where one meant to write `a
/// op= b`. /// op= b`.
/// ///
/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have /// ### Known problems
/// Clippy cannot know for sure if `a op= a op b` should have
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both. /// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
/// If `a op= a op b` is really the correct behaviour it should be /// If `a op= a op b` is really the correct behaviour it should be
/// written as `a = a op a op b` as it's less confusing. /// written as `a = a op a op b` as it's less confusing.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let mut a = 5; /// let mut a = 5;
/// let b = 2; /// let b = 2;

View File

@ -7,15 +7,14 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for async blocks that yield values of types /// ### What it does
/// Checks for async blocks that yield values of types
/// that can themselves be awaited. /// that can themselves be awaited.
/// ///
/// **Why is this bad?** An await is likely missing. /// ### Why is this bad?
/// /// An await is likely missing.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// async fn foo() {} /// async fn foo() {}
/// ///

View File

@ -8,16 +8,16 @@ use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of invalid atomic /// ### What it does
/// Checks for usage of invalid atomic
/// ordering in atomic loads/stores/exchanges/updates and /// ordering in atomic loads/stores/exchanges/updates and
/// memory fences. /// memory fences.
/// ///
/// **Why is this bad?** Using an invalid atomic ordering /// ### Why is this bad?
/// Using an invalid atomic ordering
/// will cause a panic at run-time. /// will cause a panic at run-time.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,no_run /// ```rust,no_run
/// # use std::sync::atomic::{self, AtomicU8, Ordering}; /// # use std::sync::atomic::{self, AtomicU8, Ordering};
/// ///

View File

@ -41,10 +41,12 @@ static UNIX_SYSTEMS: &[&str] = &[
static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"]; static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for items annotated with `#[inline(always)]`, /// ### What it does
/// Checks for items annotated with `#[inline(always)]`,
/// unless the annotated function is empty or simply panics. /// unless the annotated function is empty or simply panics.
/// ///
/// **Why is this bad?** While there are valid uses of this annotation (and once /// ### Why is this bad?
/// While there are valid uses of this annotation (and once
/// you know when to use it, by all means `allow` this lint), it's a common /// you know when to use it, by all means `allow` this lint), it's a common
/// newbie-mistake to pepper one's code with it. /// newbie-mistake to pepper one's code with it.
/// ///
@ -52,11 +54,12 @@ declare_clippy_lint! {
/// measure if that additional function call really affects your runtime profile /// measure if that additional function call really affects your runtime profile
/// sufficiently to make up for the increase in compile time. /// sufficiently to make up for the increase in compile time.
/// ///
/// **Known problems:** False positives, big time. This lint is meant to be /// ### Known problems
/// False positives, big time. This lint is meant to be
/// deactivated by everyone doing serious performance work. This means having /// deactivated by everyone doing serious performance work. This means having
/// done the measurement. /// done the measurement.
/// ///
/// **Example:** /// ### Example
/// ```ignore /// ```ignore
/// #[inline(always)] /// #[inline(always)]
/// fn not_quite_hot_code(..) { ... } /// fn not_quite_hot_code(..) { ... }
@ -67,7 +70,8 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `extern crate` and `use` items annotated with /// ### What it does
/// Checks for `extern crate` and `use` items annotated with
/// lint attributes. /// lint attributes.
/// ///
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`, /// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
@ -75,12 +79,11 @@ declare_clippy_lint! {
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on /// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
/// `extern crate` items with a `#[macro_use]` attribute. /// `extern crate` items with a `#[macro_use]` attribute.
/// ///
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most /// ### Why is this bad?
/// Lint attributes have no effect on crate imports. Most
/// likely a `!` was forgotten. /// likely a `!` was forgotten.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// // Bad /// // Bad
/// #[deny(dead_code)] /// #[deny(dead_code)]
@ -101,15 +104,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `#[deprecated]` annotations with a `since` /// ### What it does
/// Checks for `#[deprecated]` annotations with a `since`
/// field that is not a valid semantic version. /// field that is not a valid semantic version.
/// ///
/// **Why is this bad?** For checking the version of the deprecation, it must be /// ### Why is this bad?
/// For checking the version of the deprecation, it must be
/// a valid semver. Failing that, the contained information is useless. /// a valid semver. Failing that, the contained information is useless.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// #[deprecated(since = "forever")] /// #[deprecated(since = "forever")]
/// fn something_else() { /* ... */ } /// fn something_else() { /* ... */ }
@ -120,20 +123,22 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for empty lines after outer attributes /// ### What it does
/// Checks for empty lines after outer attributes
/// ///
/// **Why is this bad?** /// ### Why is this bad?
/// Most likely the attribute was meant to be an inner attribute using a '!'. /// Most likely the attribute was meant to be an inner attribute using a '!'.
/// If it was meant to be an outer attribute, then the following item /// If it was meant to be an outer attribute, then the following item
/// should not be separated by empty lines. /// should not be separated by empty lines.
/// ///
/// **Known problems:** Can cause false positives. /// ### Known problems
/// Can cause false positives.
/// ///
/// From the clippy side it's difficult to detect empty lines between an attributes and the /// From the clippy side it's difficult to detect empty lines between an attributes and the
/// following item because empty lines and comments are not part of the AST. The parsing /// following item because empty lines and comments are not part of the AST. The parsing
/// currently works for basic cases but is not perfect. /// currently works for basic cases but is not perfect.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// // Good (as inner attribute) /// // Good (as inner attribute)
/// #![allow(dead_code)] /// #![allow(dead_code)]
@ -155,14 +160,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category. /// ### What it does
/// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
/// ///
/// **Why is this bad?** Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust. /// ### Why is this bad?
/// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
/// These lints should only be enabled on a lint-by-lint basis and with careful consideration. /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// Bad: /// Bad:
/// ```rust /// ```rust
/// #![deny(clippy::restriction)] /// #![deny(clippy::restriction)]
@ -178,18 +183,20 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it /// ### What it does
/// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
/// with `#[rustfmt::skip]`. /// with `#[rustfmt::skip]`.
/// ///
/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690)) /// ### Why is this bad?
/// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes. /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
/// ///
/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get /// ### Known problems
/// This lint doesn't detect crate level inner attributes, because they get
/// processed before the PreExpansionPass lints get executed. See /// processed before the PreExpansionPass lints get executed. See
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765) /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
/// ///
/// **Example:** /// ### Example
///
/// Bad: /// Bad:
/// ```rust /// ```rust
/// #[cfg_attr(rustfmt, rustfmt_skip)] /// #[cfg_attr(rustfmt, rustfmt_skip)]
@ -207,15 +214,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for cfg attributes having operating systems used in target family position. /// ### What it does
/// Checks for cfg attributes having operating systems used in target family position.
/// ///
/// **Why is this bad?** The configuration option will not be recognised and the related item will not be included /// ### Why is this bad?
/// The configuration option will not be recognised and the related item will not be included
/// by the conditional compilation engine. /// by the conditional compilation engine.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// Bad: /// Bad:
/// ```rust /// ```rust
/// #[cfg(linux)] /// #[cfg(linux)]

View File

@ -8,10 +8,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span; use rustc_span::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to await while holding a /// ### What it does
/// Checks for calls to await while holding a
/// non-async-aware MutexGuard. /// non-async-aware MutexGuard.
/// ///
/// **Why is this bad?** The Mutex types found in std::sync and parking_lot /// ### Why is this bad?
/// The Mutex types found in std::sync and parking_lot
/// are not designed to operate in an async context across await points. /// are not designed to operate in an async context across await points.
/// ///
/// There are two potential solutions. One is to use an asynx-aware Mutex /// There are two potential solutions. One is to use an asynx-aware Mutex
@ -19,10 +21,10 @@ declare_clippy_lint! {
/// other solution is to ensure the mutex is unlocked before calling await, /// other solution is to ensure the mutex is unlocked before calling await,
/// either by introducing a scope or an explicit call to Drop::drop. /// either by introducing a scope or an explicit call to Drop::drop.
/// ///
/// **Known problems:** Will report false positive for explicitly dropped guards ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). /// ### Known problems
/// /// Will report false positive for explicitly dropped guards ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)).
/// **Example:**
/// ///
/// ### Example
/// ```rust,ignore /// ```rust,ignore
/// use std::sync::Mutex; /// use std::sync::Mutex;
/// ///
@ -51,17 +53,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to await while holding a /// ### What it does
/// Checks for calls to await while holding a
/// `RefCell` `Ref` or `RefMut`. /// `RefCell` `Ref` or `RefMut`.
/// ///
/// **Why is this bad?** `RefCell` refs only check for exclusive mutable access /// ### Why is this bad?
/// `RefCell` refs only check for exclusive mutable access
/// at runtime. Holding onto a `RefCell` ref across an `await` suspension point /// at runtime. Holding onto a `RefCell` ref across an `await` suspension point
/// risks panics from a mutable ref shared while other refs are outstanding. /// risks panics from a mutable ref shared while other refs are outstanding.
/// ///
/// **Known problems:** Will report false positive for explicitly dropped refs ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). /// ### Known problems
/// /// Will report false positive for explicitly dropped refs ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)).
/// **Example:**
/// ///
/// ### Example
/// ```rust,ignore /// ```rust,ignore
/// use std::cell::RefCell; /// use std::cell::RefCell;
/// ///

View File

@ -10,7 +10,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for incompatible bit masks in comparisons. /// ### What it does
/// Checks for incompatible bit masks in comparisons.
/// ///
/// The formula for detecting if an expression of the type `_ <bit_op> m /// The formula for detecting if an expression of the type `_ <bit_op> m
/// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of /// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
@ -26,7 +27,8 @@ declare_clippy_lint! {
/// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` | /// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |
/// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` | /// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |
/// ///
/// **Why is this bad?** If the bits that the comparison cares about are always /// ### Why is this bad?
/// If the bits that the comparison cares about are always
/// set to zero or one by the bit mask, the comparison is constant `true` or /// set to zero or one by the bit mask, the comparison is constant `true` or
/// `false` (depending on mask, compared value, and operators). /// `false` (depending on mask, compared value, and operators).
/// ///
@ -34,9 +36,7 @@ declare_clippy_lint! {
/// this intentionally is to win an underhanded Rust contest or create a /// this intentionally is to win an underhanded Rust contest or create a
/// test-case for this lint. /// test-case for this lint.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// if (x & 1 == 2) { } /// if (x & 1 == 2) { }
@ -47,7 +47,8 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for bit masks in comparisons which can be removed /// ### What it does
/// Checks for bit masks in comparisons which can be removed
/// without changing the outcome. The basic structure can be seen in the /// without changing the outcome. The basic structure can be seen in the
/// following table: /// following table:
/// ///
@ -56,16 +57,18 @@ declare_clippy_lint! {
/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`| /// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|
/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`| /// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|
/// ///
/// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask), /// ### Why is this bad?
/// Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
/// but still a bit misleading, because the bit mask is ineffective. /// but still a bit misleading, because the bit mask is ineffective.
/// ///
/// **Known problems:** False negatives: This lint will only match instances /// ### Known problems
/// False negatives: This lint will only match instances
/// where we have figured out the math (which is for a power-of-two compared /// where we have figured out the math (which is for a power-of-two compared
/// value). This means things like `x | 1 >= 7` (which would be better written /// value). This means things like `x | 1 >= 7` (which would be better written
/// as `x >= 6`) will not be reported (but bit masks like this are fairly /// as `x >= 6`) will not be reported (but bit masks like this are fairly
/// uncommon). /// uncommon).
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// if (x | 1 > 3) { } /// if (x | 1 > 3) { }
@ -76,15 +79,18 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for bit masks that can be replaced by a call /// ### What it does
/// Checks for bit masks that can be replaced by a call
/// to `trailing_zeros` /// to `trailing_zeros`
/// ///
/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15 /// ### Why is this bad?
/// `x.trailing_zeros() > 4` is much clearer than `x & 15
/// == 0` /// == 0`
/// ///
/// **Known problems:** llvm generates better code for `x & 15 == 0` on x86 /// ### Known problems
/// llvm generates better code for `x & 15 == 0` on x86
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// if x & 0b1111 == 0 { } /// if x & 0b1111 == 0 { }

View File

@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of blacklisted names for variables, such /// ### What it does
/// Checks for usage of blacklisted names for variables, such
/// as `foo`. /// as `foo`.
/// ///
/// **Why is this bad?** These names are usually placeholder names and should be /// ### Why is this bad?
/// These names are usually placeholder names and should be
/// avoided. /// avoided.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let foo = 3.14; /// let foo = 3.14;
/// ``` /// ```

View File

@ -13,14 +13,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; 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
/// expression, statements or conditions that use closures with blocks. /// expression, statements or conditions that use closures with blocks.
/// ///
/// **Why is this bad?** Style, using blocks in the condition makes it hard to read. /// ### Why is this bad?
/// Style, using blocks in the condition makes it hard to read.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ```rust /// ```rust
/// // Bad /// // Bad
/// if { true } { /* ... */ } /// if { true } { /* ... */ }

View File

@ -6,14 +6,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** This lint warns about boolean comparisons in assert-like macros. /// ### What it does
/// This lint warns about boolean comparisons in assert-like macros.
/// ///
/// **Why is this bad?** It is shorter to use the equivalent. /// ### Why is this bad?
/// /// It is shorter to use the equivalent.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// // Bad /// // Bad
/// assert_eq!("a".is_empty(), false); /// assert_eq!("a".is_empty(), false);

View File

@ -14,16 +14,19 @@ use rustc_span::source_map::Span;
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for boolean expressions that can be written more /// ### What it does
/// Checks for boolean expressions that can be written more
/// concisely. /// concisely.
/// ///
/// **Why is this bad?** Readability of boolean expressions suffers from /// ### Why is this bad?
/// Readability of boolean expressions suffers from
/// unnecessary duplication. /// unnecessary duplication.
/// ///
/// **Known problems:** Ignores short circuiting behavior of `||` and /// ### Known problems
/// Ignores short circuiting behavior of `||` and
/// `&&`. Ignores `|`, `&` and `^`. /// `&&`. Ignores `|`, `&` and `^`.
/// ///
/// **Example:** /// ### Example
/// ```ignore /// ```ignore
/// if a && true // should be: if a /// if a && true // should be: if a
/// if !(a == b) // should be: if a != b /// if !(a == b) // should be: if a != b
@ -34,14 +37,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for boolean expressions that contain terminals that /// ### What it does
/// Checks for boolean expressions that contain terminals that
/// can be eliminated. /// can be eliminated.
/// ///
/// **Why is this bad?** This is most likely a logic bug. /// ### Why is this bad?
/// This is most likely a logic bug.
/// ///
/// **Known problems:** Ignores short circuiting behavior. /// ### Known problems
/// Ignores short circuiting behavior.
/// ///
/// **Example:** /// ### Example
/// ```ignore /// ```ignore
/// if a && b || a { ... } /// if a && b || a { ... }
/// ``` /// ```

View File

@ -12,18 +12,20 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for naive byte counts /// ### What it does
/// Checks for naive byte counts
/// ///
/// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount) /// ### Why is this bad?
/// The [`bytecount`](https://crates.io/crates/bytecount)
/// crate has methods to count your bytes faster, especially for large slices. /// crate has methods to count your bytes faster, especially for large slices.
/// ///
/// **Known problems:** If you have predominantly small slices, the /// ### Known problems
/// If you have predominantly small slices, the
/// `bytecount::count(..)` method may actually be slower. However, if you can /// `bytecount::count(..)` method may actually be slower. However, if you can
/// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
/// faster in those cases. /// faster in those cases.
/// ///
/// **Example:** /// ### Example
///
/// ```rust /// ```rust
/// # let vec = vec![1_u8]; /// # let vec = vec![1_u8];
/// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead /// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead

View File

@ -9,15 +9,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::DUMMY_SP; use rustc_span::source_map::DUMMY_SP;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks to see if all common metadata is defined in /// ### What it does
/// Checks to see if all common metadata is defined in
/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata /// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
/// ///
/// **Why is this bad?** It will be more difficult for users to discover the /// ### Why is this bad?
/// It will be more difficult for users to discover the
/// purpose of the crate, and key information related to it. /// purpose of the crate, and key information related to it.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```toml /// ```toml
/// # This `Cargo.toml` is missing a description field: /// # This `Cargo.toml` is missing a description field:
/// [package] /// [package]

View File

@ -8,17 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{source_map::Spanned, symbol::sym, Span}; use rustc_span::{source_map::Spanned, symbol::sym, Span};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** /// ### What it does
/// Checks for calls to `ends_with` with possible file extensions /// Checks for calls to `ends_with` with possible file extensions
/// and suggests to use a case-insensitive approach instead. /// and suggests to use a case-insensitive approach instead.
/// ///
/// **Why is this bad?** /// ### Why is this bad?
/// `ends_with` is case-sensitive and may not detect files with a valid extension. /// `ends_with` is case-sensitive and may not detect files with a valid extension.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// fn is_rust_file(filename: &str) -> bool { /// fn is_rust_file(filename: &str) -> bool {
/// filename.ends_with(".rs") /// filename.ends_with(".rs")

View File

@ -20,7 +20,8 @@ use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
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
/// rounding errors. This possible rounding is to be expected, so this lint is /// rounding errors. This possible rounding is to be expected, so this lint is
/// `Allow` by default. /// `Allow` by default.
@ -28,13 +29,12 @@ declare_clippy_lint! {
/// Basically, this warns on casting any integer with 32 or more bits to `f32` /// Basically, this warns on casting any integer with 32 or more bits to `f32`
/// or any 64-bit integer to `f64`. /// or any 64-bit integer to `f64`.
/// ///
/// **Why is this bad?** It's not bad at all. But in some applications it can be /// ### Why is this bad?
/// It's not bad at all. But in some applications it can be
/// helpful to know where precision loss can take place. This lint can help find /// helpful to know where precision loss can take place. This lint can help find
/// those places in the code. /// those places in the code.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x = u64::MAX; /// let x = u64::MAX;
/// x as f64; /// x as f64;
@ -45,17 +45,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts from a signed to an unsigned numerical /// ### What it does
/// Checks for casts from a signed to an unsigned numerical
/// type. In this case, negative values wrap around to large positive values, /// type. In this case, negative values wrap around to large positive values,
/// which can be quite surprising in practice. However, as the cast works as /// which can be quite surprising in practice. However, as the cast works as
/// defined, this lint is `Allow` by default. /// defined, this lint is `Allow` by default.
/// ///
/// **Why is this bad?** Possibly surprising results. You can activate this lint /// ### Why is this bad?
/// Possibly surprising results. You can activate this lint
/// as a one-time check to see where numerical wrapping can arise. /// as a one-time check to see where numerical wrapping can arise.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let y: i8 = -1; /// let y: i8 = -1;
/// y as u128; // will return 18446744073709551615 /// y as u128; // will return 18446744073709551615
@ -66,17 +66,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts between numerical types that may /// ### What it does
/// Checks for casts between numerical types that may
/// truncate large values. This is expected behavior, so the cast is `Allow` by /// truncate large values. This is expected behavior, so the cast is `Allow` by
/// default. /// default.
/// ///
/// **Why is this bad?** In some problem domains, it is good practice to avoid /// ### Why is this bad?
/// In some problem domains, it is good practice to avoid
/// truncation. This lint can be activated to help assess where additional /// truncation. This lint can be activated to help assess where additional
/// checks could be beneficial. /// checks could be beneficial.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// fn as_u8(x: u64) -> u8 { /// fn as_u8(x: u64) -> u8 {
/// x as u8 /// x as u8
@ -88,20 +88,20 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts from an unsigned type to a signed type of /// ### What it does
/// Checks for casts from an unsigned type to a signed type of
/// the same size. Performing such a cast is a 'no-op' for the compiler, /// the same size. Performing such a cast is a 'no-op' for the compiler,
/// i.e., nothing is changed at the bit level, and the binary representation of /// i.e., nothing is changed at the bit level, and the binary representation of
/// the value is reinterpreted. This can cause wrapping if the value is too big /// the value is reinterpreted. This can cause wrapping if the value is too big
/// for the target signed type. However, the cast works as defined, so this lint /// for the target signed type. However, the cast works as defined, so this lint
/// is `Allow` by default. /// is `Allow` by default.
/// ///
/// **Why is this bad?** While such a cast is not bad in itself, the results can /// ### Why is this bad?
/// While such a cast is not bad in itself, the results can
/// be surprising when this is not the intended behavior, as demonstrated by the /// be surprising when this is not the intended behavior, as demonstrated by the
/// example below. /// example below.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// u32::MAX as i32; // will yield a value of `-1` /// u32::MAX as i32; // will yield a value of `-1`
/// ``` /// ```
@ -111,19 +111,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts between numerical types that may /// ### What it does
/// Checks for casts between numerical types that may
/// be replaced by safe conversion functions. /// be replaced by safe conversion functions.
/// ///
/// **Why is this bad?** Rust's `as` keyword will perform many kinds of /// ### Why is this bad?
/// Rust's `as` keyword will perform many kinds of
/// conversions, including silently lossy conversions. Conversion functions such /// conversions, including silently lossy conversions. Conversion functions such
/// as `i32::from` will only perform lossless conversions. Using the conversion /// as `i32::from` will only perform lossless conversions. Using the conversion
/// functions prevents conversions from turning into silent lossy conversions if /// functions prevents conversions from turning into silent lossy conversions if
/// the types of the input expressions ever change, and make it easier for /// the types of the input expressions ever change, and make it easier for
/// people reading the code to know that the conversion is lossless. /// people reading the code to know that the conversion is lossless.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// fn as_u64(x: u8) -> u64 { /// fn as_u64(x: u8) -> u64 {
/// x as u64 /// x as u64
@ -143,14 +143,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts to the same type, casts of int literals to integer types /// ### What it does
/// Checks for casts to the same type, casts of int literals to integer types
/// and casts of float literals to float types. /// and casts of float literals to float types.
/// ///
/// **Why is this bad?** It's just unnecessary. /// ### Why is this bad?
/// It's just unnecessary.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let _ = 2i32 as i32; /// let _ = 2i32 as i32;
/// let _ = 0.5 as f32; /// let _ = 0.5 as f32;
@ -168,17 +168,20 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts, using `as` or `pointer::cast`, /// ### What it does
/// Checks for casts, using `as` or `pointer::cast`,
/// from a less-strictly-aligned pointer to a more-strictly-aligned pointer /// from a less-strictly-aligned pointer to a more-strictly-aligned pointer
/// ///
/// **Why is this bad?** Dereferencing the resulting pointer may be undefined /// ### Why is this bad?
/// Dereferencing the resulting pointer may be undefined
/// behavior. /// behavior.
/// ///
/// **Known problems:** Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar /// ### Known problems
/// Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
/// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like /// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like
/// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. /// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let _ = (&1u8 as *const u8) as *const u16; /// let _ = (&1u8 as *const u8) as *const u16;
/// let _ = (&mut 1u8 as *mut u8) as *mut u16; /// let _ = (&mut 1u8 as *mut u8) as *mut u16;
@ -192,9 +195,10 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts of function pointers to something other than usize /// ### What it does
/// Checks for casts of function pointers to something other than usize
/// ///
/// **Why is this bad?** /// ### Why is this bad?
/// Casting a function pointer to anything other than usize/isize is not portable across /// Casting a function pointer to anything other than usize/isize is not portable across
/// architectures, because you end up losing bits if the target type is too small or end up with a /// architectures, because you end up losing bits if the target type is too small or end up with a
/// bunch of extra bits that waste space and add more instructions to the final binary than /// bunch of extra bits that waste space and add more instructions to the final binary than
@ -202,8 +206,7 @@ declare_clippy_lint! {
/// ///
/// Casting to isize also doesn't make sense since there are no signed addresses. /// Casting to isize also doesn't make sense since there are no signed addresses.
/// ///
/// **Example** /// ### Example
///
/// ```rust /// ```rust
/// // Bad /// // Bad
/// fn fun() -> i32 { 1 } /// fn fun() -> i32 { 1 }
@ -219,16 +222,16 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to /// ### What it does
/// Checks for casts of a function pointer to a numeric type not wide enough to
/// store address. /// store address.
/// ///
/// **Why is this bad?** /// ### Why is this bad?
/// Such a cast discards some bits of the function's address. If this is intended, it would be more /// Such a cast discards some bits of the function's address. If this is intended, it would be more
/// clearly expressed by casting to usize first, then casting the usize to the intended type (with /// clearly expressed by casting to usize first, then casting the usize to the intended type (with
/// a comment) to perform the truncation. /// a comment) to perform the truncation.
/// ///
/// **Example** /// ### Example
///
/// ```rust /// ```rust
/// // Bad /// // Bad
/// fn fn1() -> i16 { /// fn fn1() -> i16 {
@ -249,15 +252,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. /// ### What it does
/// Checks for casts of `&T` to `&mut T` anywhere in the code.
/// ///
/// **Why is this bad?** Its basically guaranteed to be undefined behaviour. /// ### Why is this bad?
/// Its basically guaranteed to be undefined behaviour.
/// `UnsafeCell` is the only way to obtain aliasable data that is considered /// `UnsafeCell` is the only way to obtain aliasable data that is considered
/// mutable. /// mutable.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// fn x(r: &i32) { /// fn x(r: &i32) {
/// unsafe { /// unsafe {
@ -283,18 +286,18 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for expressions where a character literal is cast /// ### What it does
/// Checks for expressions where a character literal is cast
/// to `u8` and suggests using a byte literal instead. /// to `u8` and suggests using a byte literal instead.
/// ///
/// **Why is this bad?** In general, casting values to smaller types is /// ### Why is this bad?
/// In general, casting values to smaller types is
/// error-prone and should be avoided where possible. In the particular case of /// error-prone and should be avoided where possible. In the particular case of
/// converting a character literal to u8, it is easy to avoid by just using a /// converting a character literal to u8, it is easy to avoid by just using a
/// byte literal instead. As an added bonus, `b'a'` is even slightly shorter /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter
/// than `'a' as u8`. /// than `'a' as u8`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// 'x' as u8 /// 'x' as u8
/// ``` /// ```
@ -310,18 +313,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** /// ### What it does
/// Checks for `as` casts between raw pointers without changing its mutability, /// Checks for `as` casts between raw pointers without changing its mutability,
/// namely `*const T` to `*const U` and `*mut T` to `*mut U`. /// namely `*const T` to `*const U` and `*mut T` to `*mut U`.
/// ///
/// **Why is this bad?** /// ### Why is this bad?
/// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because /// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// let ptr: *const u32 = &42_u32; /// let ptr: *const u32 = &42_u32;
/// let mut_ptr: *mut u32 = &mut 42_u32; /// let mut_ptr: *mut u32 = &mut 42_u32;

View File

@ -13,13 +13,13 @@ use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for explicit bounds checking when casting. /// ### What it does
/// Checks for explicit bounds checking when casting.
/// ///
/// **Why is this bad?** Reduces the readability of statements & is error prone. /// ### Why is this bad?
/// Reduces the readability of statements & is error prone.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let foo: u32 = 5; /// # let foo: u32 = 5;
/// # let _ = /// # let _ =

View File

@ -14,15 +14,19 @@ use rustc_span::source_map::Span;
use rustc_span::{sym, BytePos}; use rustc_span::{sym, BytePos};
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.
/// ///
/// **Why is this bad?** Methods of high cognitive complexity tend to be hard to /// ### Why is this bad?
/// Methods of high cognitive complexity tend to be hard to
/// both read and maintain. Also LLVM will tend to optimize small methods better. /// both read and maintain. Also LLVM will tend to optimize small methods better.
/// ///
/// **Known problems:** Sometimes it's hard to find a way to reduce the /// ### Known problems
/// Sometimes it's hard to find a way to reduce the
/// complexity. /// complexity.
/// ///
/// **Example:** No. You'll see it when you get the warning. /// ### Example
/// No. You'll see it when you get the warning.
pub COGNITIVE_COMPLEXITY, pub COGNITIVE_COMPLEXITY,
nursery, nursery,
"functions that should be split up into multiple functions" "functions that should be split up into multiple functions"

View File

@ -22,15 +22,15 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
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.
/// ///
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which /// ### Why is this bad?
/// Each `if`-statement adds one level of nesting, which
/// makes code look more complex than it really is. /// makes code look more complex than it really is.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// if x { /// if x {
/// if y { /// if y {
@ -53,15 +53,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for collapsible `else { if ... }` expressions /// ### What it does
/// Checks for collapsible `else { if ... }` expressions
/// that can be collapsed to `else if ...`. /// that can be collapsed to `else if ...`.
/// ///
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which /// ### Why is this bad?
/// Each `if`-statement adds one level of nesting, which
/// makes code look more complex than it really is. /// makes code look more complex than it really is.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// ///
/// if x { /// if x {

View File

@ -9,18 +9,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{MultiSpan, Span}; use rustc_span::{MultiSpan, Span};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together /// ### What it does
/// Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
/// without adding any branches. /// without adding any branches.
/// ///
/// Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only /// Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
/// cases where merging would most likely make the code more readable. /// cases where merging would most likely make the code more readable.
/// ///
/// **Why is this bad?** It is unnecessarily verbose and complex. /// ### Why is this bad?
/// /// It is unnecessarily verbose and complex.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// fn func(opt: Option<Result<u64, String>>) { /// fn func(opt: Option<Result<u64, String>>) {
/// let n = match opt { /// let n = match opt {

View File

@ -6,16 +6,19 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks comparison chains written with `if` that can be /// ### What it does
/// Checks comparison chains written with `if` that can be
/// rewritten with `match` and `cmp`. /// rewritten with `match` and `cmp`.
/// ///
/// **Why is this bad?** `if` is not guaranteed to be exhaustive and conditionals can get /// ### Why is this bad?
/// `if` is not guaranteed to be exhaustive and conditionals can get
/// repetitive /// repetitive
/// ///
/// **Known problems:** The match statement may be slower due to the compiler /// ### Known problems
/// The match statement may be slower due to the compiler
/// not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354) /// not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// # fn a() {} /// # fn a() {}
/// # fn b() {} /// # fn b() {}

View File

@ -16,13 +16,13 @@ use rustc_span::{source_map::Span, symbol::Symbol, BytePos};
use std::borrow::Cow; use std::borrow::Cow;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for consecutive `if`s with the same condition. /// ### What it does
/// Checks for consecutive `if`s with the same condition.
/// ///
/// **Why is this bad?** This is probably a copy & paste error. /// ### Why is this bad?
/// This is probably a copy & paste error.
/// ///
/// **Known problems:** Hopefully none. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// if a == b { /// if a == b {
/// … /// …
@ -47,15 +47,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for consecutive `if`s with the same function call. /// ### What it does
/// Checks for consecutive `if`s with the same function call.
/// ///
/// **Why is this bad?** This is probably a copy & paste error. /// ### Why is this bad?
/// This is probably a copy & paste error.
/// Despite the fact that function can have side effects and `if` works as /// Despite the fact that function can have side effects and `if` works as
/// intended, such an approach is implicit and can be considered a "code smell". /// intended, such an approach is implicit and can be considered a "code smell".
/// ///
/// **Known problems:** Hopefully none. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// if foo() == bar { /// if foo() == bar {
/// … /// …
@ -94,14 +94,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `if/else` with the same body as the *then* part /// ### What it does
/// Checks for `if/else` with the same body as the *then* part
/// and the *else* part. /// and the *else* part.
/// ///
/// **Why is this bad?** This is probably a copy & paste error. /// ### Why is this bad?
/// This is probably a copy & paste error.
/// ///
/// **Known problems:** Hopefully none. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// let foo = if … { /// let foo = if … {
/// 42 /// 42
@ -115,17 +115,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks if the `if` and `else` block contain shared code that can be /// ### What it does
/// Checks if the `if` and `else` block contain shared code that can be
/// moved out of the blocks. /// moved out of the blocks.
/// ///
/// **Why is this bad?** Duplicate code is less maintainable. /// ### Why is this bad?
/// Duplicate code is less maintainable.
/// ///
/// **Known problems:** /// ### Known problems
/// * The lint doesn't check if the moved expressions modify values that are beeing used in /// * The lint doesn't check if the moved expressions modify values that are beeing used in
/// the if condition. The suggestion can in that case modify the behavior of the program. /// the if condition. The suggestion can in that case modify the behavior of the program.
/// See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452) /// See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)
/// ///
/// **Example:** /// ### Example
/// ```ignore /// ```ignore
/// let foo = if … { /// let foo = if … {
/// println!("Hello World"); /// println!("Hello World");

View File

@ -8,15 +8,15 @@ use rustc_span::sym;
use if_chain::if_chain; 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
/// `Iterator`. /// `Iterator`.
/// ///
/// **Why is this bad?** Implicit copies can be confusing when working with /// ### Why is this bad?
/// Implicit copies can be confusing when working with
/// iterator combinators. /// iterator combinators.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// #[derive(Copy, Clone)] /// #[derive(Copy, Clone)]
/// struct Countdown(u8); /// struct Countdown(u8);

View File

@ -8,13 +8,13 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead. /// ### What it does
/// Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
/// ///
/// **Why is this bad?** Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`. /// ### Why is this bad?
/// Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// ```rust /// ```rust
/// std::fs::create_dir("foo"); /// std::fs::create_dir("foo");

View File

@ -8,14 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of dbg!() macro. /// ### What it does
/// Checks for usage of dbg!() macro.
/// ///
/// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It /// ### Why is this bad?
/// `dbg!` macro is intended as a debugging tool. It
/// should not be in version control. /// should not be in version control.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// // Bad /// // Bad
/// dbg!(true) /// dbg!(true)

View File

@ -13,14 +13,14 @@ use rustc_span::symbol::{Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for literal calls to `Default::default()`. /// ### What it does
/// Checks for literal calls to `Default::default()`.
/// ///
/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is /// ### Why is this bad?
/// It's more clear to the reader to use the name of the type whose default is
/// being gotten than the generic `Default`. /// being gotten than the generic `Default`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// // Bad /// // Bad
/// let s: String = Default::default(); /// let s: String = Default::default();
@ -34,14 +34,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for immediate reassignment of fields initialized /// ### What it does
/// Checks for immediate reassignment of fields initialized
/// with Default::default(). /// with Default::default().
/// ///
/// **Why is this bad?**It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax). /// ### Why is this bad?
///It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
/// ///
/// **Known problems:** Assignments to patterns that are of tuple type are not linted. /// ### Known problems
/// Assignments to patterns that are of tuple type are not linted.
/// ///
/// **Example:** /// ### Example
/// Bad: /// Bad:
/// ``` /// ```
/// # #[derive(Default)] /// # #[derive(Default)]

View File

@ -18,7 +18,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::iter; use std::iter;
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.
/// ///
/// Default numeric fallback means that if numeric types have not yet been bound to concrete /// Default numeric fallback means that if numeric types have not yet been bound to concrete
@ -27,12 +28,14 @@ declare_clippy_lint! {
/// ///
/// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback. /// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
/// ///
/// **Why is this bad?** For those who are very careful about types, default numeric fallback /// ### Why is this bad?
/// For those who are very careful about types, default numeric fallback
/// can be a pitfall that cause unexpected runtime behavior. /// can be a pitfall that cause unexpected runtime behavior.
/// ///
/// **Known problems:** This lint can only be allowed at the function level or above. /// ### Known problems
/// This lint can only be allowed at the function level or above.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let i = 10; /// let i = 10;
/// let f = 1.23; /// let f = 1.23;

View File

@ -12,27 +12,33 @@ macro_rules! declare_deprecated_lint {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This used to check for `assert!(a == b)` and recommend /// ### Deprecation reason
/// This used to check for `assert!(a == b)` and recommend
/// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011. /// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.
pub SHOULD_ASSERT_EQ, pub SHOULD_ASSERT_EQ,
"`assert!()` will be more flexible with RFC 2011" "`assert!()` will be more flexible with RFC 2011"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This used to check for `Vec::extend`, which was slower than /// ### Deprecation reason
/// This used to check for `Vec::extend`, which was slower than
/// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true. /// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true.
pub EXTEND_FROM_SLICE, pub EXTEND_FROM_SLICE,
"`.extend_from_slice(_)` is a faster way to extend a Vec by a slice" "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** `Range::step_by(0)` used to be linted since it's /// ### Deprecation reason
/// `Range::step_by(0)` used to be linted since it's
/// an infinite iterator, which is better expressed by `iter::repeat`, /// an infinite iterator, which is better expressed by `iter::repeat`,
/// but the method has been removed for `Iterator::step_by` which panics /// but the method has been removed for `Iterator::step_by` which panics
/// if given a zero /// if given a zero
@ -41,27 +47,33 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This used to check for `Vec::as_slice`, which was unstable with good /// ### Deprecation reason
/// This used to check for `Vec::as_slice`, which was unstable with good
/// stable alternatives. `Vec::as_slice` has now been stabilized. /// stable alternatives. `Vec::as_slice` has now been stabilized.
pub UNSTABLE_AS_SLICE, pub UNSTABLE_AS_SLICE,
"`Vec::as_slice` has been stabilized in 1.7" "`Vec::as_slice` has been stabilized in 1.7"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This used to check for `Vec::as_mut_slice`, which was unstable with good /// ### Deprecation reason
/// This used to check for `Vec::as_mut_slice`, which was unstable with good
/// stable alternatives. `Vec::as_mut_slice` has now been stabilized. /// stable alternatives. `Vec::as_mut_slice` has now been stabilized.
pub UNSTABLE_AS_MUT_SLICE, pub UNSTABLE_AS_MUT_SLICE,
"`Vec::as_mut_slice` has been stabilized in 1.7" "`Vec::as_mut_slice` has been stabilized in 1.7"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint should never have applied to non-pointer types, as transmuting /// ### Deprecation reason
/// This lint should never have applied to non-pointer types, as transmuting
/// between non-pointer types of differing alignment is well-defined behavior (it's semantically /// between non-pointer types of differing alignment is well-defined behavior (it's semantically
/// equivalent to a memcpy). This lint has thus been refactored into two separate lints: /// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
/// cast_ptr_alignment and transmute_ptr_to_ptr. /// cast_ptr_alignment and transmute_ptr_to_ptr.
@ -70,9 +82,11 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint is too subjective, not having a good reason for being in clippy. /// ### Deprecation reason
/// This lint is too subjective, not having a good reason for being in clippy.
/// Additionally, compound assignment operators may be overloaded separately from their non-assigning /// Additionally, compound assignment operators may be overloaded separately from their non-assigning
/// counterparts, so this lint may suggest a change in behavior or the code may not compile. /// counterparts, so this lint may suggest a change in behavior or the code may not compile.
pub ASSIGN_OPS, pub ASSIGN_OPS,
@ -80,9 +94,11 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** The original rule will only lint for `if let`. After /// ### Deprecation reason
/// The original rule will only lint for `if let`. After
/// making it support to lint `match`, naming as `if let` is not suitable for it. /// making it support to lint `match`, naming as `if let` is not suitable for it.
/// So, this lint is deprecated. /// So, this lint is deprecated.
pub IF_LET_REDUNDANT_PATTERN_MATCHING, pub IF_LET_REDUNDANT_PATTERN_MATCHING,
@ -90,9 +106,11 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint used to suggest replacing `let mut vec = /// ### Deprecation reason
/// This lint used to suggest replacing `let mut vec =
/// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The /// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The
/// replacement has very different performance characteristics so the lint is /// replacement has very different performance characteristics so the lint is
/// deprecated. /// deprecated.
@ -101,51 +119,63 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint has been superseded by #[must_use] in rustc. /// ### Deprecation reason
/// This lint has been superseded by #[must_use] in rustc.
pub UNUSED_COLLECT, pub UNUSED_COLLECT,
"`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint" "`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** Associated-constants are now preferred. /// ### Deprecation reason
/// Associated-constants are now preferred.
pub REPLACE_CONSTS, pub REPLACE_CONSTS,
"associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants" "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** The regex! macro does not exist anymore. /// ### Deprecation reason
/// The regex! macro does not exist anymore.
pub REGEX_MACRO, pub REGEX_MACRO,
"the regex! macro has been removed from the regex crate in 2018" "the regex! macro has been removed from the regex crate in 2018"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint has been replaced by `manual_find_map`, a /// ### Deprecation reason
/// This lint has been replaced by `manual_find_map`, a
/// more specific lint. /// more specific lint.
pub FIND_MAP, pub FIND_MAP,
"this lint has been replaced by `manual_find_map`, a more specific lint" "this lint has been replaced by `manual_find_map`, a more specific lint"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** This lint has been replaced by `manual_filter_map`, a /// ### Deprecation reason
/// This lint has been replaced by `manual_filter_map`, a
/// more specific lint. /// more specific lint.
pub FILTER_MAP, pub FILTER_MAP,
"this lint has been replaced by `manual_filter_map`, a more specific lint" "this lint has been replaced by `manual_filter_map`, a more specific lint"
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** The `avoid_breaking_exported_api` config option was added, which /// ### Deprecation reason
/// The `avoid_breaking_exported_api` config option was added, which
/// enables the `enum_variant_names` lint for public items. /// enables the `enum_variant_names` lint for public items.
/// ``` /// ```
pub PUB_ENUM_VARIANT_NAMES, pub PUB_ENUM_VARIANT_NAMES,
@ -153,9 +183,11 @@ declare_deprecated_lint! {
} }
declare_deprecated_lint! { declare_deprecated_lint! {
/// **What it does:** Nothing. This lint has been deprecated. /// ### What it does
/// Nothing. This lint has been deprecated.
/// ///
/// **Deprecation reason:** The `avoid_breaking_exported_api` config option was added, which /// ### Deprecation reason
/// The `avoid_breaking_exported_api` config option was added, which
/// enables the `wrong_self_conversion` lint for public items. /// enables the `wrong_self_conversion` lint for public items.
pub WRONG_PUB_SELF_CONVENTION, pub WRONG_PUB_SELF_CONVENTION,
"set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items" "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items"

View File

@ -11,12 +11,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span}; 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.
/// ///
/// **Why is this bad?** Dereferencing by `&*x` or `&mut *x` is clearer and more concise, /// ### Why is this bad?
/// Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
/// when not part of a method chain. /// when not part of a method chain.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// use std::ops::Deref; /// use std::ops::Deref;
/// let a: &mut String = &mut String::from("foo"); /// let a: &mut String = &mut String::from("foo");

View File

@ -15,10 +15,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq` /// ### What it does
/// Checks for deriving `Hash` but implementing `PartialEq`
/// explicitly or vice versa. /// explicitly or vice versa.
/// ///
/// **Why is this bad?** The implementation of these traits must agree (for /// ### Why is this bad?
/// The implementation of these traits must agree (for
/// example for use with `HashMap`) so its probably a bad idea to use a /// example for use with `HashMap`) so its probably a bad idea to use a
/// default-generated `Hash` implementation with an explicitly defined /// default-generated `Hash` implementation with an explicitly defined
/// `PartialEq`. In particular, the following must hold for any type: /// `PartialEq`. In particular, the following must hold for any type:
@ -27,9 +29,7 @@ declare_clippy_lint! {
/// k1 == k2 ⇒ hash(k1) == hash(k2) /// k1 == k2 ⇒ hash(k1) == hash(k2)
/// ``` /// ```
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// #[derive(Hash)] /// #[derive(Hash)]
/// struct Foo; /// struct Foo;
@ -44,10 +44,12 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for deriving `Ord` but implementing `PartialOrd` /// ### What it does
/// Checks for deriving `Ord` but implementing `PartialOrd`
/// explicitly or vice versa. /// explicitly or vice versa.
/// ///
/// **Why is this bad?** The implementation of these traits must agree (for /// ### Why is this bad?
/// The implementation of these traits must agree (for
/// example for use with `sort`) so its probably a bad idea to use a /// example for use with `sort`) so its probably a bad idea to use a
/// default-generated `Ord` implementation with an explicitly defined /// default-generated `Ord` implementation with an explicitly defined
/// `PartialOrd`. In particular, the following must hold for any type /// `PartialOrd`. In particular, the following must hold for any type
@ -57,10 +59,7 @@ declare_clippy_lint! {
/// k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap() /// k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
/// ``` /// ```
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust,ignore /// ```rust,ignore
/// #[derive(Ord, PartialEq, Eq)] /// #[derive(Ord, PartialEq, Eq)]
/// struct Foo; /// struct Foo;
@ -95,18 +94,21 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for explicit `Clone` implementations for `Copy` /// ### What it does
/// Checks for explicit `Clone` implementations for `Copy`
/// types. /// types.
/// ///
/// **Why is this bad?** To avoid surprising behaviour, these traits should /// ### Why is this bad?
/// To avoid surprising behaviour, these traits should
/// agree and the behaviour of `Copy` cannot be overridden. In almost all /// agree and the behaviour of `Copy` cannot be overridden. In almost all
/// situations a `Copy` type should have a `Clone` implementation that does /// situations a `Copy` type should have a `Clone` implementation that does
/// nothing more than copy the object, which is what `#[derive(Copy, Clone)]` /// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
/// gets you. /// gets you.
/// ///
/// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925 /// ### Known problems
/// Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// #[derive(Copy)] /// #[derive(Copy)]
/// struct Foo; /// struct Foo;
@ -121,16 +123,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for deriving `serde::Deserialize` on a type that /// ### What it does
/// Checks for deriving `serde::Deserialize` on a type that
/// has methods using `unsafe`. /// has methods using `unsafe`.
/// ///
/// **Why is this bad?** Deriving `serde::Deserialize` will create a constructor /// ### Why is this bad?
/// Deriving `serde::Deserialize` will create a constructor
/// that may violate invariants hold by another constructor. /// that may violate invariants hold by another constructor.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust,ignore /// ```rust,ignore
/// use serde::Deserialize; /// use serde::Deserialize;
/// ///

View File

@ -8,15 +8,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Symbol; use rustc_span::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Denies the configured methods and functions in clippy.toml /// ### What it does
/// Denies the configured methods and functions in clippy.toml
/// ///
/// **Why is this bad?** Some methods are undesirable in certain contexts, /// ### Why is this bad?
/// Some methods are undesirable in certain contexts,
/// and it's beneficial to lint for them as needed. /// and it's beneficial to lint for them as needed.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// An example clippy.toml configuration: /// An example clippy.toml configuration:
/// ```toml /// ```toml
/// # clippy.toml /// # clippy.toml

View File

@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use unicode_script::{Script, UnicodeScript}; use unicode_script::{Script, UnicodeScript};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of unicode scripts other than those explicitly allowed /// ### What it does
/// Checks for usage of unicode scripts other than those explicitly allowed
/// by the lint config. /// by the lint config.
/// ///
/// This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`. /// This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
@ -19,7 +20,8 @@ declare_clippy_lint! {
/// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases /// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
/// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html /// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
/// ///
/// **Why is this bad?** It may be not desired to have many different scripts for /// ### Why is this bad?
/// It may be not desired to have many different scripts for
/// identifiers in the codebase. /// identifiers in the codebase.
/// ///
/// Note that if you only want to allow plain English, you might want to use /// Note that if you only want to allow plain English, you might want to use
@ -27,9 +29,7 @@ declare_clippy_lint! {
/// ///
/// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents /// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// // Assuming that `clippy.toml` contains the following line: /// // Assuming that `clippy.toml` contains the following line:
/// // allowed-locales = ["Latin", "Cyrillic"] /// // allowed-locales = ["Latin", "Cyrillic"]

View File

@ -2,27 +2,24 @@ use clippy_utils::diagnostics::span_lint;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{ use rustc_hir::{
def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind, def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, PrimTy, TraitBoundModifier, Ty, TyKind, UseKind,
}; };
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};
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Denies the configured types in clippy.toml. /// ### What it does
/// Denies the configured types in clippy.toml.
/// ///
/// **Why is this bad?** Some types are undesirable in certain contexts. /// ### Why is this bad?
/// /// Some types are undesirable in certain contexts.
/// **Known problems:** None.
///
/// N.B. There is no way to ban primitive types.
///
/// **Example:**
/// ///
/// ### Example:
/// An example clippy.toml configuration: /// An example clippy.toml configuration:
/// ```toml /// ```toml
/// # clippy.toml /// # clippy.toml
/// disallowed-methods = ["std::collections::BTreeMap"] /// disallowed-types = ["std::collections::BTreeMap"]
/// ``` /// ```
/// ///
/// ```rust,ignore /// ```rust,ignore
@ -42,7 +39,8 @@ declare_clippy_lint! {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DisallowedType { pub struct DisallowedType {
disallowed: FxHashSet<Vec<Symbol>>, disallowed: FxHashSet<Vec<Symbol>>,
def_ids: FxHashSet<(DefId, Vec<Symbol>)>, def_ids: FxHashSet<DefId>,
prim_tys: FxHashSet<PrimTy>,
} }
impl DisallowedType { impl DisallowedType {
@ -53,6 +51,23 @@ impl DisallowedType {
.map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>()) .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
.collect(), .collect(),
def_ids: FxHashSet::default(), def_ids: FxHashSet::default(),
prim_tys: FxHashSet::default(),
}
}
fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {
match res {
Res::Def(_, did) => {
if self.def_ids.contains(did) {
emit(cx, &cx.tcx.def_path_str(*did), span);
}
},
Res::PrimTy(prim) => {
if self.prim_tys.contains(prim) {
emit(cx, prim.name_str(), span);
}
},
_ => {},
} }
} }
} }
@ -63,60 +78,36 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) { fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
for path in &self.disallowed { for path in &self.disallowed {
let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>(); let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>()) match clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>()) {
{ Res::Def(_, id) => {
self.def_ids.insert((id, path.clone())); self.def_ids.insert(id);
},
Res::PrimTy(ty) => {
self.prim_tys.insert(ty);
},
_ => {},
} }
} }
} }
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if_chain! { if let ItemKind::Use(path, UseKind::Single) = &item.kind {
if let ItemKind::Use(path, UseKind::Single) = &item.kind; self.check_res_emit(cx, &path.res, item.span);
if let Res::Def(_, did) = path.res;
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
then {
emit(cx, name, item.span,);
}
} }
} }
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
if_chain! { if let TyKind::Path(path) = &ty.kind {
if let TyKind::Path(path) = &ty.kind; self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);
if let Some(did) = cx.qpath_res(path, ty.hir_id).opt_def_id();
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
then {
emit(cx, name, path.span());
}
} }
} }
fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) { fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) {
if_chain! { self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);
if let Res::Def(_, did) = poly.trait_ref.path.res;
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
then {
emit(cx, name, poly.trait_ref.path.span);
}
}
} }
// TODO: if non primitive const generics are a thing
// fn check_generic_arg(&mut self, cx: &LateContext<'tcx>, arg: &'tcx GenericArg<'tcx>) {
// match arg {
// GenericArg::Const(c) => {},
// }
// }
// fn check_generic_param(&mut self, cx: &LateContext<'tcx>, param: &'tcx GenericParam<'tcx>) {
// match param.kind {
// GenericParamKind::Const { .. } => {},
// }
// }
} }
fn emit(cx: &LateContext<'_>, name: &[Symbol], span: Span) { fn emit(cx: &LateContext<'_>, name: &str, span: Span) {
let name = name.iter().map(|s| s.to_ident_string()).collect::<Vec<_>>().join("::");
span_lint( span_lint(
cx, cx,
DISALLOWED_TYPE, DISALLOWED_TYPE,

View File

@ -30,15 +30,18 @@ use std::thread;
use url::Url; use url::Url;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for the presence of `_`, `::` or camel-case words /// ### What it does
/// Checks for the presence of `_`, `::` or camel-case words
/// outside ticks in documentation. /// outside ticks in documentation.
/// ///
/// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and /// ### Why is this bad?
/// *Rustdoc* supports markdown formatting, `_`, `::` and
/// camel-case probably indicates some code which should be included between /// camel-case probably indicates some code which should be included between
/// ticks. `_` can also be used for emphasis in markdown, this lint tries to /// ticks. `_` can also be used for emphasis in markdown, this lint tries to
/// consider that. /// consider that.
/// ///
/// **Known problems:** Lots of bad docs wont be fixed, what the lint checks /// ### Known problems
/// Lots of bad docs wont be fixed, what the lint checks
/// for is limited, and there are still false positives. HTML elements and their /// for is limited, and there are still false positives. HTML elements and their
/// content are not linted. /// content are not linted.
/// ///
@ -47,7 +50,7 @@ declare_clippy_lint! {
/// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec /// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
/// would fail. /// would fail.
/// ///
/// **Examples:** /// ### Examples
/// ```rust /// ```rust
/// /// Do something with the foo_bar parameter. See also /// /// Do something with the foo_bar parameter. See also
/// /// that::other::module::foo. /// /// that::other::module::foo.
@ -68,15 +71,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for the doc comments of publicly visible /// ### What it does
/// Checks for the doc comments of publicly visible
/// unsafe functions and warns if there is no `# Safety` section. /// unsafe functions and warns if there is no `# Safety` section.
/// ///
/// **Why is this bad?** Unsafe functions should document their safety /// ### Why is this bad?
/// Unsafe functions should document their safety
/// preconditions, so that users can be sure they are using them safely. /// preconditions, so that users can be sure they are using them safely.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ```rust /// ```rust
///# type Universe = (); ///# type Universe = ();
/// /// This function should really be documented /// /// This function should really be documented
@ -102,16 +105,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks the doc comments of publicly visible functions that /// ### What it does
/// Checks the doc comments of publicly visible functions that
/// return a `Result` type and warns if there is no `# Errors` section. /// return a `Result` type and warns if there is no `# Errors` section.
/// ///
/// **Why is this bad?** Documenting the type of errors that can be returned from a /// ### Why is this bad?
/// Documenting the type of errors that can be returned from a
/// function can help callers write code to handle the errors appropriately. /// function can help callers write code to handle the errors appropriately.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
///
/// Since the following function returns a `Result` it has an `# Errors` section in /// Since the following function returns a `Result` it has an `# Errors` section in
/// its doc comment: /// its doc comment:
/// ///
@ -131,16 +133,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks the doc comments of publicly visible functions that /// ### What it does
/// Checks the doc comments of publicly visible functions that
/// may panic and warns if there is no `# Panics` section. /// may panic and warns if there is no `# Panics` section.
/// ///
/// **Why is this bad?** Documenting the scenarios in which panicking occurs /// ### Why is this bad?
/// Documenting the scenarios in which panicking occurs
/// can help callers who do not want to panic to avoid those situations. /// can help callers who do not want to panic to avoid those situations.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
///
/// Since the following function may panic it has a `# Panics` section in /// Since the following function may panic it has a `# Panics` section in
/// its doc comment: /// its doc comment:
/// ///
@ -162,14 +163,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `fn main() { .. }` in doctests /// ### What it does
/// Checks for `fn main() { .. }` in doctests
/// ///
/// **Why is this bad?** The test can be shorter (and likely more readable) /// ### Why is this bad?
/// The test can be shorter (and likely more readable)
/// if the `fn main()` is left implicit. /// if the `fn main()` is left implicit.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ``````rust /// ``````rust
/// /// An example of a doctest with a `main()` function /// /// An example of a doctest with a `main()` function
/// /// /// ///

View File

@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
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.
/// ///
/// ///
/// **Why is this bad?** Readability. /// ### Why is this bad?
/// Readability.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// # let y = 2; /// # let y = 2;

View File

@ -4,14 +4,14 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for unnecessary double parentheses. /// ### What it does
/// Checks for unnecessary double parentheses.
/// ///
/// **Why is this bad?** This makes code harder to read and might indicate a /// ### Why is this bad?
/// This makes code harder to read and might indicate a
/// mistake. /// mistake.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// // Bad /// // Bad
/// fn simple_double_parens() -> i32 { /// fn simple_double_parens() -> i32 {

View File

@ -8,17 +8,17 @@ use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to `std::mem::drop` with a reference /// ### What it does
/// Checks for calls to `std::mem::drop` with a reference
/// instead of an owned value. /// instead of an owned value.
/// ///
/// **Why is this bad?** Calling `drop` on a reference will only drop the /// ### Why is this bad?
/// Calling `drop` on a reference will only drop the
/// reference itself, which is a no-op. It will not call the `drop` method (from /// reference itself, which is a no-op. It will not call the `drop` method (from
/// the `Drop` trait implementation) on the underlying referenced value, which /// the `Drop` trait implementation) on the underlying referenced value, which
/// is likely what was intended. /// is likely what was intended.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// let mut lock_guard = mutex.lock(); /// let mut lock_guard = mutex.lock();
/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
@ -31,17 +31,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to `std::mem::forget` with a reference /// ### What it does
/// Checks for calls to `std::mem::forget` with a reference
/// instead of an owned value. /// instead of an owned value.
/// ///
/// **Why is this bad?** Calling `forget` on a reference will only forget the /// ### Why is this bad?
/// Calling `forget` on a reference will only forget the
/// reference itself, which is a no-op. It will not forget the underlying /// reference itself, which is a no-op. It will not forget the underlying
/// referenced /// referenced
/// value, which is likely what was intended. /// value, which is likely what was intended.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x = Box::new(1); /// let x = Box::new(1);
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
@ -52,16 +52,16 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to `std::mem::drop` with a value /// ### What it does
/// Checks for calls to `std::mem::drop` with a value
/// that derives the Copy trait /// that derives the Copy trait
/// ///
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that /// ### Why is this bad?
/// Calling `std::mem::drop` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
/// value will be copied and moved into the function on invocation. /// value will be copied and moved into the function on invocation.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x: i32 = 42; // i32 implements Copy /// let x: i32 = 42; // i32 implements Copy
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the /// std::mem::drop(x) // A copy of x is passed to the function, leaving the
@ -73,10 +73,12 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for calls to `std::mem::forget` with a value that /// ### What it does
/// Checks for calls to `std::mem::forget` with a value that
/// derives the Copy trait /// derives the Copy trait
/// ///
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that /// ### Why is this bad?
/// Calling `std::mem::forget` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
/// value will be copied and moved into the function on invocation. /// value will be copied and moved into the function on invocation.
/// ///
@ -86,9 +88,7 @@ declare_clippy_lint! {
/// there /// there
/// is nothing for `std::mem::forget` to ignore. /// is nothing for `std::mem::forget` to ignore.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x: i32 = 42; // i32 implements Copy /// let x: i32 = 42; // i32 implements Copy
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the /// std::mem::forget(x) // A copy of x is passed to the function, leaving the

View File

@ -12,15 +12,15 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::paths; 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
/// from other `Duration` methods. /// from other `Duration` methods.
/// ///
/// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or /// ### Why is this bad?
/// It's more concise to call `Duration::subsec_micros()` or
/// `Duration::subsec_millis()` than to calculate them. /// `Duration::subsec_millis()` than to calculate them.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # use std::time::Duration; /// # use std::time::Duration;
/// let dur = Duration::new(5, 0); /// let dur = Duration::new(5, 0);

View File

@ -7,14 +7,14 @@ 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};
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.
/// ///
/// **Why is this bad?** Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10). /// ### Why is this bad?
/// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # fn a() {} /// # fn a() {}
/// # fn b() {} /// # fn b() {}

View File

@ -6,13 +6,15 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `enum`s with no variants. /// ### What it does
/// Checks for `enum`s with no variants.
/// ///
/// As of this writing, the `never_type` is still a /// As of this writing, the `never_type` is still a
/// nightly-only experimental API. Therefore, this lint is only triggered /// nightly-only experimental API. Therefore, this lint is only triggered
/// if the `never_type` is enabled. /// if the `never_type` is enabled.
/// ///
/// **Why is this bad?** If you want to introduce a type which /// ### Why is this bad?
/// If you want to introduce a type which
/// can't be instantiated, you should use `!` (the primitive type "never"), /// can't be instantiated, you should use `!` (the primitive type "never"),
/// or a wrapper around it, because `!` has more extensive /// or a wrapper around it, because `!` has more extensive
/// compiler support (type inference, etc...) and wrappers /// compiler support (type inference, etc...) and wrappers
@ -20,10 +22,7 @@ declare_clippy_lint! {
/// For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html) /// For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html)
/// ///
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// Bad: /// Bad:
/// ```rust /// ```rust
/// enum Test {} /// enum Test {}

View File

@ -16,12 +16,15 @@ use rustc_span::{Span, SyntaxContext, DUMMY_SP};
use std::fmt::Write; use std::fmt::Write;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap` /// ### What it does
/// Checks for uses of `contains_key` + `insert` on `HashMap`
/// or `BTreeMap`. /// or `BTreeMap`.
/// ///
/// **Why is this bad?** Using `entry` is more efficient. /// ### Why is this bad?
/// Using `entry` is more efficient.
/// ///
/// **Known problems:** The suggestion may have type inference errors in some cases. e.g. /// ### Known problems
/// The suggestion may have type inference errors in some cases. e.g.
/// ```rust /// ```rust
/// let mut map = std::collections::HashMap::new(); /// let mut map = std::collections::HashMap::new();
/// let _ = if !map.contains_key(&0) { /// let _ = if !map.contains_key(&0) {
@ -31,7 +34,7 @@ declare_clippy_lint! {
/// }; /// };
/// ``` /// ```
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// # let mut map = HashMap::new(); /// # let mut map = HashMap::new();

View File

@ -11,15 +11,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::convert::TryFrom; use std::convert::TryFrom;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for C-like enumerations that are /// ### What it does
/// Checks for C-like enumerations that are
/// `repr(isize/usize)` and have values that don't fit into an `i32`. /// `repr(isize/usize)` and have values that don't fit into an `i32`.
/// ///
/// **Why is this bad?** This will truncate the variant value on 32 bit /// ### Why is this bad?
/// This will truncate the variant value on 32 bit
/// architectures, but works fine on 64 bit. /// architectures, but works fine on 64 bit.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # #[cfg(target_pointer_width = "64")] /// # #[cfg(target_pointer_width = "64")]
/// #[repr(usize)] /// #[repr(usize)]

View File

@ -10,15 +10,15 @@ use rustc_span::source_map::Span;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Detects enumeration variants that are prefixed or suffixed /// ### What it does
/// Detects enumeration variants that are prefixed or suffixed
/// by the same characters. /// by the same characters.
/// ///
/// **Why is this bad?** Enumeration variant names should specify their variant, /// ### Why is this bad?
/// Enumeration variant names should specify their variant,
/// not repeat the enumeration name. /// not repeat the enumeration name.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// enum Cake { /// enum Cake {
/// BlackForestCake, /// BlackForestCake,
@ -40,14 +40,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Detects type names that are prefixed or suffixed by the /// ### What it does
/// Detects type names that are prefixed or suffixed by the
/// containing module's name. /// containing module's name.
/// ///
/// **Why is this bad?** It requires the user to type the module name twice. /// ### Why is this bad?
/// It requires the user to type the module name twice.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// mod cake { /// mod cake {
/// struct BlackForestCake; /// struct BlackForestCake;
@ -65,10 +65,12 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for modules that have the same name as their /// ### What it does
/// Checks for modules that have the same name as their
/// parent module /// parent module
/// ///
/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and /// ### Why is this bad?
/// A typical beginner mistake is to have `mod foo;` and
/// again `mod foo { .. /// again `mod foo { ..
/// }` in `foo.rs`. /// }` in `foo.rs`.
/// The expectation is that items inside the inner `mod foo { .. }` are then /// The expectation is that items inside the inner `mod foo { .. }` are then
@ -78,9 +80,7 @@ declare_clippy_lint! {
/// If this is done on purpose, it would be better to choose a more /// If this is done on purpose, it would be better to choose a more
/// representative module name. /// representative module name.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// // lib.rs /// // lib.rs
/// mod foo; /// mod foo;

View File

@ -9,18 +9,21 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for equal operands to comparison, logical and /// ### What it does
/// Checks for equal operands to comparison, logical and
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`, /// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
/// `||`, `&`, `|`, `^`, `-` and `/`). /// `||`, `&`, `|`, `^`, `-` and `/`).
/// ///
/// **Why is this bad?** This is usually just a typo or a copy and paste error. /// ### Why is this bad?
/// This is usually just a typo or a copy and paste error.
/// ///
/// **Known problems:** False negatives: We had some false positives regarding /// ### Known problems
/// False negatives: We had some false positives regarding
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance /// calls (notably [racer](https://github.com/phildawes/racer) had one instance
/// of `x.pop() && x.pop()`), so we removed matching any function or method /// of `x.pop() && x.pop()`), so we removed matching any function or method
/// calls. We may introduce a list of known pure functions in the future. /// calls. We may introduce a list of known pure functions in the future.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// if x + 1 == x + 1 {} /// if x + 1 == x + 1 {}
@ -37,15 +40,18 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for arguments to `==` which have their address /// ### What it does
/// Checks for arguments to `==` which have their address
/// taken to satisfy a bound /// taken to satisfy a bound
/// and suggests to dereference the other argument instead /// and suggests to dereference the other argument instead
/// ///
/// **Why is this bad?** It is more idiomatic to dereference the other argument. /// ### Why is this bad?
/// It is more idiomatic to dereference the other argument.
/// ///
/// **Known problems:** None /// ### Known problems
/// None
/// ///
/// **Example:** /// ### Example
/// ```ignore /// ```ignore
/// // Bad /// // Bad
/// &x == y /// &x == y

View File

@ -6,15 +6,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
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`.
/// ///
/// **Why is this bad?** The whole expression can be replaced by zero. /// ### Why is this bad?
/// The whole expression can be replaced by zero.
/// This is most likely not the intended outcome and should probably be /// This is most likely not the intended outcome and should probably be
/// corrected /// corrected
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// let x = 1; /// let x = 1;
/// 0 / x; /// 0 / x;

View File

@ -19,16 +19,16 @@ pub struct BoxedLocal {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would /// ### What it does
/// Checks for usage of `Box<T>` where an unboxed `T` would
/// work fine. /// work fine.
/// ///
/// **Why is this bad?** This is an unnecessary allocation, and bad for /// ### Why is this bad?
/// This is an unnecessary allocation, and bad for
/// performance. It is only necessary to allocate if you wish to move the box /// performance. It is only necessary to allocate if you wish to move the box
/// into something. /// into something.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # fn foo(bar: usize) {} /// # fn foo(bar: usize) {}
/// // Bad /// // Bad

View File

@ -14,19 +14,22 @@ use rustc_middle::ty::{self, ClosureKind, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
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
/// get adjusted are ignored. /// get adjusted are ignored.
/// ///
/// **Why is this bad?** Needlessly creating a closure adds code for no benefit /// ### Why is this bad?
/// Needlessly creating a closure adds code for no benefit
/// and gives the optimizer more work. /// and gives the optimizer more work.
/// ///
/// **Known problems:** If creating the closure inside the closure has a side- /// ### Known problems
/// If creating the closure inside the closure has a side-
/// effect then moving the closure creation out will change when that side- /// effect then moving the closure creation out will change when that side-
/// effect runs. /// effect runs.
/// See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details. /// See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// // Bad /// // Bad
/// xs.map(|x| foo(x)) /// xs.map(|x| foo(x))
@ -42,17 +45,20 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for closures which only invoke a method on the closure /// ### What it does
/// Checks for closures which only invoke a method on the closure
/// argument and can be replaced by referencing the method directly. /// argument and can be replaced by referencing the method directly.
/// ///
/// **Why is this bad?** It's unnecessary to create the closure. /// ### Why is this bad?
/// It's unnecessary to create the closure.
/// ///
/// **Known problems:** [#3071](https://github.com/rust-lang/rust-clippy/issues/3071), /// ### Known problems
/// [#3071](https://github.com/rust-lang/rust-clippy/issues/3071),
/// [#3942](https://github.com/rust-lang/rust-clippy/issues/3942), /// [#3942](https://github.com/rust-lang/rust-clippy/issues/3942),
/// [#4002](https://github.com/rust-lang/rust-clippy/issues/4002) /// [#4002](https://github.com/rust-lang/rust-clippy/issues/4002)
/// ///
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// Some('a').map(|s| s.to_uppercase()); /// Some('a').map(|s| s.to_uppercase());
/// ``` /// ```

View File

@ -9,17 +9,20 @@ use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for a read and a write to the same variable where /// ### What it does
/// Checks for a read and a write to the same variable where
/// whether the read occurs before or after the write depends on the evaluation /// whether the read occurs before or after the write depends on the evaluation
/// order of sub-expressions. /// order of sub-expressions.
/// ///
/// **Why is this bad?** It is often confusing to read. In addition, the /// ### Why is this bad?
/// It is often confusing to read. In addition, the
/// sub-expression evaluation order for Rust is not well documented. /// sub-expression evaluation order for Rust is not well documented.
/// ///
/// **Known problems:** Code which intentionally depends on the evaluation /// ### Known problems
/// Code which intentionally depends on the evaluation
/// order, or which is correct for any evaluation order. /// order, or which is correct for any evaluation order.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let mut x = 0; /// let mut x = 0;
/// ///
@ -43,16 +46,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for diverging calls that are not match arms or /// ### What it does
/// Checks for diverging calls that are not match arms or
/// statements. /// statements.
/// ///
/// **Why is this bad?** It is often confusing to read. In addition, the /// ### Why is this bad?
/// It is often confusing to read. In addition, the
/// sub-expression evaluation order for Rust is not well documented. /// sub-expression evaluation order for Rust is not well documented.
/// ///
/// **Known problems:** Someone might want to use `some_bool || panic!()` as a /// ### Known problems
/// Someone might want to use `some_bool || panic!()` as a
/// shorthand. /// shorthand.
/// ///
/// **Example:** /// ### Example
/// ```rust,no_run /// ```rust,no_run
/// # fn b() -> bool { true } /// # fn b() -> bool { true }
/// # fn c() -> bool { true } /// # fn c() -> bool { true }

View File

@ -8,19 +8,19 @@ use rustc_span::{sym, Span};
use std::convert::TryInto; use std::convert::TryInto;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for excessive /// ### What it does
/// Checks for excessive
/// use of bools in structs. /// use of bools in structs.
/// ///
/// **Why is this bad?** Excessive bools in a struct /// ### Why is this bad?
/// Excessive bools in a struct
/// is often a sign that it's used as a state machine, /// is often a sign that it's used as a state machine,
/// which is much better implemented as an enum. /// which is much better implemented as an enum.
/// If it's not the case, excessive bools usually benefit /// If it's not the case, excessive bools usually benefit
/// from refactoring into two-variant enums for better /// from refactoring into two-variant enums for better
/// readability and API. /// readability and API.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// Bad: /// Bad:
/// ```rust /// ```rust
/// struct S { /// struct S {
@ -44,19 +44,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for excessive use of /// ### What it does
/// Checks for excessive use of
/// bools in function definitions. /// bools in function definitions.
/// ///
/// **Why is this bad?** Calls to such functions /// ### Why is this bad?
/// Calls to such functions
/// are confusing and error prone, because it's /// are confusing and error prone, because it's
/// hard to remember argument order and you have /// hard to remember argument order and you have
/// no type system support to back you up. Using /// no type system support to back you up. Using
/// two-variant enums instead of bools often makes /// two-variant enums instead of bools often makes
/// API easier to use. /// API easier to use.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// Bad: /// Bad:
/// ```rust,ignore /// ```rust,ignore
/// fn f(is_round: bool, is_hot: bool) { ... } /// fn f(is_round: bool, is_hot: bool) { ... }

View File

@ -8,16 +8,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Warns on any exported `enum`s that are not tagged `#[non_exhaustive]` /// ### What it does
/// Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
/// ///
/// **Why is this bad?** Exhaustive enums are typically fine, but a project which does /// ### Why is this bad?
/// Exhaustive enums are typically fine, but a project which does
/// not wish to make a stability commitment around exported enums may wish to /// not wish to make a stability commitment around exported enums may wish to
/// disable them by default. /// disable them by default.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// enum Foo { /// enum Foo {
/// Bar, /// Bar,
@ -38,16 +37,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Warns on any exported `structs`s that are not tagged `#[non_exhaustive]` /// ### What it does
/// Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
/// ///
/// **Why is this bad?** Exhaustive structs are typically fine, but a project which does /// ### Why is this bad?
/// Exhaustive structs are typically fine, but a project which does
/// not wish to make a stability commitment around exported structs may wish to /// not wish to make a stability commitment around exported structs may wish to
/// disable them by default. /// disable them by default.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// struct Foo { /// struct Foo {
/// bar: u8, /// bar: u8,

View File

@ -6,15 +6,15 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** `exit()` terminates the program and doesn't provide a /// ### What it does
/// `exit()` terminates the program and doesn't provide a
/// stack trace. /// stack trace.
/// ///
/// **Why is this bad?** Ideally a program is terminated by finishing /// ### Why is this bad?
/// Ideally a program is terminated by finishing
/// the main function. /// the main function.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// std::process::exit(0) /// std::process::exit(0)
/// ``` /// ```

View File

@ -9,14 +9,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be /// ### What it does
/// Checks for usage of `write!()` / `writeln()!` which can be
/// replaced with `(e)print!()` / `(e)println!()` /// replaced with `(e)print!()` / `(e)println!()`
/// ///
/// **Why is this bad?** Using `(e)println! is clearer and more concise /// ### Why is this bad?
/// Using `(e)println! is clearer and more concise
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # use std::io::Write; /// # use std::io::Write;
/// # let bar = "furchtbar"; /// # let bar = "furchtbar";

View File

@ -10,13 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span}; use rustc_span::{sym, Span};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()` /// ### What it does
/// Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
/// ///
/// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure. /// ### Why is this bad?
/// `TryFrom` should be used if there's a possibility of failure.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// struct Foo(i32); /// struct Foo(i32);
/// ///

View File

@ -11,30 +11,32 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for statements of the form `(a - b) < f32::EPSILON` or /// ### What it does
/// `(a - b) < f64::EPSILON`. Notes the missing `.abs()`. /// Checks for statements of the form `(a - b) < f32::EPSILON` or
/// /// `(a - b) < f64::EPSILON`. Notes the missing `.abs()`.
/// **Why is this bad?** The code without `.abs()` is more likely to have a bug. ///
/// /// ### Why is this bad?
/// **Known problems:** If the user can ensure that b is larger than a, the `.abs()` is /// The code without `.abs()` is more likely to have a bug.
/// technically unneccessary. However, it will make the code more robust and doesn't have any ///
/// large performance implications. If the abs call was deliberately left out for performance /// ### Known problems
/// reasons, it is probably better to state this explicitly in the code, which then can be done /// If the user can ensure that b is larger than a, the `.abs()` is
/// with an allow. /// technically unneccessary. However, it will make the code more robust and doesn't have any
/// /// large performance implications. If the abs call was deliberately left out for performance
/// **Example:** /// reasons, it is probably better to state this explicitly in the code, which then can be done
/// /// with an allow.
/// ```rust ///
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool { /// ### Example
/// (a - b) < f32::EPSILON /// ```rust
/// } /// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
/// ``` /// (a - b) < f32::EPSILON
/// Use instead: /// }
/// ```rust /// ```
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool { /// Use instead:
/// (a - b).abs() < f32::EPSILON /// ```rust
/// } /// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
/// ``` /// (a - b).abs() < f32::EPSILON
/// }
/// ```
pub FLOAT_EQUALITY_WITHOUT_ABS, pub FLOAT_EQUALITY_WITHOUT_ABS,
suspicious, suspicious,
"float equality check without `.abs()`" "float equality check without `.abs()`"

View File

@ -10,15 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::fmt; use std::fmt;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for float literals with a precision greater /// ### What it does
/// Checks for float literals with a precision greater
/// than that supported by the underlying type. /// than that supported by the underlying type.
/// ///
/// **Why is this bad?** Rust will truncate the literal silently. /// ### Why is this bad?
/// /// Rust will truncate the literal silently.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// // Bad /// // Bad
/// let v: f32 = 0.123_456_789_9; /// let v: f32 = 0.123_456_789_9;
@ -34,16 +33,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for whole number float literals that /// ### What it does
/// Checks for whole number float literals that
/// cannot be represented as the underlying type without loss. /// cannot be represented as the underlying type without loss.
/// ///
/// **Why is this bad?** Rust will silently lose precision during /// ### Why is this bad?
/// Rust will silently lose precision during
/// conversion to a float. /// conversion to a float.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// // Bad /// // Bad
/// let _: f32 = 16_777_217.0; // 16_777_216.0 /// let _: f32 = 16_777_217.0; // 16_777_216.0

View File

@ -18,16 +18,15 @@ use std::f64::consts as f64_consts;
use sugg::Sugg; use sugg::Sugg;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Looks for floating-point expressions that /// ### What it does
/// Looks for floating-point expressions that
/// can be expressed using built-in methods to improve accuracy /// can be expressed using built-in methods to improve accuracy
/// at the cost of performance. /// at the cost of performance.
/// ///
/// **Why is this bad?** Negatively impacts accuracy. /// ### Why is this bad?
/// /// Negatively impacts accuracy.
/// **Known problems:** None
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// let a = 3f32; /// let a = 3f32;
/// let _ = a.powf(1.0 / 3.0); /// let _ = a.powf(1.0 / 3.0);
@ -49,16 +48,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Looks for floating-point expressions that /// ### What it does
/// Looks for floating-point expressions that
/// can be expressed using built-in methods to improve both /// can be expressed using built-in methods to improve both
/// accuracy and performance. /// accuracy and performance.
/// ///
/// **Why is this bad?** Negatively impacts accuracy and performance. /// ### Why is this bad?
/// /// Negatively impacts accuracy and performance.
/// **Known problems:** None
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// use std::f32::consts::E; /// use std::f32::consts::E;
/// ///

View File

@ -13,18 +13,18 @@ use rustc_span::symbol::kw;
use rustc_span::{sym, Span}; use rustc_span::{sym, Span};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for the use of `format!("string literal with no /// ### What it does
/// Checks for the use of `format!("string literal with no
/// argument")` and `format!("{}", foo)` where `foo` is a string. /// argument")` and `format!("{}", foo)` where `foo` is a string.
/// ///
/// **Why is this bad?** There is no point of doing that. `format!("foo")` can /// ### Why is this bad?
/// There is no point of doing that. `format!("foo")` can
/// be replaced by `"foo".to_owned()` if you really need a `String`. The even /// be replaced by `"foo".to_owned()` if you really need a `String`. The even
/// worse `&format!("foo")` is often encountered in the wild. `format!("{}", /// worse `&format!("foo")` is often encountered in the wild. `format!("{}",
/// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()` /// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
/// if `foo: &str`. /// if `foo: &str`.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ```rust /// ```rust
/// ///
/// // Bad /// // Bad

View File

@ -9,15 +9,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-` /// ### What it does
/// Checks for use of the non-existent `=*`, `=!` and `=-`
/// operators. /// operators.
/// ///
/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or /// ### Why is this bad?
/// This is either a typo of `*=`, `!=` or `-=` or
/// confusing. /// confusing.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`? /// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
/// ``` /// ```
@ -27,15 +27,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks the formatting of a unary operator on the right hand side /// ### What it does
/// Checks the formatting of a unary operator on the right hand side
/// of a binary operator. It lints if there is no space between the binary and unary operators, /// of a binary operator. It lints if there is no space between the binary and unary operators,
/// but there is a space between the unary and its operand. /// but there is a space between the unary and its operand.
/// ///
/// **Why is this bad?** This is either a typo in the binary operator or confusing. /// ### Why is this bad?
/// This is either a typo in the binary operator or confusing.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// if foo <- 30 { // this should be `foo < -30` but looks like a different operator /// if foo <- 30 { // this should be `foo < -30` but looks like a different operator
/// } /// }
@ -49,15 +49,15 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for formatting of `else`. It lints if the `else` /// ### What it does
/// Checks for formatting of `else`. It lints if the `else`
/// is followed immediately by a newline or the `else` seems to be missing. /// is followed immediately by a newline or the `else` seems to be missing.
/// ///
/// **Why is this bad?** This is probably some refactoring remnant, even if the /// ### Why is this bad?
/// This is probably some refactoring remnant, even if the
/// code is correct, it might look confusing. /// code is correct, it might look confusing.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// if foo { /// if foo {
/// } { // looks like an `else` is missing here /// } { // looks like an `else` is missing here
@ -85,14 +85,14 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for possible missing comma in an array. It lints if /// ### What it does
/// Checks for possible missing comma in an array. It lints if
/// an array element is a binary operator expression and it lies on two lines. /// an array element is a binary operator expression and it lies on two lines.
/// ///
/// **Why is this bad?** This could lead to unexpected results. /// ### Why is this bad?
/// This could lead to unexpected results.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// let a = &[ /// let a = &[
/// -1, -2, -3 // <= no comma here /// -1, -2, -3 // <= no comma here

View File

@ -1,21 +1,20 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::paths::INTO; use clippy_utils::{meets_msrv, msrvs};
use clippy_utils::{match_def_path, meets_msrv, msrvs};
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};
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 rustc_span::symbol::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead. /// ### What it does
/// Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
/// ///
/// **Why is this bad?** According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true. /// ### Why is this bad?
/// /// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// struct StringWrapper(String); /// struct StringWrapper(String);
/// ///
@ -62,7 +61,7 @@ impl LateLintPass<'_> for FromOverInto {
if_chain! { if_chain! {
if let hir::ItemKind::Impl{ .. } = &item.kind; if let hir::ItemKind::Impl{ .. } = &item.kind;
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.def_id); if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
if match_def_path(cx, impl_trait_ref.def_id, &INTO); if cx.tcx.is_diagnostic_item(sym::into_trait, impl_trait_ref.def_id);
then { then {
span_lint_and_help( span_lint_and_help(

View File

@ -10,20 +10,22 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
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)`
/// ///
/// **Why is this bad?** /// ### Why is this bad?
///
/// This specific common use case can be rewritten as `s.parse::<primitive>()` /// This specific common use case can be rewritten as `s.parse::<primitive>()`
/// (and in most cases, the turbofish can be removed), which reduces code length /// (and in most cases, the turbofish can be removed), which reduces code length
/// and complexity. /// and complexity.
/// ///
/// **Known problems:** /// ### Known problems
///
/// This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly /// This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly
/// in some cases, which is correct but adds unnecessary complexity to the code. /// in some cases, which is correct but adds unnecessary complexity to the code.
/// ///
/// **Example:** /// ### Example
///
/// ```ignore /// ```ignore
/// let input: &str = get_input(); /// let input: &str = get_input();
/// let num = u16::from_str_radix(input, 10)?; /// let num = u16::from_str_radix(input, 10)?;

View File

@ -11,15 +11,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span; use rustc_span::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for functions with too many parameters. /// ### What it does
/// Checks for functions with too many parameters.
/// ///
/// **Why is this bad?** Functions with lots of parameters are considered bad /// ### Why is this bad?
/// Functions with lots of parameters are considered bad
/// style and reduce readability (“what does the 5th parameter mean?”). Consider /// style and reduce readability (“what does the 5th parameter mean?”). Consider
/// grouping some parameters into a new type. /// grouping some parameters into a new type.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # struct Color; /// # struct Color;
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { /// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
@ -32,16 +32,16 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for functions with a large amount of lines. /// ### What it does
/// Checks for functions with a large amount of lines.
/// ///
/// **Why is this bad?** Functions with a lot of lines are harder to understand /// ### Why is this bad?
/// Functions with a lot of lines are harder to understand
/// due to having to look at a larger amount of code to understand what the /// due to having to look at a larger amount of code to understand what the
/// function is doing. Consider splitting the body of the function into /// function is doing. Consider splitting the body of the function into
/// multiple functions. /// multiple functions.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// fn im_too_long() { /// fn im_too_long() {
/// println!(""); /// println!("");
@ -55,15 +55,16 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for public functions that dereference raw pointer /// ### What it does
/// Checks for public functions that dereference raw pointer
/// arguments but are not marked `unsafe`. /// arguments but are not marked `unsafe`.
/// ///
/// **Why is this bad?** The function should probably be marked `unsafe`, since /// ### Why is this bad?
/// The function should probably be marked `unsafe`, since
/// for an arbitrary raw pointer, there is no way of telling for sure if it is /// for an arbitrary raw pointer, there is no way of telling for sure if it is
/// valid. /// valid.
/// ///
/// **Known problems:** /// ### Known problems
///
/// * It does not check functions recursively so if the pointer is passed to a /// * It does not check functions recursively so if the pointer is passed to a
/// private non-`unsafe` function which does the dereferencing, the lint won't /// private non-`unsafe` function which does the dereferencing, the lint won't
/// trigger. /// trigger.
@ -71,7 +72,7 @@ declare_clippy_lint! {
/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
/// `some_argument.get_raw_ptr()`). /// `some_argument.get_raw_ptr()`).
/// ///
/// **Example:** /// ### Example
/// ```rust,ignore /// ```rust,ignore
/// // Bad /// // Bad
/// pub fn foo(x: *const u8) { /// pub fn foo(x: *const u8) {
@ -89,17 +90,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for a [`#[must_use]`] attribute on /// ### What it does
/// Checks for a [`#[must_use]`] attribute on
/// unit-returning functions and methods. /// unit-returning functions and methods.
/// ///
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute /// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
/// ///
/// **Why is this bad?** Unit values are useless. The attribute is likely /// ### Why is this bad?
/// Unit values are useless. The attribute is likely
/// a remnant of a refactoring that removed the return type. /// a remnant of a refactoring that removed the return type.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ```rust /// ```rust
/// #[must_use] /// #[must_use]
/// fn useless() { } /// fn useless() { }
@ -110,19 +111,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for a [`#[must_use]`] attribute without /// ### What it does
/// Checks for a [`#[must_use]`] attribute without
/// further information on functions and methods that return a type already /// further information on functions and methods that return a type already
/// marked as `#[must_use]`. /// marked as `#[must_use]`.
/// ///
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute /// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
/// ///
/// **Why is this bad?** The attribute isn't needed. Not using the result /// ### Why is this bad?
/// The attribute isn't needed. Not using the result
/// will already be reported. Alternatively, one can add some text to the /// will already be reported. Alternatively, one can add some text to the
/// attribute to improve the lint message. /// attribute to improve the lint message.
/// ///
/// **Known problems:** None. /// ### Examples
///
/// **Examples:**
/// ```rust /// ```rust
/// #[must_use] /// #[must_use]
/// fn double_must_use() -> Result<(), ()> { /// fn double_must_use() -> Result<(), ()> {
@ -135,16 +136,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for public functions that have no /// ### What it does
/// Checks for public functions that have no
/// [`#[must_use]`] attribute, but return something not already marked /// [`#[must_use]`] attribute, but return something not already marked
/// must-use, have no mutable arg and mutate no statics. /// must-use, have no mutable arg and mutate no statics.
/// ///
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute /// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
/// ///
/// **Why is this bad?** Not bad at all, this lint just shows places where /// ### Why is this bad?
/// Not bad at all, this lint just shows places where
/// you could add the attribute. /// you could add the attribute.
/// ///
/// **Known problems:** The lint only checks the arguments for mutable /// ### Known problems
/// The lint only checks the arguments for mutable
/// types without looking if they are actually changed. On the other hand, /// types without looking if they are actually changed. On the other hand,
/// it also ignores a broad range of potentially interesting side effects, /// it also ignores a broad range of potentially interesting side effects,
/// because we cannot decide whether the programmer intends the function to /// because we cannot decide whether the programmer intends the function to
@ -152,7 +156,7 @@ declare_clippy_lint! {
/// positives. At least we don't lint if the result type is unit or already /// positives. At least we don't lint if the result type is unit or already
/// `#[must_use]`. /// `#[must_use]`.
/// ///
/// **Examples:** /// ### Examples
/// ```rust /// ```rust
/// // this could be annotated with `#[must_use]`. /// // this could be annotated with `#[must_use]`.
/// fn id<T>(t: T) -> T { t } /// fn id<T>(t: T) -> T { t }
@ -163,20 +167,23 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for public functions that return a `Result` /// ### What it does
/// Checks for public functions that return a `Result`
/// with an `Err` type of `()`. It suggests using a custom type that /// with an `Err` type of `()`. It suggests using a custom type that
/// implements `std::error::Error`. /// implements `std::error::Error`.
/// ///
/// **Why is this bad?** Unit does not implement `Error` and carries no /// ### Why is this bad?
/// Unit does not implement `Error` and carries no
/// further information about what went wrong. /// further information about what went wrong.
/// ///
/// **Known problems:** Of course, this lint assumes that `Result` is used /// ### Known problems
/// Of course, this lint assumes that `Result` is used
/// for a fallible operation (which is after all the intended use). However /// for a fallible operation (which is after all the intended use). However
/// code may opt to (mis)use it as a basic two-variant-enum. In that case, /// code may opt to (mis)use it as a basic two-variant-enum. In that case,
/// the suggestion is misguided, and the code should use a custom enum /// the suggestion is misguided, and the code should use a custom enum
/// instead. /// instead.
/// ///
/// **Examples:** /// ### Examples
/// ```rust /// ```rust
/// pub fn read_u8() -> Result<u8, ()> { Err(()) } /// pub fn read_u8() -> Result<u8, ()> { Err(()) }
/// ``` /// ```

View File

@ -12,12 +12,14 @@ use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine}; use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** This lint requires Future implementations returned from /// ### What it does
/// This lint requires Future implementations returned from
/// functions and methods to implement the `Send` marker trait. It is mostly /// functions and methods to implement the `Send` marker trait. It is mostly
/// used by library authors (public and internal) that target an audience where /// used by library authors (public and internal) that target an audience where
/// multithreaded executors are likely to be used for running these Futures. /// multithreaded executors are likely to be used for running these Futures.
/// ///
/// **Why is this bad?** A Future implementation captures some state that it /// ### Why is this bad?
/// A Future implementation captures some state that it
/// needs to eventually produce its final value. When targeting a multithreaded /// needs to eventually produce its final value. When targeting a multithreaded
/// executor (which is the norm on non-embedded devices) this means that this /// executor (which is the norm on non-embedded devices) this means that this
/// state may need to be transported to other threads, in other words the /// state may need to be transported to other threads, in other words the
@ -31,10 +33,7 @@ declare_clippy_lint! {
/// modifying the library where the offending Future implementation is /// modifying the library where the offending Future implementation is
/// produced. /// produced.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// async fn not_send(bytes: std::rc::Rc<[u8]>) {} /// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
/// ``` /// ```

View File

@ -14,10 +14,12 @@ use rustc_span::source_map::Spanned;
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for using `x.get(x.len() - 1)` instead of /// ### What it does
/// Checks for using `x.get(x.len() - 1)` instead of
/// `x.last()`. /// `x.last()`.
/// ///
/// **Why is this bad?** Using `x.last()` is easier to read and has the same /// ### Why is this bad?
/// Using `x.last()` is easier to read and has the same
/// result. /// result.
/// ///
/// Note that using `x[x.len() - 1]` is semantically different from /// Note that using `x[x.len() - 1]` is semantically different from
@ -27,10 +29,7 @@ declare_clippy_lint! {
/// There is another lint (get_unwrap) that covers the case of using /// There is another lint (get_unwrap) that covers the case of using
/// `x.get(index).unwrap()` instead of `x[index]`. /// `x.get(index).unwrap()` instead of `x[index]`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// // Bad /// // Bad
/// let x = vec![2, 3, 5]; /// let x = vec![2, 3, 5];

View File

@ -11,14 +11,14 @@ use clippy_utils::diagnostics::span_lint;
use clippy_utils::{clip, unsext}; 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`.
/// ///
/// **Why is this bad?** This code can be removed without changing the /// ### Why is this bad?
/// This code can be removed without changing the
/// meaning. So it just obscures what's going on. Delete it mercilessly. /// meaning. So it just obscures what's going on. Delete it mercilessly.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// x / 1 + 0 * 1 - 0 | 0; /// x / 1 + 0 * 1 - 0 | 0;

View File

@ -9,16 +9,15 @@ use rustc_middle::hir::map::Map;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `Mutex::lock` calls in `if let` expression /// ### What it does
/// Checks for `Mutex::lock` calls in `if let` expression
/// with lock calls in any of the else blocks. /// with lock calls in any of the else blocks.
/// ///
/// **Why is this bad?** The Mutex lock remains held for the whole /// ### Why is this bad?
/// The Mutex lock remains held for the whole
/// `if let ... else` block and deadlocks. /// `if let ... else` block and deadlocks.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust,ignore /// ```rust,ignore
/// if let Ok(thing) = mutex.lock() { /// if let Ok(thing) = mutex.lock() {
/// do_thing(); /// do_thing();

View File

@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:*** Checks for unnecessary `ok()` in if let. /// ### What it does
///* Checks for unnecessary `ok()` in if let.
/// ///
/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match /// ### Why is this bad?
/// Calling `ok()` in if let is unnecessary, instead match
/// on `Ok(pat)` /// on `Ok(pat)`
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// for i in iter { /// for i in iter {
/// if let Some(value) = i.parse().ok() { /// if let Some(value) = i.parse().ok() {

View File

@ -8,14 +8,14 @@ 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};
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.
/// ///
/// **Why is this bad?** Negations reduce the readability of statements. /// ### Why is this bad?
/// Negations reduce the readability of statements.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let v: Vec<usize> = vec![]; /// # let v: Vec<usize> = vec![];
/// # fn a() {} /// # fn a() {}

View File

@ -10,14 +10,13 @@ use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for if-else that could be written to `bool::then`. /// ### 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. /// ### Why is this bad?
/// /// Looks a little redundant. Using `bool::then` helps it have less lines of code.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// # let v = vec![0]; /// # let v = vec![0];
/// let a = if v.is_empty() { /// let a = if v.is_empty() {

View File

@ -5,7 +5,7 @@ use std::collections::BTreeMap;
use rustc_errors::DiagnosticBuilder; use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, walk_inf, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, NestedVisitorMap, Visitor};
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind}; use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
@ -19,24 +19,26 @@ use rustc_typeck::hir_ty_to_ty;
use if_chain::if_chain; use if_chain::if_chain;
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::paths; use clippy_utils::differing_macro_contexts;
use clippy_utils::source::{snippet, snippet_opt}; use clippy_utils::source::{snippet, snippet_opt};
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{differing_macro_contexts, match_def_path};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for public `impl` or `fn` missing generalization /// ### What it does
/// Checks for public `impl` or `fn` missing generalization
/// over different hashers and implicitly defaulting to the default hashing /// over different hashers and implicitly defaulting to the default hashing
/// algorithm (`SipHash`). /// algorithm (`SipHash`).
/// ///
/// **Why is this bad?** `HashMap` or `HashSet` with custom hashers cannot be /// ### Why is this bad?
/// `HashMap` or `HashSet` with custom hashers cannot be
/// used with them. /// used with them.
/// ///
/// **Known problems:** Suggestions for replacing constructors can contain /// ### Known problems
/// Suggestions for replacing constructors can contain
/// false-positives. Also applying suggestions can require modification of other /// false-positives. Also applying suggestions can require modification of other
/// pieces of code, possibly including external crates. /// pieces of code, possibly including external crates.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// # use std::hash::{Hash, BuildHasher}; /// # use std::hash::{Hash, BuildHasher};
@ -347,7 +349,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
return; return;
} }
if match_def_path(self.cx, ty_did, &paths::HASHMAP) { if self.cx.tcx.is_diagnostic_item(sym::hashmap_type, ty_did) {
if method.ident.name == sym::new { if method.ident.name == sym::new {
self.suggestions self.suggestions
.insert(e.span, "HashMap::default()".to_string()); .insert(e.span, "HashMap::default()".to_string());
@ -360,7 +362,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
), ),
); );
} }
} else if match_def_path(self.cx, ty_did, &paths::HASHSET) { } else if self.cx.tcx.is_diagnostic_item(sym::hashset_type, ty_did) {
if method.ident.name == sym::new { if method.ident.name == sym::new {
self.suggestions self.suggestions
.insert(e.span, "HashSet::default()".to_string()); .insert(e.span, "HashSet::default()".to_string());

View File

@ -13,17 +13,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{Span, SyntaxContext}; use rustc_span::{Span, SyntaxContext};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for missing return statements at the end of a block. /// ### What it does
/// Checks for missing return statements at the end of a block.
/// ///
/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers /// ### Why is this bad?
/// Actually omitting the return keyword is idiomatic Rust code. Programmers
/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
/// the last returning statement because the only difference is a missing `;`. Especially in bigger /// the last returning statement because the only difference is a missing `;`. Especially in bigger
/// code with multiple return paths having a `return` keyword makes it easier to find the /// code with multiple return paths having a `return` keyword makes it easier to find the
/// corresponding statements. /// corresponding statements.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// fn foo(x: usize) -> usize { /// fn foo(x: usize) -> usize {
/// x /// x

View File

@ -8,14 +8,13 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for implicit saturating subtraction. /// ### What it does
/// Checks for implicit saturating subtraction.
/// ///
/// **Why is this bad?** Simplicity and readability. Instead we can easily use an builtin function. /// ### Why is this bad?
/// /// Simplicity and readability. Instead we can easily use an builtin function.
/// **Known problems:** None.
///
/// **Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// let end: u32 = 10; /// let end: u32 = 10;
/// let start: u32 = 5; /// let start: u32 = 5;

View File

@ -10,11 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for struct constructors where all fields are shorthand and /// ### What it does
/// Checks for struct constructors where all fields are shorthand and
/// the order of the field init shorthand in the constructor is inconsistent /// the order of the field init shorthand in the constructor is inconsistent
/// with the order in the struct definition. /// 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,
/// ///
/// ```rust /// ```rust
@ -32,10 +34,7 @@ declare_clippy_lint! {
/// ///
/// inconsistent order can be confusing and decreases readability and consistency. /// inconsistent order can be confusing and decreases readability and consistency.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
///
/// ```rust /// ```rust
/// struct Foo { /// struct Foo {
/// x: i32, /// x: i32,

View File

@ -10,14 +10,17 @@ use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for out of bounds array indexing with a constant /// ### What it does
/// Checks for out of bounds array indexing with a constant
/// index. /// index.
/// ///
/// **Why is this bad?** This will always panic at runtime. /// ### Why is this bad?
/// This will always panic at runtime.
/// ///
/// **Known problems:** Hopefully none. /// ### Known problems
/// Hopefully none.
/// ///
/// **Example:** /// ### Example
/// ```no_run /// ```no_run
/// # #![allow(const_err)] /// # #![allow(const_err)]
/// let x = [1, 2, 3, 4]; /// let x = [1, 2, 3, 4];
@ -36,16 +39,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cases, this lint /// ### What it does
/// Checks for usage of indexing or slicing. Arrays are special cases, this lint
/// does report on arrays if we can tell that slicing operations are in bounds and does not /// does report on arrays if we can tell that slicing operations are in bounds and does not
/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint. /// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
/// ///
/// **Why is this bad?** Indexing and slicing can panic at runtime and there are /// ### Why is this bad?
/// Indexing and slicing can panic at runtime and there are
/// safe alternatives. /// safe alternatives.
/// ///
/// **Known problems:** Hopefully none. /// ### Known problems
/// Hopefully none.
/// ///
/// **Example:** /// ### Example
/// ```rust,no_run /// ```rust,no_run
/// // Vector /// // Vector
/// let x = vec![0; 5]; /// let x = vec![0; 5];

View File

@ -1,19 +1,20 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::{implements_trait, match_type}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths}; use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, 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 rustc_span::symbol::{sym, Symbol};
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.
/// ///
/// **Why is this bad?** While there may be places where this is acceptable /// ### Why is this bad?
/// While there may be places where this is acceptable
/// (e.g., in event streams), in most cases this is simply an error. /// (e.g., in event streams), in most cases this is simply an error.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```no_run /// ```no_run
/// use std::iter; /// use std::iter;
/// ///
@ -25,15 +26,18 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for iteration that may be infinite. /// ### What it does
/// Checks for iteration that may be infinite.
/// ///
/// **Why is this bad?** While there may be places where this is acceptable /// ### Why is this bad?
/// While there may be places where this is acceptable
/// (e.g., in event streams), in most cases this is simply an error. /// (e.g., in event streams), in most cases this is simply an error.
/// ///
/// **Known problems:** The code may have a condition to stop iteration, but /// ### Known problems
/// The code may have a condition to stop iteration, but
/// this lint is not clever enough to analyze it. /// this lint is not clever enough to analyze it.
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let infinite_iter = 0..; /// let infinite_iter = 0..;
/// [0..].iter().zip(infinite_iter.take_while(|x| *x > 5)); /// [0..].iter().zip(infinite_iter.take_while(|x| *x > 5));
@ -202,15 +206,15 @@ const COMPLETING_METHODS: [(&str, usize); 12] = [
]; ];
/// the paths of types that are known to be infinitely allocating /// the paths of types that are known to be infinitely allocating
const INFINITE_COLLECTORS: [&[&str]; 8] = [ const INFINITE_COLLECTORS: &[Symbol] = &[
&paths::BINARY_HEAP, sym::BinaryHeap,
&paths::BTREEMAP, sym::BTreeMap,
&paths::BTREESET, sym::BTreeSet,
&paths::HASHMAP, sym::hashmap_type,
&paths::HASHSET, sym::hashset_type,
&paths::LINKED_LIST, sym::LinkedList,
&paths::VEC, sym::vec_type,
&paths::VEC_DEQUE, sym::vecdeque_type,
]; ];
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
@ -235,7 +239,10 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
} }
} else if method.ident.name == sym!(collect) { } else if method.ident.name == sym!(collect) {
let ty = cx.typeck_results().expr_ty(expr); let ty = cx.typeck_results().expr_ty(expr);
if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) { if INFINITE_COLLECTORS
.iter()
.any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item))
{
return is_infinite(cx, &args[0]); return is_infinite(cx, &args[0]);
} }
} }

View File

@ -10,13 +10,13 @@ use rustc_span::Span;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for multiple inherent implementations of a struct /// ### What it does
/// Checks for multiple inherent implementations of a struct
/// ///
/// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate. /// ### Why is this bad?
/// Splitting the implementation of a type makes the code harder to navigate.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// struct X; /// struct X;
/// impl X { /// impl X {

View File

@ -8,14 +8,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
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`.
/// ///
/// **Why is this bad?** This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred. /// ### Why is this bad?
/// This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.
/// ///
/// **Known problems:** None /// ### Known problems
/// /// None
/// ** Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// // Bad /// // Bad
/// pub struct A; /// pub struct A;
@ -45,14 +47,16 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait. /// ### What it does
/// Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait.
/// ///
/// **Why is this bad?** This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`. /// ### Why is this bad?
/// This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.
/// ///
/// **Known problems:** None /// ### Known problems
/// /// None
/// ** Example:**
/// ///
/// ### Example
/// ```rust /// ```rust
/// // Bad /// // Bad
/// use std::fmt; /// use std::fmt;

View File

@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Symbol}; use rustc_span::{sym, Symbol};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `#[inline]` on trait methods without bodies /// ### What it does
/// Checks for `#[inline]` on trait methods without bodies
/// ///
/// **Why is this bad?** Only implementations of trait methods may be inlined. /// ### Why is this bad?
/// Only implementations of trait methods may be inlined.
/// The inline attribute is ignored for trait methods without bodies. /// The inline attribute is ignored for trait methods without bodies.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// trait Animal { /// trait Animal {
/// #[inline] /// #[inline]

View File

@ -8,13 +8,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
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
/// ///
/// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`. /// ### Why is this bad?
/// Readability -- better to use `> y` instead of `>= y + 1`.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// # let x = 1; /// # let x = 1;
/// # let y = 1; /// # let y = 1;

View File

@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for division of integers /// ### What it does
/// Checks for division of integers
/// ///
/// **Why is this bad?** When outside of some very specific algorithms, /// ### Why is this bad?
/// When outside of some very specific algorithms,
/// integer division is very often a mistake because it discards the /// integer division is very often a mistake because it discards the
/// remainder. /// remainder.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// // Bad /// // Bad
/// let x = 3 / 2; /// let x = 3 / 2;

View File

@ -14,18 +14,20 @@ use clippy_utils::source::snippet;
use clippy_utils::{comparisons, sext}; use clippy_utils::{comparisons, sext};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for comparisons where the relation is always either /// ### What it does
/// Checks for comparisons where the relation is always either
/// true or false, but where one side has been upcast so that the comparison is /// true or false, but where one side has been upcast so that the comparison is
/// necessary. Only integer types are checked. /// necessary. Only integer types are checked.
/// ///
/// **Why is this bad?** An expression like `let x : u8 = ...; (x as u32) > 300` /// ### Why is this bad?
/// An expression like `let x : u8 = ...; (x as u32) > 300`
/// will mistakenly imply that it is possible for `x` to be outside the range of /// will mistakenly imply that it is possible for `x` to be outside the range of
/// `u8`. /// `u8`.
/// ///
/// **Known problems:** /// ### Known problems
/// https://github.com/rust-lang/rust-clippy/issues/886 /// https://github.com/rust-lang/rust-clippy/issues/886
/// ///
/// **Example:** /// ### Example
/// ```rust /// ```rust
/// let x: u8 = 1; /// let x: u8 = 1;
/// (x as u32) > 300; /// (x as u32) > 300;

View File

@ -7,15 +7,15 @@ 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};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for items declared after some statement in a block. /// ### What it does
/// Checks for items declared after some statement in a block.
/// ///
/// **Why is this bad?** Items live for the entire scope they are declared /// ### Why is this bad?
/// Items live for the entire scope they are declared
/// in. But statements are processed in order. This might cause confusion as /// in. But statements are processed in order. This might cause confusion as
/// it's hard to figure out which item is meant in a statement. /// it's hard to figure out which item is meant in a statement.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// // Bad /// // Bad
/// fn foo() { /// fn foo() {

View File

@ -11,15 +11,15 @@ use rustc_span::{BytePos, Pos, Span};
use rustc_typeck::hir_ty_to_ty; use rustc_typeck::hir_ty_to_ty;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for large `const` arrays that should /// ### What it does
/// Checks for large `const` arrays that should
/// be defined as `static` instead. /// be defined as `static` instead.
/// ///
/// **Why is this bad?** Performance: const variables are inlined upon use. /// ### Why is this bad?
/// Performance: const variables are inlined upon use.
/// Static items result in only one instance and has a fixed location in memory. /// Static items result in only one instance and has a fixed location in memory.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// // Bad /// // Bad
/// pub const a = [0u32; 1_000_000]; /// pub const a = [0u32; 1_000_000];

View File

@ -10,20 +10,22 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_target::abi::LayoutOf; use rustc_target::abi::LayoutOf;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for large size differences between variants on /// ### What it does
/// Checks for large size differences between variants on
/// `enum`s. /// `enum`s.
/// ///
/// **Why is this bad?** Enum size is bounded by the largest variant. Having a /// ### Why is this bad?
/// Enum size is bounded by the largest variant. Having a
/// large variant can penalize the memory layout of that enum. /// large variant can penalize the memory layout of that enum.
/// ///
/// **Known problems:** This lint obviously cannot take the distribution of /// ### Known problems
/// This lint obviously cannot take the distribution of
/// variants in your running program into account. It is possible that the /// variants in your running program into account. It is possible that the
/// smaller variants make up less than 1% of all instances, in which case /// smaller variants make up less than 1% of all instances, in which case
/// the overhead is negligible and the boxing is counter-productive. Always /// the overhead is negligible and the boxing is counter-productive. Always
/// measure the change this lint suggests. /// measure the change this lint suggests.
/// ///
/// **Example:** /// ### Example
///
/// ```rust /// ```rust
/// // Bad /// // Bad
/// enum Test { /// enum Test {

View File

@ -10,13 +10,13 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use crate::rustc_target::abi::LayoutOf; use crate::rustc_target::abi::LayoutOf;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for local arrays that may be too large. /// ### What it does
/// Checks for local arrays that may be too large.
/// ///
/// **Why is this bad?** Large local arrays may cause stack overflow. /// ### Why is this bad?
/// Large local arrays may cause stack overflow.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// let a = [0u32; 1_000_000]; /// let a = [0u32; 1_000_000];
/// ``` /// ```

View File

@ -18,17 +18,17 @@ use rustc_span::{
}; };
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for getting the length of something via `.len()` /// ### What it does
/// Checks for getting the length of something via `.len()`
/// just to compare to zero, and suggests using `.is_empty()` where applicable. /// just to compare to zero, and suggests using `.is_empty()` where applicable.
/// ///
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster /// ### Why is this bad?
/// Some structures can answer `.is_empty()` much faster
/// than calculating their length. So it is good to get into the habit of using /// than calculating their length. So it is good to get into the habit of using
/// `.is_empty()`, and having it is cheap. /// `.is_empty()`, and having it is cheap.
/// Besides, it makes the intent clearer than a manual comparison in some contexts. /// Besides, it makes the intent clearer than a manual comparison in some contexts.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// if x.len() == 0 { /// if x.len() == 0 {
/// .. /// ..
@ -52,18 +52,18 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for items that implement `.len()` but not /// ### What it does
/// Checks for items that implement `.len()` but not
/// `.is_empty()`. /// `.is_empty()`.
/// ///
/// **Why is this bad?** It is good custom to have both methods, because for /// ### Why is this bad?
/// It is good custom to have both methods, because for
/// some data structures, asking about the length will be a costly operation, /// some data structures, asking about the length will be a costly operation,
/// whereas `.is_empty()` can usually answer in constant time. Also it used to /// whereas `.is_empty()` can usually answer in constant time. Also it used to
/// lead to false positives on the [`len_zero`](#len_zero) lint currently that /// lead to false positives on the [`len_zero`](#len_zero) lint currently that
/// lint will ignore such entities. /// lint will ignore such entities.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```ignore /// ```ignore
/// impl X { /// impl X {
/// pub fn len(&self) -> usize { /// pub fn len(&self) -> usize {
@ -77,17 +77,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for comparing to an empty slice such as `""` or `[]`, /// ### What it does
/// Checks for comparing to an empty slice such as `""` or `[]`,
/// and suggests using `.is_empty()` where applicable. /// and suggests using `.is_empty()` where applicable.
/// ///
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster /// ### Why is this bad?
/// Some structures can answer `.is_empty()` much faster
/// than checking for equality. So it is good to get into the habit of using /// than checking for equality. So it is good to get into the habit of using
/// `.is_empty()`, and having it is cheap. /// `.is_empty()`, and having it is cheap.
/// Besides, it makes the intent clearer than a manual comparison in some contexts. /// Besides, it makes the intent clearer than a manual comparison in some contexts.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// ```ignore /// ```ignore
/// if s == "" { /// if s == "" {

View File

@ -9,14 +9,14 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for variable declarations immediately followed by a /// ### What it does
/// Checks for variable declarations immediately followed by a
/// conditional affectation. /// conditional affectation.
/// ///
/// **Why is this bad?** This is not idiomatic Rust. /// ### Why is this bad?
/// This is not idiomatic Rust.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust,ignore /// ```rust,ignore
/// let foo; /// let foo;
/// ///

View File

@ -9,15 +9,15 @@ use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `let _ = <expr>` /// ### What it does
/// Checks for `let _ = <expr>`
/// where expr is #[must_use] /// where expr is #[must_use]
/// ///
/// **Why is this bad?** It's better to explicitly /// ### Why is this bad?
/// It's better to explicitly
/// handle the value of a #[must_use] expr /// handle the value of a #[must_use] expr
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ```rust /// ```rust
/// fn f() -> Result<u32, u32> { /// fn f() -> Result<u32, u32> {
/// Ok(0) /// Ok(0)
@ -33,17 +33,17 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `let _ = sync_lock` /// ### What it does
/// Checks for `let _ = sync_lock`
/// ///
/// **Why is this bad?** This statement immediately drops the lock instead of /// ### Why is this bad?
/// This statement immediately drops the lock instead of
/// extending its lifetime to the end of the scope, which is often not intended. /// extending its lifetime to the end of the scope, which is often not intended.
/// To extend lock lifetime to the end of the scope, use an underscore-prefixed /// To extend lock lifetime to the end of the scope, use an underscore-prefixed
/// name instead (i.e. _lock). If you want to explicitly drop the lock, /// name instead (i.e. _lock). If you want to explicitly drop the lock,
/// `std::mem::drop` conveys your intention better and is less error-prone. /// `std::mem::drop` conveys your intention better and is less error-prone.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// Bad: /// Bad:
/// ```rust,ignore /// ```rust,ignore
@ -60,19 +60,19 @@ declare_clippy_lint! {
} }
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for `let _ = <expr>` /// ### What it does
/// Checks for `let _ = <expr>`
/// where expr has a type that implements `Drop` /// where expr has a type that implements `Drop`
/// ///
/// **Why is this bad?** This statement immediately drops the initializer /// ### Why is this bad?
/// This statement immediately drops the initializer
/// expression instead of extending its lifetime to the end of the scope, which /// expression instead of extending its lifetime to the end of the scope, which
/// is often not intended. To extend the expression's lifetime to the end of the /// is often not intended. To extend the expression's lifetime to the end of the
/// scope, use an underscore-prefixed name instead (i.e. _var). If you want to /// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
/// explicitly drop the expression, `std::mem::drop` conveys your intention /// explicitly drop the expression, `std::mem::drop` conveys your intention
/// better and is less error-prone. /// better and is less error-prone.
/// ///
/// **Known problems:** None. /// ### Example
///
/// **Example:**
/// ///
/// Bad: /// Bad:
/// ```rust,ignore /// ```rust,ignore

View File

@ -73,14 +73,13 @@ use rustc_session::Session;
/// use clippy_lints::declare_clippy_lint; /// use clippy_lints::declare_clippy_lint;
/// ///
/// declare_clippy_lint! { /// declare_clippy_lint! {
/// /// **What it does:** Checks for ... (describe what the lint matches). /// /// ### What it does
/// /// Checks for ... (describe what the lint matches).
/// /// /// ///
/// /// **Why is this bad?** Supply the reason for linting the code. /// /// ### Why is this bad?
/// /// /// /// Supply the reason for linting the code.
/// /// **Known problems:** None. (Or describe where it could go wrong.)
/// ///
/// /// **Example:**
/// /// /// ///
/// /// ### Example
/// /// ```rust /// /// ```rust
/// /// // Bad /// /// // Bad
/// /// Insert a short example of code that triggers the lint /// /// Insert a short example of code that triggers the lint
@ -330,7 +329,7 @@ mod regex;
mod repeat_once; mod repeat_once;
mod returns; mod returns;
mod self_assignment; mod self_assignment;
mod self_named_constructor; mod self_named_constructors;
mod semicolon_if_nothing_returned; mod semicolon_if_nothing_returned;
mod serde_api; mod serde_api;
mod shadow; mod shadow;
@ -741,7 +740,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
mem_replace::MEM_REPLACE_OPTION_WITH_NONE, mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
mem_replace::MEM_REPLACE_WITH_DEFAULT, mem_replace::MEM_REPLACE_WITH_DEFAULT,
mem_replace::MEM_REPLACE_WITH_UNINIT, mem_replace::MEM_REPLACE_WITH_UNINIT,
methods::APPEND_INSTEAD_OF_EXTEND,
methods::BIND_INSTEAD_OF_MAP, methods::BIND_INSTEAD_OF_MAP,
methods::BYTES_NTH, methods::BYTES_NTH,
methods::CHARS_LAST_CMP, methods::CHARS_LAST_CMP,
@ -752,6 +750,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
methods::CLONE_ON_REF_PTR, methods::CLONE_ON_REF_PTR,
methods::EXPECT_FUN_CALL, methods::EXPECT_FUN_CALL,
methods::EXPECT_USED, methods::EXPECT_USED,
methods::EXTEND_WITH_DRAIN,
methods::FILETYPE_IS_FILE, methods::FILETYPE_IS_FILE,
methods::FILTER_MAP_IDENTITY, methods::FILTER_MAP_IDENTITY,
methods::FILTER_MAP_NEXT, methods::FILTER_MAP_NEXT,
@ -901,7 +900,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
returns::LET_AND_RETURN, returns::LET_AND_RETURN,
returns::NEEDLESS_RETURN, returns::NEEDLESS_RETURN,
self_assignment::SELF_ASSIGNMENT, self_assignment::SELF_ASSIGNMENT,
self_named_constructor::SELF_NAMED_CONSTRUCTOR, self_named_constructors::SELF_NAMED_CONSTRUCTORS,
semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED, semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
serde_api::SERDE_API_MISUSE, serde_api::SERDE_API_MISUSE,
shadow::SHADOW_REUSE, shadow::SHADOW_REUSE,
@ -1297,7 +1296,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE), LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT), LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT), LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
LintId::of(methods::BIND_INSTEAD_OF_MAP), LintId::of(methods::BIND_INSTEAD_OF_MAP),
LintId::of(methods::BYTES_NTH), LintId::of(methods::BYTES_NTH),
LintId::of(methods::CHARS_LAST_CMP), LintId::of(methods::CHARS_LAST_CMP),
@ -1305,6 +1303,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(methods::CLONE_DOUBLE_REF), LintId::of(methods::CLONE_DOUBLE_REF),
LintId::of(methods::CLONE_ON_COPY), LintId::of(methods::CLONE_ON_COPY),
LintId::of(methods::EXPECT_FUN_CALL), LintId::of(methods::EXPECT_FUN_CALL),
LintId::of(methods::EXTEND_WITH_DRAIN),
LintId::of(methods::FILTER_MAP_IDENTITY), LintId::of(methods::FILTER_MAP_IDENTITY),
LintId::of(methods::FILTER_NEXT), LintId::of(methods::FILTER_NEXT),
LintId::of(methods::FLAT_MAP_IDENTITY), LintId::of(methods::FLAT_MAP_IDENTITY),
@ -1408,7 +1407,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(returns::LET_AND_RETURN), LintId::of(returns::LET_AND_RETURN),
LintId::of(returns::NEEDLESS_RETURN), LintId::of(returns::NEEDLESS_RETURN),
LintId::of(self_assignment::SELF_ASSIGNMENT), LintId::of(self_assignment::SELF_ASSIGNMENT),
LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR), LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
LintId::of(serde_api::SERDE_API_MISUSE), LintId::of(serde_api::SERDE_API_MISUSE),
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT), LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
@ -1562,7 +1561,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES), LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
LintId::of(returns::LET_AND_RETURN), LintId::of(returns::LET_AND_RETURN),
LintId::of(returns::NEEDLESS_RETURN), LintId::of(returns::NEEDLESS_RETURN),
LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR), LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS), LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME), LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
@ -1763,8 +1762,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(large_enum_variant::LARGE_ENUM_VARIANT), LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
LintId::of(loops::MANUAL_MEMCPY), LintId::of(loops::MANUAL_MEMCPY),
LintId::of(loops::NEEDLESS_COLLECT), LintId::of(loops::NEEDLESS_COLLECT),
LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
LintId::of(methods::EXPECT_FUN_CALL), LintId::of(methods::EXPECT_FUN_CALL),
LintId::of(methods::EXTEND_WITH_DRAIN),
LintId::of(methods::ITER_NTH), LintId::of(methods::ITER_NTH),
LintId::of(methods::MANUAL_STR_REPEAT), LintId::of(methods::MANUAL_STR_REPEAT),
LintId::of(methods::OR_FUN_CALL), LintId::of(methods::OR_FUN_CALL),
@ -2105,7 +2104,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
let scripts = conf.allowed_scripts.clone(); let scripts = conf.allowed_scripts.clone();
store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts)); store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts));
store.register_late_pass(|| box strlen_on_c_strings::StrlenOnCStrings); store.register_late_pass(|| box strlen_on_c_strings::StrlenOnCStrings);
store.register_late_pass(move || box self_named_constructor::SelfNamedConstructor); store.register_late_pass(move || box self_named_constructors::SelfNamedConstructors);
} }
#[rustfmt::skip] #[rustfmt::skip]

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