diff --git a/Cargo.lock b/Cargo.lock index 40e4837c663..b7c180012e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -542,7 +542,7 @@ dependencies = [ [[package]] name = "clippy" -version = "0.1.55" +version = "0.1.56" dependencies = [ "cargo_metadata 0.12.0", "clippy_lints", @@ -575,7 +575,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.55" +version = "0.1.56" dependencies = [ "cargo_metadata 0.12.0", "clippy_utils", @@ -596,7 +596,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.55" +version = "0.1.56" dependencies = [ "if_chain", "itertools 0.9.0", diff --git a/src/tools/clippy/.github/deploy.sh b/src/tools/clippy/.github/deploy.sh index e85e8874ba6..a3c57232f55 100644 --- a/src/tools/clippy/.github/deploy.sh +++ b/src/tools/clippy/.github/deploy.sh @@ -8,13 +8,12 @@ rm -rf out/master/ || exit 0 echo "Making the docs for master" mkdir 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 echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it" - cp -r out/master "out/$TAG_NAME" - rm -f out/stable - ln -s "$TAG_NAME" out/stable + cp -Tr out/master "out/$TAG_NAME" + ln -sf "$TAG_NAME" out/stable fi if [[ $BETA = "true" ]]; then @@ -28,8 +27,8 @@ cp util/gh-pages/versions.html out/index.html echo "Making the versions.json file" python3 ./util/versions.py out -cd out # Now let's go have some fun with the cloned repo +cd out git config user.name "GHA CI" git config user.email "gha@ci.invalid" diff --git a/src/tools/clippy/.github/workflows/deploy.yml b/src/tools/clippy/.github/workflows/deploy.yml index 15aeaf907dc..b8be730be32 100644 --- a/src/tools/clippy/.github/workflows/deploy.yml +++ b/src/tools/clippy/.github/workflows/deploy.yml @@ -39,10 +39,23 @@ jobs: if: github.ref == 'refs/heads/beta' 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: | 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 run: | diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md index 5e00dec2e77..acbefc8064d 100644 --- a/src/tools/clippy/CHANGELOG.md +++ b/src/tools/clippy/CHANGELOG.md @@ -2423,7 +2423,6 @@ Released 2018-09-13 [`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 -[`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 [`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 @@ -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_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_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 [`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 @@ -2772,7 +2772,7 @@ Released 2018-09-13 [`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 [`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 [`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 diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index 9b5d9b2adf3..82e04c8fb85 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.55" +version = "0.1.56" authors = ["The Rust Clippy Developers"] description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs index 4676c2affad..3a81aaba6de 100644 --- a/src/tools/clippy/clippy_dev/src/new_lint.rs +++ b/src/tools/clippy/clippy_dev/src/new_lint.rs @@ -169,14 +169,11 @@ use rustc_session::{{declare_lint_pass, declare_tool_lint}}; {pass_import} declare_clippy_lint! {{ - /// **What it does:** + /// ### What it does /// - /// **Why is this bad?** - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? /// + /// ### Example /// ```rust /// // example code where clippy issues a warning /// ``` diff --git a/src/tools/clippy/clippy_dev/src/serve.rs b/src/tools/clippy/clippy_dev/src/serve.rs index d13c27a1957..b36e2a28ee4 100644 --- a/src/tools/clippy/clippy_dev/src/serve.rs +++ b/src/tools/clippy/clippy_dev/src/serve.rs @@ -15,8 +15,8 @@ pub fn run(port: u16, lint: Option<&str>) -> ! { loop { if mtime("util/gh-pages/lints.json") < mtime("clippy_lints/src") { - Command::new("python3") - .arg("util/export.py") + Command::new("cargo") + .arg("collect-metadata") .spawn() .unwrap() .wait() diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml index 42cf7547f51..0aa5b297442 100644 --- a/src/tools/clippy/clippy_lints/Cargo.toml +++ b/src/tools/clippy/clippy_lints/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy_lints" # begin automatic update -version = "0.1.55" +version = "0.1.56" # end automatic update authors = ["The Rust Clippy Developers"] description = "A bunch of helpful lints to avoid common pitfalls in Rust" diff --git a/src/tools/clippy/clippy_lints/src/absurd_extreme_comparisons.rs b/src/tools/clippy/clippy_lints/src/absurd_extreme_comparisons.rs index 49d4350123f..1483f3f9185 100644 --- a/src/tools/clippy/clippy_lints/src/absurd_extreme_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/absurd_extreme_comparisons.rs @@ -11,24 +11,26 @@ use clippy_utils::ty::is_isize_or_usize; use clippy_utils::{clip, int_bits, unsext}; 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 /// case that is always true or always false. Only integer and boolean types are /// 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 /// `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 /// a comparison to detect target pointer width will trigger this lint. One can /// use `mem::sizeof` and compare its value or conditional compilation /// attributes /// like `#[cfg(target_pointer_width = "64")] ..` instead. /// - /// **Example:** - /// + /// ### Example /// ```rust /// let vec: Vec = Vec::new(); /// if vec.len() <= 0 {} diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs index 3d04abe094d..6100f4e435a 100644 --- a/src/tools/clippy/clippy_lints/src/approx_const.rs +++ b/src/tools/clippy/clippy_lints/src/approx_const.rs @@ -7,21 +7,21 @@ use rustc_span::symbol; use std::f64::consts as f64; 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 /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) /// or /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), /// 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 /// actually more precise, please [file a Rust /// issue](https://github.com/rust-lang/rust/issues). /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = 3.14; /// let y = 1_f64 / x; diff --git a/src/tools/clippy/clippy_lints/src/arithmetic.rs b/src/tools/clippy/clippy_lints/src/arithmetic.rs index 24c2a972811..36fe7b7a867 100644 --- a/src/tools/clippy/clippy_lints/src/arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/arithmetic.rs @@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; 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 /// of overflowing according to the [Rust @@ -14,13 +15,12 @@ declare_clippy_lint! { /// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is /// 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 /// wants explicitly checked, wrapping or saturating arithmetic. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let a = 0; /// a + 1; @@ -31,14 +31,14 @@ 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let a = 0.0; /// a + 1.0; diff --git a/src/tools/clippy/clippy_lints/src/as_conversions.rs b/src/tools/clippy/clippy_lints/src/as_conversions.rs index 4b31e16094e..7c39a3e2ce3 100644 --- a/src/tools/clippy/clippy_lints/src/as_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/as_conversions.rs @@ -5,7 +5,8 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_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` /// 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 /// [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. /// There are cases when it makes sense to use `as`, so the lint is /// Allow by default. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// let a: u32; /// ... diff --git a/src/tools/clippy/clippy_lints/src/asm_syntax.rs b/src/tools/clippy/clippy_lints/src/asm_syntax.rs index b970c71b753..825832eb79d 100644 --- a/src/tools/clippy/clippy_lints/src/asm_syntax.rs +++ b/src/tools/clippy/clippy_lints/src/asm_syntax.rs @@ -53,14 +53,14 @@ fn check_expr_asm_syntax(lint: &'static Lint, cx: &EarlyContext<'_>, expr: &Expr } 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```rust,no_run /// # #![feature(asm)] @@ -89,14 +89,14 @@ impl EarlyLintPass for InlineAsmX86IntelSyntax { } 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```rust,no_run /// # #![feature(asm)] diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs index 5235b2642d1..cb9347a923d 100644 --- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs +++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs @@ -8,14 +8,17 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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!()` /// - /// **Known problems:** None + /// ### Known problems + /// None /// - /// **Example:** + /// ### Example /// ```rust,ignore /// assert!(false) /// assert!(true) diff --git a/src/tools/clippy/clippy_lints/src/assign_ops.rs b/src/tools/clippy/clippy_lints/src/assign_ops.rs index 17ce3cd809f..2097a1feff9 100644 --- a/src/tools/clippy/clippy_lints/src/assign_ops.rs +++ b/src/tools/clippy/clippy_lints/src/assign_ops.rs @@ -12,15 +12,18 @@ use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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. /// - /// **Example:** + /// ### Example /// ```rust /// let mut a = 5; /// let b = 0; @@ -37,17 +40,20 @@ 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`. /// - /// **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. /// If `a op= a op b` is really the correct behaviour it should be /// written as `a = a op a op b` as it's less confusing. /// - /// **Example:** + /// ### Example /// ```rust /// let mut a = 5; /// let b = 2; diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs index e6c7c68f91a..182736a5a20 100644 --- a/src/tools/clippy/clippy_lints/src/async_yields_async.rs +++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs @@ -7,15 +7,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **Why is this bad?** An await is likely missing. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// An await is likely missing. /// + /// ### Example /// ```rust /// async fn foo() {} /// diff --git a/src/tools/clippy/clippy_lints/src/atomic_ordering.rs b/src/tools/clippy/clippy_lints/src/atomic_ordering.rs index 7ceb01f5590..cece28e8b3c 100644 --- a/src/tools/clippy/clippy_lints/src/atomic_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/atomic_ordering.rs @@ -8,16 +8,16 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_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 /// 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,no_run /// # use std::sync::atomic::{self, AtomicU8, Ordering}; /// diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index f272ed010a1..c9ff468874b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -41,10 +41,12 @@ static UNIX_SYSTEMS: &[&str] = &[ static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"]; 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. /// - /// **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 /// 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 /// 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 /// done the measurement. /// - /// **Example:** + /// ### Example /// ```ignore /// #[inline(always)] /// fn not_quite_hot_code(..) { ... } @@ -67,7 +70,8 @@ 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. /// /// 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 /// `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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// // Bad /// #[deny(dead_code)] @@ -101,15 +104,15 @@ 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// #[deprecated(since = "forever")] /// fn something_else() { /* ... */ } @@ -120,20 +123,22 @@ 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 '!'. /// If it was meant to be an outer attribute, then the following item /// 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 /// following item because empty lines and comments are not part of the AST. The parsing /// currently works for basic cases but is not perfect. /// - /// **Example:** + /// ### Example /// ```rust /// // Good (as inner attribute) /// #![allow(dead_code)] @@ -155,14 +160,14 @@ 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust /// #![deny(clippy::restriction)] @@ -178,18 +183,20 @@ 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]`. /// - /// **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. /// - /// **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 /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765) /// - /// **Example:** - /// + /// ### Example /// Bad: /// ```rust /// #[cfg_attr(rustfmt, rustfmt_skip)] @@ -207,15 +214,14 @@ 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. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// Bad: /// ```rust /// #[cfg(linux)] diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs index 1739a57a240..0cc79c8b6e8 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs @@ -8,10 +8,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; 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. /// - /// **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. /// /// 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, /// 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)). - /// - /// **Example:** + /// ### Known problems + /// Will report false positive for explicitly dropped guards ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). /// + /// ### Example /// ```rust,ignore /// use std::sync::Mutex; /// @@ -51,17 +53,19 @@ 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`. /// - /// **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 /// 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)). - /// - /// **Example:** + /// ### Known problems + /// Will report false positive for explicitly dropped refs ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). /// + /// ### Example /// ```rust,ignore /// use std::cell::RefCell; /// diff --git a/src/tools/clippy/clippy_lints/src/bit_mask.rs b/src/tools/clippy/clippy_lints/src/bit_mask.rs index 991ed94572c..11346e7c96a 100644 --- a/src/tools/clippy/clippy_lints/src/bit_mask.rs +++ b/src/tools/clippy/clippy_lints/src/bit_mask.rs @@ -10,7 +10,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; 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 `_ m /// c` (where `` is one of {`&`, `|`} and `` is one of @@ -26,7 +27,8 @@ declare_clippy_lint! { /// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`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 /// `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 /// test-case for this lint. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// if (x & 1 == 2) { } @@ -47,7 +47,8 @@ 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 /// following table: /// @@ -56,16 +57,18 @@ declare_clippy_lint! { /// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`| /// |`<` / `>=`|`|` / `^`|`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. /// - /// **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 /// 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 /// uncommon). /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// if (x | 1 > 3) { } @@ -76,15 +79,18 @@ 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` /// - /// **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` /// - /// **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 /// # let x = 1; /// if x & 0b1111 == 0 { } diff --git a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs b/src/tools/clippy/clippy_lints/src/blacklisted_name.rs index 8eb94f3c28e..916c78c982a 100644 --- a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs +++ b/src/tools/clippy/clippy_lints/src/blacklisted_name.rs @@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; 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`. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let foo = 3.14; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs index badcf8d2a43..9b2e4f8998e 100644 --- a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs +++ b/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs @@ -13,14 +13,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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. /// - /// **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 /// // Bad /// if { true } { /* ... */ } diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index bee706ed402..8d3f68565b2 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -6,14 +6,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// It is shorter to use the equivalent. /// + /// ### Example /// ```rust /// // Bad /// assert_eq!("a".is_empty(), false); diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index e72399af232..4a83d35a568 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -14,16 +14,19 @@ use rustc_span::source_map::Span; use rustc_span::sym; 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. /// - /// **Why is this bad?** Readability of boolean expressions suffers from + /// ### Why is this bad? + /// Readability of boolean expressions suffers from /// unnecessary duplication. /// - /// **Known problems:** Ignores short circuiting behavior of `||` and + /// ### Known problems + /// Ignores short circuiting behavior of `||` and /// `&&`. Ignores `|`, `&` and `^`. /// - /// **Example:** + /// ### Example /// ```ignore /// if a && true // should be: if a /// if !(a == b) // should be: if a != b @@ -34,14 +37,17 @@ 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. /// - /// **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 /// if a && b || a { ... } /// ``` diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs index 4f7ffdcdfb4..c444984bc13 100644 --- a/src/tools/clippy/clippy_lints/src/bytecount.rs +++ b/src/tools/clippy/clippy_lints/src/bytecount.rs @@ -12,18 +12,20 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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. /// - /// **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 /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be /// faster in those cases. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # let vec = vec![1_u8]; /// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead diff --git a/src/tools/clippy/clippy_lints/src/cargo_common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo_common_metadata.rs index 21c7b2448ce..bd5426ba707 100644 --- a/src/tools/clippy/clippy_lints/src/cargo_common_metadata.rs +++ b/src/tools/clippy/clippy_lints/src/cargo_common_metadata.rs @@ -9,15 +9,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::DUMMY_SP; 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 /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```toml /// # This `Cargo.toml` is missing a description field: /// [package] diff --git a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs index c9ef379be56..86b32475ceb 100644 --- a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs @@ -8,17 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{source_map::Spanned, symbol::sym, Span}; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for calls to `ends_with` with possible file extensions /// 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. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// fn is_rust_file(filename: &str) -> bool { /// filename.ends_with(".rs") diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs index ae4fdd12c41..27e1bea7993 100644 --- a/src/tools/clippy/clippy_lints/src/casts/mod.rs +++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs @@ -20,7 +20,8 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; 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 /// rounding errors. This possible rounding is to be expected, so this lint is /// `Allow` by default. @@ -28,13 +29,12 @@ declare_clippy_lint! { /// Basically, this warns on casting any integer with 32 or more bits to `f32` /// 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 /// those places in the code. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = u64::MAX; /// x as f64; @@ -45,17 +45,17 @@ 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, /// which can be quite surprising in practice. However, as the cast works as /// 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let y: i8 = -1; /// y as u128; // will return 18446744073709551615 @@ -66,17 +66,17 @@ 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 /// 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 /// checks could be beneficial. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn as_u8(x: u64) -> u8 { /// x as u8 @@ -88,20 +88,20 @@ 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, /// 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 /// for the target signed type. However, the cast works as defined, so this lint /// 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 /// example below. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// u32::MAX as i32; // will yield a value of `-1` /// ``` @@ -111,19 +111,19 @@ 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. /// - /// **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 /// as `i32::from` will only perform lossless conversions. Using the conversion /// functions prevents conversions from turning into silent lossy conversions if /// the types of the input expressions ever change, and make it easier for /// people reading the code to know that the conversion is lossless. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn as_u64(x: u8) -> u64 { /// x as u64 @@ -143,14 +143,14 @@ 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. /// - /// **Why is this bad?** It's just unnecessary. + /// ### Why is this bad? + /// It's just unnecessary. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let _ = 2i32 as i32; /// let _ = 0.5 as f32; @@ -168,17 +168,20 @@ 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 /// - /// **Why is this bad?** Dereferencing the resulting pointer may be undefined + /// ### Why is this bad? + /// Dereferencing the resulting pointer may be undefined /// 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 /// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. /// - /// **Example:** + /// ### Example /// ```rust /// let _ = (&1u8 as *const u8) as *const u16; /// let _ = (&mut 1u8 as *mut u8) as *mut u16; @@ -192,9 +195,10 @@ 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 /// 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 @@ -202,8 +206,7 @@ declare_clippy_lint! { /// /// Casting to isize also doesn't make sense since there are no signed addresses. /// - /// **Example** - /// + /// ### Example /// ```rust /// // Bad /// fn fun() -> i32 { 1 } @@ -219,16 +222,16 @@ 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. /// - /// **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 /// clearly expressed by casting to usize first, then casting the usize to the intended type (with /// a comment) to perform the truncation. /// - /// **Example** - /// + /// ### Example /// ```rust /// // Bad /// fn fn1() -> i16 { @@ -249,15 +252,15 @@ 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?** It’s basically guaranteed to be undefined behaviour. + /// ### Why is this bad? + /// It’s basically guaranteed to be undefined behaviour. /// `UnsafeCell` is the only way to obtain aliasable data that is considered /// mutable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// fn x(r: &i32) { /// unsafe { @@ -283,18 +286,18 @@ 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. /// - /// **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 /// 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 /// than `'a' as u8`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// 'x' as u8 /// ``` @@ -310,18 +313,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for `as` casts between raw pointers without changing its mutability, /// 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 /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let ptr: *const u32 = &42_u32; /// let mut_ptr: *mut u32 = &mut 42_u32; diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs index 8d3123e1ec8..842bbf006cc 100644 --- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs @@ -13,13 +13,13 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; 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 /// # let foo: u32 = 5; /// # let _ = diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index f62c6a9c325..96c30d57ee1 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -14,15 +14,19 @@ use rustc_span::source_map::Span; use rustc_span::{sym, BytePos}; 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. /// - /// **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. /// - /// **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, nursery, "functions that should be split up into multiple functions" diff --git a/src/tools/clippy/clippy_lints/src/collapsible_if.rs b/src/tools/clippy/clippy_lints/src/collapsible_if.rs index 6e950738239..4aa87980715 100644 --- a/src/tools/clippy/clippy_lints/src/collapsible_if.rs +++ b/src/tools/clippy/clippy_lints/src/collapsible_if.rs @@ -22,15 +22,15 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// if x { /// if y { @@ -53,15 +53,15 @@ 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 ...`. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// /// if x { diff --git a/src/tools/clippy/clippy_lints/src/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/collapsible_match.rs index a6c3a5b0e83..a403a9846ba 100644 --- a/src/tools/clippy/clippy_lints/src/collapsible_match.rs +++ b/src/tools/clippy/clippy_lints/src/collapsible_match.rs @@ -9,18 +9,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{MultiSpan, Span}; 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. /// /// 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. /// - /// **Why is this bad?** It is unnecessarily verbose and complex. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// It is unnecessarily verbose and complex. /// + /// ### Example /// ```rust /// fn func(opt: Option>) { /// let n = match opt { diff --git a/src/tools/clippy/clippy_lints/src/comparison_chain.rs b/src/tools/clippy/clippy_lints/src/comparison_chain.rs index b6999bef6e7..597a3c67024 100644 --- a/src/tools/clippy/clippy_lints/src/comparison_chain.rs +++ b/src/tools/clippy/clippy_lints/src/comparison_chain.rs @@ -6,16 +6,19 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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`. /// - /// **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 /// - /// **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) /// - /// **Example:** + /// ### Example /// ```rust,ignore /// # fn a() {} /// # fn b() {} diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs index 9cbcde59768..2dcd5545799 100644 --- a/src/tools/clippy/clippy_lints/src/copies.rs +++ b/src/tools/clippy/clippy_lints/src/copies.rs @@ -16,13 +16,13 @@ use rustc_span::{source_map::Span, symbol::Symbol, BytePos}; use std::borrow::Cow; 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 /// if a == b { /// … @@ -47,15 +47,15 @@ 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 /// intended, such an approach is implicit and can be considered a "code smell". /// - /// **Known problems:** Hopefully none. - /// - /// **Example:** + /// ### Example /// ```ignore /// if foo() == bar { /// … @@ -94,14 +94,14 @@ 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. /// - /// **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 /// let foo = if … { /// 42 @@ -115,17 +115,19 @@ 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. /// - /// **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 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) /// - /// **Example:** + /// ### Example /// ```ignore /// let foo = if … { /// println!("Hello World"); diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs index 35079c6bedc..c2e9e8b3ab7 100644 --- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs @@ -8,15 +8,15 @@ use rustc_span::sym; use if_chain::if_chain; 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`. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// #[derive(Copy, Clone)] /// struct Countdown(u8); diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs index 7b5cce6462a..e4ee2772483 100644 --- a/src/tools/clippy/clippy_lints/src/create_dir.rs +++ b/src/tools/clippy/clippy_lints/src/create_dir.rs @@ -8,13 +8,13 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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 /// std::fs::create_dir("foo"); diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs index 286cc7e223e..bab4a696f83 100644 --- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs +++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs @@ -8,14 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// dbg!(true) diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 947479db8f5..db8f2171348 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -13,14 +13,14 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; 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`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let s: String = Default::default(); @@ -34,14 +34,17 @@ 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(). /// - /// **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: /// ``` /// # #[derive(Default)] diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index e719a1b0abf..3f1b7ea6214 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -18,7 +18,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::iter; 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. /// /// 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. /// - /// **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. /// - /// **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 /// let i = 10; /// let f = 1.23; diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index 2933fbc9341..c604516742c 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -12,27 +12,33 @@ macro_rules! 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. pub SHOULD_ASSERT_EQ, "`assert!()` will be more flexible with RFC 2011" } 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. pub EXTEND_FROM_SLICE, "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice" } 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`, /// but the method has been removed for `Iterator::step_by` which panics /// if given a zero @@ -41,27 +47,33 @@ 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. pub UNSTABLE_AS_SLICE, "`Vec::as_slice` has been stabilized in 1.7" } 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. pub UNSTABLE_AS_MUT_SLICE, "`Vec::as_mut_slice` has been stabilized in 1.7" } 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 /// equivalent to a memcpy). This lint has thus been refactored into two separate lints: /// cast_ptr_alignment and transmute_ptr_to_ptr. @@ -70,9 +82,11 @@ 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 /// counterparts, so this lint may suggest a change in behavior or the code may not compile. pub ASSIGN_OPS, @@ -80,9 +94,11 @@ 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. /// So, this lint is deprecated. pub IF_LET_REDUNDANT_PATTERN_MATCHING, @@ -90,9 +106,11 @@ 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 /// replacement has very different performance characteristics so the lint is /// deprecated. @@ -101,51 +119,63 @@ 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, "`collect` has been marked as #[must_use] in rustc and that covers all cases of this 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, "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants" } 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, "the regex! macro has been removed from the regex crate in 2018" } 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. pub FIND_MAP, "this lint has been replaced by `manual_find_map`, a more specific 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. pub FILTER_MAP, "this lint has been replaced by `manual_filter_map`, a more specific 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. /// ``` pub PUB_ENUM_VARIANT_NAMES, @@ -153,9 +183,11 @@ 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. 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" diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 682003f9c2c..ded7001ad8c 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -11,12 +11,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{symbol::sym, Span}; 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. /// - /// **Example:** + /// ### Example /// ```rust /// use std::ops::Deref; /// let a: &mut String = &mut String::from("foo"); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 7aafaf71383..dcfa5253f83 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -15,10 +15,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; 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. /// - /// **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 it’s probably a bad idea to use a /// default-generated `Hash` implementation with an explicitly defined /// `PartialEq`. In particular, the following must hold for any type: @@ -27,9 +29,7 @@ declare_clippy_lint! { /// k1 == k2 ⇒ hash(k1) == hash(k2) /// ``` /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// #[derive(Hash)] /// struct Foo; @@ -44,10 +44,12 @@ 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. /// - /// **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 it’s probably a bad idea to use a /// default-generated `Ord` implementation with an explicitly defined /// `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() /// ``` /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// #[derive(Ord, PartialEq, Eq)] /// struct Foo; @@ -95,18 +94,21 @@ 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. /// - /// **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 /// situations a `Copy` type should have a `Clone` implementation that does /// nothing more than copy the object, which is what `#[derive(Copy, Clone)]` /// 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 /// #[derive(Copy)] /// struct Foo; @@ -121,16 +123,15 @@ 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`. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// use serde::Deserialize; /// diff --git a/src/tools/clippy/clippy_lints/src/disallowed_method.rs b/src/tools/clippy/clippy_lints/src/disallowed_method.rs index aa1a609afed..7069cb4198c 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_method.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_method.rs @@ -8,15 +8,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Symbol; 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. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// An example clippy.toml configuration: /// ```toml /// # clippy.toml diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs index 12c525634c5..6d38d30cd0b 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs @@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use unicode_script::{Script, UnicodeScript}; 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. /// /// 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 /// [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. /// /// 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 /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Assuming that `clippy.toml` contains the following line: /// // allowed-locales = ["Latin", "Cyrillic"] diff --git a/src/tools/clippy/clippy_lints/src/disallowed_type.rs b/src/tools/clippy/clippy_lints/src/disallowed_type.rs index e4a88c6324e..e627168b932 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_type.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_type.rs @@ -2,27 +2,24 @@ use clippy_utils::diagnostics::span_lint; use rustc_data_structures::fx::FxHashSet; 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_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{Span, Symbol}; 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. - /// - /// **Known problems:** None. - /// - /// N.B. There is no way to ban primitive types. - /// - /// **Example:** + /// ### Why is this bad? + /// Some types are undesirable in certain contexts. /// + /// ### Example: /// An example clippy.toml configuration: /// ```toml /// # clippy.toml - /// disallowed-methods = ["std::collections::BTreeMap"] + /// disallowed-types = ["std::collections::BTreeMap"] /// ``` /// /// ```rust,ignore @@ -42,7 +39,8 @@ declare_clippy_lint! { #[derive(Clone, Debug)] pub struct DisallowedType { disallowed: FxHashSet>, - def_ids: FxHashSet<(DefId, Vec)>, + def_ids: FxHashSet, + prim_tys: FxHashSet, } impl DisallowedType { @@ -53,6 +51,23 @@ impl DisallowedType { .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::>()) .collect(), 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<'_>) { for path in &self.disallowed { let segs = path.iter().map(ToString::to_string).collect::>(); - if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::>()) - { - self.def_ids.insert((id, path.clone())); + match clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::>()) { + Res::Def(_, id) => { + 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>) { - if_chain! { - if let ItemKind::Use(path, UseKind::Single) = &item.kind; - 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,); - } + if let ItemKind::Use(path, UseKind::Single) = &item.kind { + self.check_res_emit(cx, &path.res, item.span); } } fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) { - if_chain! { - if let TyKind::Path(path) = &ty.kind; - 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()); - } + if let TyKind::Path(path) = &ty.kind { + self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span); } } fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) { - if_chain! { - 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); - } - } + self.check_res_emit(cx, &poly.trait_ref.path.res, 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) { - let name = name.iter().map(|s| s.to_ident_string()).collect::>().join("::"); +fn emit(cx: &LateContext<'_>, name: &str, span: Span) { span_lint( cx, DISALLOWED_TYPE, diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 0c19988a975..c39829fdc7a 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -30,15 +30,18 @@ use std::thread; use url::Url; 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. /// - /// **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 /// ticks. `_` can also be used for emphasis in markdown, this lint tries to /// consider that. /// - /// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks + /// ### Known problems + /// Lots of bad docs won’t be fixed, what the lint checks /// for is limited, and there are still false positives. HTML elements and their /// content are not linted. /// @@ -47,7 +50,7 @@ declare_clippy_lint! { /// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec /// would fail. /// - /// **Examples:** + /// ### Examples /// ```rust /// /// Do something with the foo_bar parameter. See also /// /// that::other::module::foo. @@ -68,15 +71,15 @@ 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust ///# type Universe = (); /// /// This function should really be documented @@ -102,16 +105,15 @@ 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Examples:** - /// + /// ### Examples /// Since the following function returns a `Result` it has an `# Errors` section in /// its doc comment: /// @@ -131,16 +133,15 @@ 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Examples:** - /// + /// ### Examples /// Since the following function may panic it has a `# Panics` section in /// its doc comment: /// @@ -162,14 +163,14 @@ 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. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ``````rust /// /// An example of a doctest with a `main()` function /// /// diff --git a/src/tools/clippy/clippy_lints/src/double_comparison.rs b/src/tools/clippy/clippy_lints/src/double_comparison.rs index 4966638cb1b..6520bb91faf 100644 --- a/src/tools/clippy/clippy_lints/src/double_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/double_comparison.rs @@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; 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 /// # let x = 1; /// # let y = 2; diff --git a/src/tools/clippy/clippy_lints/src/double_parens.rs b/src/tools/clippy/clippy_lints/src/double_parens.rs index e4e4a93b011..d0d87b6df9a 100644 --- a/src/tools/clippy/clippy_lints/src/double_parens.rs +++ b/src/tools/clippy/clippy_lints/src/double_parens.rs @@ -4,14 +4,14 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// fn simple_double_parens() -> i32 { diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index b5b29760636..0f3dc866afb 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -8,17 +8,17 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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 /// the `Drop` trait implementation) on the underlying referenced value, which /// is likely what was intended. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// let mut lock_guard = mutex.lock(); /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex @@ -31,17 +31,17 @@ 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. /// - /// **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 /// referenced /// value, which is likely what was intended. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = Box::new(1); /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped @@ -52,16 +52,16 @@ 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 /// - /// **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 /// value will be copied and moved into the function on invocation. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x: i32 = 42; // i32 implements Copy /// 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! { - /// **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 /// - /// **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 /// value will be copied and moved into the function on invocation. /// @@ -86,9 +88,7 @@ declare_clippy_lint! { /// there /// is nothing for `std::mem::forget` to ignore. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x: i32 = 42; // i32 implements Copy /// std::mem::forget(x) // A copy of x is passed to the function, leaving the diff --git a/src/tools/clippy/clippy_lints/src/duration_subsec.rs b/src/tools/clippy/clippy_lints/src/duration_subsec.rs index 94b09bf7173..3774de62521 100644 --- a/src/tools/clippy/clippy_lints/src/duration_subsec.rs +++ b/src/tools/clippy/clippy_lints/src/duration_subsec.rs @@ -12,15 +12,15 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::paths; 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::time::Duration; /// let dur = Duration::new(5, 0); diff --git a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs index 26984df9539..0541ac5eccc 100644 --- a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs +++ b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs @@ -7,14 +7,14 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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 /// # fn a() {} /// # fn b() {} diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index c92984a9834..3453c2da278 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -6,13 +6,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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 /// nightly-only experimental API. Therefore, this lint is only triggered /// 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"), /// or a wrapper around it, because `!` has more extensive /// 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) /// /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// Bad: /// ```rust /// enum Test {} diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs index 2eb8b1422ed..e1d0d65edb1 100644 --- a/src/tools/clippy/clippy_lints/src/entry.rs +++ b/src/tools/clippy/clippy_lints/src/entry.rs @@ -16,12 +16,15 @@ use rustc_span::{Span, SyntaxContext, DUMMY_SP}; use std::fmt::Write; 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`. /// - /// **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 /// let mut map = std::collections::HashMap::new(); /// let _ = if !map.contains_key(&0) { @@ -31,7 +34,7 @@ declare_clippy_lint! { /// }; /// ``` /// - /// **Example:** + /// ### Example /// ```rust /// # use std::collections::HashMap; /// # let mut map = HashMap::new(); diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index 021136ac5e0..a2c3c7a7b49 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -11,15 +11,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::convert::TryFrom; 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`. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # #[cfg(target_pointer_width = "64")] /// #[repr(usize)] diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs index b1a105a51c1..32b95745b64 100644 --- a/src/tools/clippy/clippy_lints/src/enum_variants.rs +++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs @@ -10,15 +10,15 @@ use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// enum Cake { /// BlackForestCake, @@ -40,14 +40,14 @@ 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. /// - /// **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 /// mod cake { /// struct BlackForestCake; @@ -65,10 +65,12 @@ 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 /// - /// **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 { .. /// }` in `foo.rs`. /// 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 /// representative module name. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// // lib.rs /// mod foo; diff --git a/src/tools/clippy/clippy_lints/src/eq_op.rs b/src/tools/clippy/clippy_lints/src/eq_op.rs index d39cabfb282..51d5094e8c9 100644 --- a/src/tools/clippy/clippy_lints/src/eq_op.rs +++ b/src/tools/clippy/clippy_lints/src/eq_op.rs @@ -9,18 +9,21 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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., `&&`, /// `||`, `&`, `|`, `^`, `-` 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 /// 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. /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// if x + 1 == x + 1 {} @@ -37,15 +40,18 @@ 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 /// 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 /// // Bad /// &x == y diff --git a/src/tools/clippy/clippy_lints/src/erasing_op.rs b/src/tools/clippy/clippy_lints/src/erasing_op.rs index 4aa9c25b1b0..026d14d0ea2 100644 --- a/src/tools/clippy/clippy_lints/src/erasing_op.rs +++ b/src/tools/clippy/clippy_lints/src/erasing_op.rs @@ -6,15 +6,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; 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 /// corrected /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = 1; /// 0 / x; diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 5f400d079da..8b0e9e6bc9b 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -19,16 +19,16 @@ pub struct BoxedLocal { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `Box` where an unboxed `T` would + /// ### What it does + /// Checks for usage of `Box` where an unboxed `T` would /// 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 /// into something. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn foo(bar: usize) {} /// // Bad diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 667eb8eb283..192b69e18f9 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -14,19 +14,22 @@ use rustc_middle::ty::{self, ClosureKind, Ty}; use rustc_session::{declare_lint_pass, declare_tool_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 /// 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. /// - /// **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 runs. /// See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// xs.map(|x| foo(x)) @@ -42,17 +45,20 @@ 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. /// - /// **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), /// [#4002](https://github.com/rust-lang/rust-clippy/issues/4002) /// /// - /// **Example:** + /// ### Example /// ```rust,ignore /// Some('a').map(|s| s.to_uppercase()); /// ``` diff --git a/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs b/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs index 03a8b40df55..f72a1e446d5 100644 --- a/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs +++ b/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs @@ -9,17 +9,20 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_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 /// 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. /// - /// **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. /// - /// **Example:** + /// ### Example /// ```rust /// let mut x = 0; /// @@ -43,16 +46,19 @@ 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. /// - /// **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. /// - /// **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. /// - /// **Example:** + /// ### Example /// ```rust,no_run /// # fn b() -> bool { true } /// # fn c() -> bool { true } diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs index 4e2dbf005d5..476e6d23f12 100644 --- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs +++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs @@ -8,19 +8,19 @@ use rustc_span::{sym, Span}; use std::convert::TryInto; declare_clippy_lint! { - /// **What it does:** Checks for excessive + /// ### What it does + /// Checks for excessive /// 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, /// which is much better implemented as an enum. /// If it's not the case, excessive bools usually benefit /// from refactoring into two-variant enums for better /// readability and API. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust /// struct S { @@ -44,19 +44,19 @@ 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. /// - /// **Why is this bad?** Calls to such functions + /// ### Why is this bad? + /// Calls to such functions /// are confusing and error prone, because it's /// hard to remember argument order and you have /// no type system support to back you up. Using /// two-variant enums instead of bools often makes /// API easier to use. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// fn f(is_round: bool, is_hot: bool) { ... } diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 60ad2e8ee14..e00126046c0 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -8,16 +8,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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 /// disable them by default. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// enum Foo { /// Bar, @@ -38,16 +37,15 @@ 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 /// disable them by default. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct Foo { /// bar: u8, diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index 16246e548b6..9cd5b2d9f44 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -6,15 +6,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// std::process::exit(0) /// ``` diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs index 66724294804..4f46ef906f4 100644 --- a/src/tools/clippy/clippy_lints/src/explicit_write.rs +++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs @@ -9,14 +9,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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!()` /// - /// **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 /// # use std::io::Write; /// # let bar = "furchtbar"; diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 2937fcb9ca0..7e4d1b3ef9f 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -10,13 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span}; 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 /// struct Foo(i32); /// diff --git a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs index 1e503cc795c..c33d80b8e8e 100644 --- a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs +++ b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs @@ -11,30 +11,32 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; declare_clippy_lint! { - /// **What it does:** 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. - /// - /// **Known problems:** If the user can ensure that b is larger than a, the `.abs()` is - /// 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 - /// reasons, it is probably better to state this explicitly in the code, which then can be done - /// with an allow. - /// - /// **Example:** - /// - /// ```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 { - /// (a - b).abs() < f32::EPSILON - /// } - /// ``` + /// ### What it does + /// 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. + /// + /// ### Known problems + /// If the user can ensure that b is larger than a, the `.abs()` is + /// 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 + /// reasons, it is probably better to state this explicitly in the code, which then can be done + /// with an allow. + /// + /// ### Example + /// ```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 { + /// (a - b).abs() < f32::EPSILON + /// } + /// ``` pub FLOAT_EQUALITY_WITHOUT_ABS, suspicious, "float equality check without `.abs()`" diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs index 7968e7b764d..a3d70f31f00 100644 --- a/src/tools/clippy/clippy_lints/src/float_literal.rs +++ b/src/tools/clippy/clippy_lints/src/float_literal.rs @@ -10,15 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::fmt; 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. /// - /// **Why is this bad?** Rust will truncate the literal silently. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Rust will truncate the literal silently. /// + /// ### Example /// ```rust /// // Bad /// let v: f32 = 0.123_456_789_9; @@ -34,16 +33,15 @@ 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. /// - /// **Why is this bad?** Rust will silently lose precision during + /// ### Why is this bad? + /// Rust will silently lose precision during /// conversion to a float. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let _: f32 = 16_777_217.0; // 16_777_216.0 diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs index e38384b01d4..b01c0cdd846 100644 --- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs @@ -18,16 +18,15 @@ use std::f64::consts as f64_consts; use sugg::Sugg; 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 /// at the cost of performance. /// - /// **Why is this bad?** Negatively impacts accuracy. - /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Why is this bad? + /// Negatively impacts accuracy. /// + /// ### Example /// ```rust /// let a = 3f32; /// let _ = a.powf(1.0 / 3.0); @@ -49,16 +48,15 @@ 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 /// accuracy and performance. /// - /// **Why is this bad?** Negatively impacts accuracy and performance. - /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Why is this bad? + /// Negatively impacts accuracy and performance. /// + /// ### Example /// ```rust /// use std::f32::consts::E; /// diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs index ca3490d8eda..863c606f5a9 100644 --- a/src/tools/clippy/clippy_lints/src/format.rs +++ b/src/tools/clippy/clippy_lints/src/format.rs @@ -13,18 +13,18 @@ use rustc_span::symbol::kw; use rustc_span::{sym, Span}; 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. /// - /// **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 /// worse `&format!("foo")` is often encountered in the wild. `format!("{}", /// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()` /// if `foo: &str`. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust /// /// // Bad diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs index 8aefb8d46f6..b4cf1971d78 100644 --- a/src/tools/clippy/clippy_lints/src/formatting.rs +++ b/src/tools/clippy/clippy_lints/src/formatting.rs @@ -9,15 +9,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// a =- 42; // confusing, should it be `a -= 42` or `a = -42`? /// ``` @@ -27,15 +27,15 @@ 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, /// 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 /// if foo <- 30 { // this should be `foo < -30` but looks like a different operator /// } @@ -49,15 +49,15 @@ 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// if foo { /// } { // looks like an `else` is missing here @@ -85,14 +85,14 @@ 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. /// - /// **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 /// let a = &[ /// -1, -2, -3 // <= no comma here diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 3560672a748..623546cd1de 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -1,21 +1,20 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::paths::INTO; -use clippy_utils::{match_def_path, meets_msrv, msrvs}; +use clippy_utils::{meets_msrv, msrvs}; use if_chain::if_chain; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::symbol::sym; 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. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### 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. /// + /// ### Example /// ```rust /// struct StringWrapper(String); /// @@ -62,7 +61,7 @@ impl LateLintPass<'_> for FromOverInto { if_chain! { if let hir::ItemKind::Impl{ .. } = &item.kind; 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 { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs index 3da5bc95b6d..cc4bb85c50f 100644 --- a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs +++ b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs @@ -10,20 +10,22 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** + /// ### What it does + /// /// 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::()` /// (and in most cases, the turbofish can be removed), which reduces code length /// and complexity. /// - /// **Known problems:** + /// ### Known problems + /// /// This lint may suggest using (&).parse() instead of .parse() directly /// in some cases, which is correct but adds unnecessary complexity to the code. /// - /// **Example:** - /// + /// ### Example /// ```ignore /// let input: &str = get_input(); /// let num = u16::from_str_radix(input, 10)?; diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs index 2beb9bc94bf..ce23c0ce4a0 100644 --- a/src/tools/clippy/clippy_lints/src/functions/mod.rs +++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs @@ -11,15 +11,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; 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 /// grouping some parameters into a new type. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct Color; /// 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! { - /// **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 /// function is doing. Consider splitting the body of the function into /// multiple functions. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn im_too_long() { /// println!(""); @@ -55,15 +55,16 @@ 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`. /// - /// **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 /// valid. /// - /// **Known problems:** - /// + /// ### Known problems /// * 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 /// trigger. @@ -71,7 +72,7 @@ declare_clippy_lint! { /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or /// `some_argument.get_raw_ptr()`). /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// pub fn foo(x: *const u8) { @@ -89,17 +90,17 @@ 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. /// /// [`#[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. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust /// #[must_use] /// fn useless() { } @@ -110,19 +111,19 @@ 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 /// marked as `#[must_use]`. /// /// [`#[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 /// attribute to improve the lint message. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust /// #[must_use] /// fn double_must_use() -> Result<(), ()> { @@ -135,16 +136,19 @@ 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, have no mutable arg and mutate no statics. /// /// [`#[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. /// - /// **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, /// it also ignores a broad range of potentially interesting side effects, /// 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 /// `#[must_use]`. /// - /// **Examples:** + /// ### Examples /// ```rust /// // this could be annotated with `#[must_use]`. /// fn id(t: T) -> T { t } @@ -163,20 +167,23 @@ 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 /// 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. /// - /// **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 /// 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 /// instead. /// - /// **Examples:** + /// ### Examples /// ```rust /// pub fn read_u8() -> Result { Err(()) } /// ``` diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 515b8887453..0be03969bcb 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -12,12 +12,14 @@ use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt; use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine}; 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 /// used by library authors (public and internal) that target an audience where /// 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 /// 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 @@ -31,10 +33,7 @@ declare_clippy_lint! { /// modifying the library where the offending Future implementation is /// produced. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// async fn not_send(bytes: std::rc::Rc<[u8]>) {} /// ``` diff --git a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs index 8e45fdfecc4..ced35030de8 100644 --- a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs +++ b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs @@ -14,10 +14,12 @@ use rustc_span::source_map::Spanned; use rustc_span::sym; 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()`. /// - /// **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. /// /// 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 /// `x.get(index).unwrap()` instead of `x[index]`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let x = vec![2, 3, 5]; diff --git a/src/tools/clippy/clippy_lints/src/identity_op.rs b/src/tools/clippy/clippy_lints/src/identity_op.rs index 99c461930e4..5feb0ce8dec 100644 --- a/src/tools/clippy/clippy_lints/src/identity_op.rs +++ b/src/tools/clippy/clippy_lints/src/identity_op.rs @@ -11,14 +11,14 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::{clip, unsext}; 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// x / 1 + 0 * 1 - 0 | 0; diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs index 5403d76ea30..d3ddeda9fd1 100644 --- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs +++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs @@ -9,16 +9,15 @@ use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// if let Ok(thing) = mutex.lock() { /// do_thing(); diff --git a/src/tools/clippy/clippy_lints/src/if_let_some_result.rs b/src/tools/clippy/clippy_lints/src/if_let_some_result.rs index 611da3744ee..587307811a1 100644 --- a/src/tools/clippy/clippy_lints/src/if_let_some_result.rs +++ b/src/tools/clippy/clippy_lints/src/if_let_some_result.rs @@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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)` /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// for i in iter { /// if let Some(value) = i.parse().ok() { diff --git a/src/tools/clippy/clippy_lints/src/if_not_else.rs b/src/tools/clippy/clippy_lints/src/if_not_else.rs index c56f67df061..28db7233d70 100644 --- a/src/tools/clippy/clippy_lints/src/if_not_else.rs +++ b/src/tools/clippy/clippy_lints/src/if_not_else.rs @@ -8,14 +8,14 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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 /// # let v: Vec = vec![]; /// # fn a() {} diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs index eadcd0867a8..17b9a2f888e 100644 --- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs +++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs @@ -10,14 +10,13 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; 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. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Looks a little redundant. Using `bool::then` helps it have less lines of code. /// + /// ### Example /// ```rust /// # let v = vec![0]; /// let a = if v.is_empty() { diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs index ad4898d1ccb..31b3fd4a538 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs @@ -5,7 +5,7 @@ use std::collections::BTreeMap; use rustc_errors::DiagnosticBuilder; 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_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -19,24 +19,26 @@ use rustc_typeck::hir_ty_to_ty; use if_chain::if_chain; 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::ty::is_type_diagnostic_item; -use clippy_utils::{differing_macro_contexts, match_def_path}; 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 /// 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. /// - /// **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 /// pieces of code, possibly including external crates. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::collections::HashMap; /// # use std::hash::{Hash, BuildHasher}; @@ -347,7 +349,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't 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 { self.suggestions .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 { self.suggestions .insert(e.span, "HashSet::default()".to_string()); diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs index f2f830ca5c0..fa7b5302cb1 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_return.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs @@ -13,17 +13,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{Span, SyntaxContext}; 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 /// 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 /// corresponding statements. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn foo(x: usize) -> usize { /// x diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 4069a685ea0..0a7d31dce2f 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -8,14 +8,13 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Simplicity and readability. Instead we can easily use an builtin function. /// + /// ### Example /// ```rust /// let end: u32 = 10; /// let start: u32 = 5; diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs index 3b635071f28..1f8240a1f63 100644 --- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs @@ -10,11 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::Symbol; 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 /// 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, /// /// ```rust @@ -32,10 +34,7 @@ declare_clippy_lint! { /// /// inconsistent order can be confusing and decreases readability and consistency. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct Foo { /// x: i32, diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index bfa284f333a..8c1f1073309 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -10,14 +10,17 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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 /// # #![allow(const_err)] /// let x = [1, 2, 3, 4]; @@ -36,16 +39,19 @@ 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 /// 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. /// - /// **Known problems:** Hopefully none. + /// ### Known problems + /// Hopefully none. /// - /// **Example:** + /// ### Example /// ```rust,no_run /// // Vector /// let x = vec![0; 5]; diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index 6b887da2630..2411a3175b9 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -1,19 +1,20 @@ 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 rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::{sym, Symbol}; 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// use std::iter; /// @@ -25,15 +26,18 @@ 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. /// - /// **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. /// - /// **Example:** + /// ### Example /// ```rust /// let infinite_iter = 0..; /// [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 -const INFINITE_COLLECTORS: [&[&str]; 8] = [ - &paths::BINARY_HEAP, - &paths::BTREEMAP, - &paths::BTREESET, - &paths::HASHMAP, - &paths::HASHSET, - &paths::LINKED_LIST, - &paths::VEC, - &paths::VEC_DEQUE, +const INFINITE_COLLECTORS: &[Symbol] = &[ + sym::BinaryHeap, + sym::BTreeMap, + sym::BTreeSet, + sym::hashmap_type, + sym::hashset_type, + sym::LinkedList, + sym::vec_type, + sym::vecdeque_type, ]; 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) { 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]); } } diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 9641784eb9a..d87055c842c 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -10,13 +10,13 @@ use rustc_span::Span; use std::collections::hash_map::Entry; 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 /// struct X; /// impl X { diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs index b023e13e846..b62fad4bd39 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs @@ -8,14 +8,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; 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 - /// - /// ** Example:** + /// ### Known problems + /// None /// + /// ### Example /// ```rust /// // Bad /// pub struct A; @@ -45,14 +47,16 @@ 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 - /// - /// ** Example:** + /// ### Known problems + /// None /// + /// ### Example /// ```rust /// // Bad /// use std::fmt; diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index 20f00bd51ba..3e3df903f17 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Symbol}; 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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// trait Animal { /// #[inline] diff --git a/src/tools/clippy/clippy_lints/src/int_plus_one.rs b/src/tools/clippy/clippy_lints/src/int_plus_one.rs index c4a1222b51f..49b69dd072a 100644 --- a/src/tools/clippy/clippy_lints/src/int_plus_one.rs +++ b/src/tools/clippy/clippy_lints/src/int_plus_one.rs @@ -8,13 +8,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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 /// # let x = 1; /// # let y = 1; diff --git a/src/tools/clippy/clippy_lints/src/integer_division.rs b/src/tools/clippy/clippy_lints/src/integer_division.rs index e5482f675e7..a0e6f12b812 100644 --- a/src/tools/clippy/clippy_lints/src/integer_division.rs +++ b/src/tools/clippy/clippy_lints/src/integer_division.rs @@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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 /// remainder. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let x = 3 / 2; diff --git a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs index 37011f5578d..3b28b121204 100644 --- a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs @@ -14,18 +14,20 @@ use clippy_utils::source::snippet; use clippy_utils::{comparisons, sext}; 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 /// 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 /// `u8`. /// - /// **Known problems:** + /// ### Known problems /// https://github.com/rust-lang/rust-clippy/issues/886 /// - /// **Example:** + /// ### Example /// ```rust /// let x: u8 = 1; /// (x as u32) > 300; diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs index c69571f32a2..429c6ed7d2d 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs @@ -7,15 +7,15 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_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 /// it's hard to figure out which item is meant in a statement. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// fn foo() { diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 48dc5fefe99..5d4e06c2af0 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -11,15 +11,15 @@ use rustc_span::{BytePos, Pos, Span}; use rustc_typeck::hir_ty_to_ty; 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. /// - /// **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. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// pub const a = [0u32; 1_000_000]; diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index f166748d86b..cde2336b690 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -10,20 +10,22 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_target::abi::LayoutOf; 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. /// - /// **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. /// - /// **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 /// smaller variants make up less than 1% of all instances, in which case /// the overhead is negligible and the boxing is counter-productive. Always /// measure the change this lint suggests. /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// enum Test { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index c46b98022c6..7088630bfdb 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -10,13 +10,13 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use crate::rustc_target::abi::LayoutOf; 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 /// let a = [0u32; 1_000_000]; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 892b3af0b32..b66d7a9f729 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -18,17 +18,17 @@ use rustc_span::{ }; 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. /// - /// **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 /// `.is_empty()`, and having it is cheap. /// Besides, it makes the intent clearer than a manual comparison in some contexts. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// if x.len() == 0 { /// .. @@ -52,18 +52,18 @@ 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()`. /// - /// **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, /// 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 /// lint will ignore such entities. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// impl X { /// pub fn len(&self) -> usize { @@ -77,17 +77,17 @@ 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. /// - /// **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 /// `.is_empty()`, and having it is cheap. /// Besides, it makes the intent clearer than a manual comparison in some contexts. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```ignore /// if s == "" { diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs index 67eae4d87bb..13f0d43cf8d 100644 --- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs +++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs @@ -9,14 +9,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_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. /// - /// **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 /// let foo; /// diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index e627b1385bc..8992d25932c 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -9,15 +9,15 @@ use rustc_middle::ty::subst::GenericArgKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for `let _ = ` + /// ### What it does + /// Checks for `let _ = ` /// 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 /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn f() -> Result { /// Ok(0) @@ -33,17 +33,17 @@ 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. /// 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, /// `std::mem::drop` conveys your intention better and is less error-prone. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// Bad: /// ```rust,ignore @@ -60,19 +60,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `let _ = ` + /// ### What it does + /// Checks for `let _ = ` /// 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 /// 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 /// explicitly drop the expression, `std::mem::drop` conveys your intention /// better and is less error-prone. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// Bad: /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index aa763b5c5e6..f49b382c5ea 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -73,14 +73,13 @@ use rustc_session::Session; /// use clippy_lints::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. -/// /// -/// /// **Known problems:** None. (Or describe where it could go wrong.) -/// /// -/// /// **Example:** +/// /// ### Why is this bad? +/// /// Supply the reason for linting the code. /// /// +/// /// ### Example /// /// ```rust /// /// // Bad /// /// Insert a short example of code that triggers the lint @@ -330,7 +329,7 @@ mod regex; mod repeat_once; mod returns; mod self_assignment; -mod self_named_constructor; +mod self_named_constructors; mod semicolon_if_nothing_returned; mod serde_api; 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_WITH_DEFAULT, mem_replace::MEM_REPLACE_WITH_UNINIT, - methods::APPEND_INSTEAD_OF_EXTEND, methods::BIND_INSTEAD_OF_MAP, methods::BYTES_NTH, 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::EXPECT_FUN_CALL, methods::EXPECT_USED, + methods::EXTEND_WITH_DRAIN, methods::FILETYPE_IS_FILE, methods::FILTER_MAP_IDENTITY, 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::NEEDLESS_RETURN, self_assignment::SELF_ASSIGNMENT, - self_named_constructor::SELF_NAMED_CONSTRUCTOR, + self_named_constructors::SELF_NAMED_CONSTRUCTORS, semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED, serde_api::SERDE_API_MISUSE, 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_WITH_DEFAULT), 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::BYTES_NTH), 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_ON_COPY), LintId::of(methods::EXPECT_FUN_CALL), + LintId::of(methods::EXTEND_WITH_DRAIN), LintId::of(methods::FILTER_MAP_IDENTITY), LintId::of(methods::FILTER_NEXT), 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::NEEDLESS_RETURN), 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(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), 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(returns::LET_AND_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(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS), 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(loops::MANUAL_MEMCPY), LintId::of(loops::NEEDLESS_COLLECT), - LintId::of(methods::APPEND_INSTEAD_OF_EXTEND), LintId::of(methods::EXPECT_FUN_CALL), + LintId::of(methods::EXTEND_WITH_DRAIN), LintId::of(methods::ITER_NTH), LintId::of(methods::MANUAL_STR_REPEAT), 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(); 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(move || box self_named_constructor::SelfNamedConstructor); + store.register_late_pass(move || box self_named_constructors::SelfNamedConstructors); } #[rustfmt::skip] diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 5ae68ba5b2f..e5e6f8d25cc 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -18,20 +18,22 @@ use rustc_span::source_map::Span; use rustc_span::symbol::{kw, Symbol}; declare_clippy_lint! { - /// **What it does:** Checks for lifetime annotations which can be removed by + /// ### What it does + /// Checks for lifetime annotations which can be removed by /// relying on lifetime elision. /// - /// **Why is this bad?** The additional lifetimes make the code look more + /// ### Why is this bad? + /// The additional lifetimes make the code look more /// complicated, while there is nothing out of the ordinary going on. Removing /// them leads to more readable code. /// - /// **Known problems:** + /// ### Known problems /// - We bail out if the function has a `where` clause where lifetimes /// are mentioned due to potenial false positives. /// - Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the /// placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`. /// - /// **Example:** + /// ### Example /// ```rust /// // Bad: unnecessary lifetime annotations /// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { @@ -50,16 +52,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for lifetimes in generics that are never used + /// ### What it does + /// Checks for lifetimes in generics that are never used /// anywhere else. /// - /// **Why is this bad?** The additional lifetimes make the code look more + /// ### Why is this bad? + /// The additional lifetimes make the code look more /// complicated, while there is nothing out of the ordinary going on. Removing /// them leads to more readable code. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad: unnecessary lifetimes /// fn unused_lifetime<'a>(x: u8) { diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs index e0c5578bd60..699ddce0cff 100644 --- a/src/tools/clippy/clippy_lints/src/literal_representation.rs +++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs @@ -16,15 +16,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use std::iter; declare_clippy_lint! { - /// **What it does:** Warns if a long integral or floating-point constant does + /// ### What it does + /// Warns if a long integral or floating-point constant does /// not contain underscores. /// - /// **Why is this bad?** Reading long numbers is difficult without separators. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Reading long numbers is difficult without separators. /// + /// ### Example /// ```rust /// // Bad /// let x: u64 = 61864918973511; @@ -38,17 +37,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns for mistyped suffix in literals + /// ### What it does + /// Warns for mistyped suffix in literals /// - /// **Why is this bad?** This is most probably a typo + /// ### Why is this bad? + /// This is most probably a typo /// - /// **Known problems:** + /// ### Known problems /// - Recommends a signed suffix, even though the number might be too big and an unsigned /// suffix is required /// - Does not match on `_127` since that is a valid grouping for decimal and octal numbers /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Probably mistyped /// 2_32; @@ -62,16 +62,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if an integral or floating-point constant is + /// ### What it does + /// Warns if an integral or floating-point constant is /// grouped inconsistently with underscores. /// - /// **Why is this bad?** Readers may incorrectly interpret inconsistently + /// ### Why is this bad? + /// Readers may incorrectly interpret inconsistently /// grouped digits. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let x: u64 = 618_64_9189_73_511; @@ -85,15 +84,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if hexadecimal or binary literals are not grouped + /// ### What it does + /// Warns if hexadecimal or binary literals are not grouped /// by nibble or byte. /// - /// **Why is this bad?** Negatively impacts readability. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Negatively impacts readability. /// + /// ### Example /// ```rust /// let x: u32 = 0xFFF_FFF; /// let y: u8 = 0b01_011_101; @@ -104,16 +102,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if the digits of an integral or floating-point + /// ### What it does + /// Warns if the digits of an integral or floating-point /// constant are grouped into groups that /// are too large. /// - /// **Why is this bad?** Negatively impacts readability. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Negatively impacts readability. /// + /// ### Example /// ```rust /// let x: u64 = 6186491_8973511; /// ``` @@ -123,15 +120,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if there is a better representation for a numeric literal. + /// ### What it does + /// Warns if there is a better representation for a numeric literal. /// - /// **Why is this bad?** Especially for big powers of 2 a hexadecimal representation is more + /// ### Why is this bad? + /// Especially for big powers of 2 a hexadecimal representation is more /// readable than a decimal representation. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// `255` => `0xFF` /// `65_535` => `0xFFFF` /// `4_042_322_160` => `0xF0F0_F0F0` diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs index c7a28f42ea1..1bab0d99b69 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -1,16 +1,17 @@ use super::EXPLICIT_INTO_ITER_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_trait_method; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{match_trait_method, paths}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::TyS; +use rustc_span::symbol::sym; pub(super) fn check(cx: &LateContext<'_>, self_arg: &'hir Expr<'hir>, call_expr: &Expr<'_>) { let self_ty = cx.typeck_results().expr_ty(self_arg); let self_ty_adjusted = cx.typeck_results().expr_ty_adjusted(self_arg); - if !(TyS::same_type(self_ty, self_ty_adjusted) && match_trait_method(cx, call_expr, &paths::INTO_ITERATOR)) { + if !(TyS::same_type(self_ty, self_ty_adjusted) && is_trait_method(cx, call_expr, sym::IntoIterator)) { return; } diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index f0327b5d777..50bc096ba22 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,8 +1,8 @@ use super::EXPLICIT_ITER_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_trait_method; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; -use clippy_utils::{match_trait_method, paths}; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; @@ -12,7 +12,7 @@ use rustc_span::sym; pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, arg: &Expr<'_>, method_name: &str) { let should_lint = match method_name { "iter" | "iter_mut" => is_ref_iterable_type(cx, self_arg), - "into_iter" if match_trait_method(cx, arg, &paths::INTO_ITERATOR) => { + "into_iter" if is_trait_method(cx, arg, sym::IntoIterator) => { let receiver_ty = cx.typeck_results().expr_ty(self_arg); let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(self_arg); let ref_receiver_ty = cx.tcx.mk_ref( @@ -55,13 +55,13 @@ fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(e); is_iterable_array(ty, cx) || is_type_diagnostic_item(cx, ty, sym::vec_type) || - match_type(cx, ty, &paths::LINKED_LIST) || + is_type_diagnostic_item(cx, ty, sym::LinkedList) || is_type_diagnostic_item(cx, ty, sym::hashmap_type) || is_type_diagnostic_item(cx, ty, sym::hashset_type) || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || - match_type(cx, ty, &paths::BINARY_HEAP) || - match_type(cx, ty, &paths::BTREEMAP) || - match_type(cx, ty, &paths::BTREESET) + is_type_diagnostic_item(cx, ty, sym::BinaryHeap) || + is_type_diagnostic_item(cx, ty, sym::BTreeMap) || + is_type_diagnostic_item(cx, ty, sym::BTreeSet) } fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs b/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs index 666b8c58728..82bf49f5b49 100644 --- a/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs +++ b/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs @@ -1,9 +1,9 @@ use super::FOR_KV_MAP; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::source::snippet; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; +use clippy_utils::sugg; +use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::LocalUsedVisitor; -use clippy_utils::{paths, sugg}; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -39,7 +39,7 @@ pub(super) fn check<'tcx>( _ => arg, }; - if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP) { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || is_type_diagnostic_item(cx, ty, sym::BTreeMap) { span_lint_and_then( cx, FOR_KV_MAP, diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs index 56a123b69c6..7ca54d53972 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mod.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs @@ -26,14 +26,14 @@ use rustc_span::source_map::Span; use utils::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; declare_clippy_lint! { - /// **What it does:** Checks for for-loops that manually copy items between + /// ### What it does + /// Checks for for-loops that manually copy items between /// slices that could be optimized by having a memcpy. /// - /// **Why is this bad?** It is not as fast as a memcpy. + /// ### Why is this bad? + /// It is not as fast as a memcpy. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let src = vec![1]; /// # let mut dst = vec![0; 65]; @@ -53,15 +53,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for looping over the range of `0..len` of some + /// ### What it does + /// Checks for looping over the range of `0..len` of some /// collection just to get the values by index. /// - /// **Why is this bad?** Just iterating the collection itself makes the intent + /// ### Why is this bad? + /// Just iterating the collection itself makes the intent /// more clear and is probably faster. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let vec = vec!['a', 'b', 'c']; /// for i in 0..vec.len() { @@ -81,15 +81,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for loops on `x.iter()` where `&x` will do, and + /// ### What it does + /// Checks for loops on `x.iter()` where `&x` will do, and /// suggests the latter. /// - /// **Why is this bad?** Readability. + /// ### Why is this bad? + /// Readability. /// - /// **Known problems:** False negatives. We currently only warn on some known + /// ### Known problems + /// False negatives. We currently only warn on some known /// types. /// - /// **Example:** + /// ### Example /// ```rust /// // with `y` a `Vec` or slice: /// # let y = vec![1]; @@ -110,14 +113,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and + /// ### What it does + /// Checks for loops on `y.into_iter()` where `y` will do, and /// suggests the latter. /// - /// **Why is this bad?** Readability. + /// ### Why is this bad? + /// Readability. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// # let y = vec![1]; /// // with `y` a `Vec` or slice: @@ -138,18 +141,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for loops on `x.next()`. + /// ### What it does + /// Checks for loops on `x.next()`. /// - /// **Why is this bad?** `next()` returns either `Some(value)` if there was a + /// ### Why is this bad? + /// `next()` returns either `Some(value)` if there was a /// value, or `None` otherwise. The insidious thing is that `Option<_>` /// implements `IntoIterator`, so that possibly one value will be iterated, /// leading to some hard to find bugs. No one will want to write such code /// [except to win an Underhanded Rust /// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// for x in y.next() { /// .. @@ -161,14 +164,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `for` loops over `Option` or `Result` values. + /// ### What it does + /// Checks for `for` loops over `Option` or `Result` values. /// - /// **Why is this bad?** Readability. This is more clearly expressed as an `if + /// ### Why is this bad? + /// Readability. This is more clearly expressed as an `if /// let`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let opt = Some(1); /// @@ -204,15 +207,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Detects `loop + match` combinations that are easier + /// ### What it does + /// Detects `loop + match` combinations that are easier /// written as a `while let` loop. /// - /// **Why is this bad?** The `while let` loop is usually shorter and more + /// ### Why is this bad? + /// The `while let` loop is usually shorter and more /// readable. /// - /// **Known problems:** Sometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)). + /// ### Known problems + /// Sometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)). /// - /// **Example:** + /// ### Example /// ```rust,no_run /// # let y = Some(1); /// loop { @@ -233,16 +239,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for functions collecting an iterator when collect + /// ### What it does + /// Checks for functions collecting an iterator when collect /// is not needed. /// - /// **Why is this bad?** `collect` causes the allocation of a new data structure, + /// ### Why is this bad? + /// `collect` causes the allocation of a new data structure, /// when this allocation may not be needed. /// - /// **Known problems:** - /// None - /// - /// **Example:** + /// ### Example /// ```rust /// # let iterator = vec![1].into_iter(); /// let len = iterator.clone().collect::>().len(); @@ -255,15 +260,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks `for` loops over slices with an explicit counter + /// ### What it does + /// Checks `for` loops over slices with an explicit counter /// and suggests the use of `.enumerate()`. /// - /// **Why is it bad?** Using `.enumerate()` makes the intent more clear, + /// ### Why is this bad? + /// Using `.enumerate()` makes the intent more clear, /// declutters the code and may be faster in some instances. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let v = vec![1]; /// # fn bar(bar: usize, baz: usize) {} @@ -285,9 +290,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for empty `loop` expressions. + /// ### What it does + /// Checks for empty `loop` expressions. /// - /// **Why is this bad?** These busy loops burn CPU cycles without doing + /// ### Why is this bad? + /// These busy loops burn CPU cycles without doing /// anything. It is _almost always_ a better idea to `panic!` than to have /// a busy loop. /// @@ -306,9 +313,7 @@ declare_clippy_lint! { /// - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html) /// - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html) /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// loop {} /// ``` @@ -318,14 +323,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `while let` expressions on iterators. + /// ### What it does + /// Checks for `while let` expressions on iterators. /// - /// **Why is this bad?** Readability. A simple `for` loop is shorter and conveys + /// ### Why is this bad? + /// Readability. A simple `for` loop is shorter and conveys /// the intent better. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// while let Some(val) = iter() { /// .. @@ -337,15 +342,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for iterating a map (`HashMap` or `BTreeMap`) and + /// ### What it does + /// Checks for iterating a map (`HashMap` or `BTreeMap`) and /// ignoring either the keys or values. /// - /// **Why is this bad?** Readability. There are `keys` and `values` methods that + /// ### Why is this bad? + /// Readability. There are `keys` and `values` methods that /// can be used to express that don't need the values or keys. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// for (k, _) in &map { /// .. @@ -365,15 +370,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for loops that will always `break`, `return` or + /// ### What it does + /// Checks for loops that will always `break`, `return` or /// `continue` an outer loop. /// - /// **Why is this bad?** This loop never loops, all it does is obfuscating the + /// ### Why is this bad? + /// This loop never loops, all it does is obfuscating the /// code. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// loop { /// ..; @@ -386,13 +391,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for loops which have a range bound that is a mutable variable + /// ### What it does + /// Checks for loops which have a range bound that is a mutable variable /// - /// **Why is this bad?** One might think that modifying the mutable variable changes the loop bounds + /// ### Why is this bad? + /// One might think that modifying the mutable variable changes the loop bounds /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// let mut foo = 42; /// for i in 0..foo { @@ -406,17 +411,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks whether variables used within while loop condition + /// ### What it does + /// Checks whether variables used within while loop condition /// can be (and are) mutated in the body. /// - /// **Why is this bad?** If the condition is unchanged, entering the body of the loop + /// ### Why is this bad? + /// If the condition is unchanged, entering the body of the loop /// will lead to an infinite loop. /// - /// **Known problems:** If the `while`-loop is in a closure, the check for mutation of the + /// ### Known problems + /// If the `while`-loop is in a closure, the check for mutation of the /// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is /// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger. /// - /// **Example:** + /// ### Example /// ```rust /// let i = 0; /// while i > 10 { @@ -429,15 +437,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks whether a for loop is being used to push a constant + /// ### What it does + /// Checks whether a for loop is being used to push a constant /// value into a Vec. /// - /// **Why is this bad?** This kind of operation can be expressed more succinctly with + /// ### Why is this bad? + /// This kind of operation can be expressed more succinctly with /// `vec![item;SIZE]` or `vec.resize(NEW_SIZE, item)` and using these alternatives may also /// have better performance. - /// **Known problems:** None /// - /// **Example:** + /// ### Example /// ```rust /// let item1 = 2; /// let item2 = 3; @@ -462,13 +471,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks whether a for loop has a single element. + /// ### What it does + /// Checks whether a for loop has a single element. /// - /// **Why is this bad?** There is no reason to have a loop of a + /// ### Why is this bad? + /// There is no reason to have a loop of a /// single element. - /// **Known problems:** None /// - /// **Example:** + /// ### Example /// ```rust /// let item1 = 2; /// for item in &[item1] { @@ -487,15 +497,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Check for unnecessary `if let` usage in a for loop + /// ### What it does + /// Check for unnecessary `if let` usage in a for loop /// where only the `Some` or `Ok` variant of the iterator element is used. /// - /// **Why is this bad?** It is verbose and can be simplified + /// ### Why is this bad? + /// It is verbose and can be simplified /// by first calling the `flatten` method on the `Iterator`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```rust /// let x = vec![Some(1), Some(2), Some(3)]; diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 66479ae264e..a371f8bbd3c 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -12,14 +12,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{edition::Edition, sym, Span}; declare_clippy_lint! { - /// **What it does:** Checks for `#[macro_use] use...`. + /// ### What it does + /// Checks for `#[macro_use] use...`. /// - /// **Why is this bad?** Since the Rust 2018 edition you can import + /// ### Why is this bad? + /// Since the Rust 2018 edition you can import /// macro's directly, this is considered idiomatic. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// #[macro_use] /// use some_macro; diff --git a/src/tools/clippy/clippy_lints/src/main_recursion.rs b/src/tools/clippy/clippy_lints/src/main_recursion.rs index 07d8a440aea..776e4b3fe76 100644 --- a/src/tools/clippy/clippy_lints/src/main_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/main_recursion.rs @@ -7,14 +7,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; declare_clippy_lint! { - /// **What it does:** Checks for recursion using the entrypoint. + /// ### What it does + /// Checks for recursion using the entrypoint. /// - /// **Why is this bad?** Apart from special setups (which we could detect following attributes like #![no_std]), + /// ### Why is this bad? + /// Apart from special setups (which we could detect following attributes like #![no_std]), /// recursing into main() seems like an unintuitive antipattern we should be able to detect. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// fn main() { /// main(); diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 5d88ff3b99f..8e1385fb83a 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -14,14 +14,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span}; declare_clippy_lint! { - /// **What it does:** It checks for manual implementations of `async` functions. + /// ### What it does + /// It checks for manual implementations of `async` functions. /// - /// **Why is this bad?** It's more idiomatic to use the dedicated syntax. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// It's more idiomatic to use the dedicated syntax. /// + /// ### Example /// ```rust /// use std::future::Future; /// diff --git a/src/tools/clippy/clippy_lints/src/manual_map.rs b/src/tools/clippy/clippy_lints/src/manual_map.rs index 563d5cdb5fb..7dec1595e0d 100644 --- a/src/tools/clippy/clippy_lints/src/manual_map.rs +++ b/src/tools/clippy/clippy_lints/src/manual_map.rs @@ -16,14 +16,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, SyntaxContext}; declare_clippy_lint! { - /// **What it does:** Checks for usages of `match` which could be implemented using `map` + /// ### What it does + /// Checks for usages of `match` which could be implemented using `map` /// - /// **Why is this bad?** Using the `map` method is clearer and more concise. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Using the `map` method is clearer and more concise. /// + /// ### Example /// ```rust /// match Some(0) { /// Some(x) => Some(x + 1), diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 54f714b54b6..335ea001ee4 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -11,15 +11,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{sym, Span}; declare_clippy_lint! { - /// **What it does:** Checks for manual implementations of the non-exhaustive pattern. + /// ### What it does + /// Checks for manual implementations of the non-exhaustive pattern. /// - /// **Why is this bad?** Using the #[non_exhaustive] attribute expresses better the intent + /// ### Why is this bad? + /// Using the #[non_exhaustive] attribute expresses better the intent /// and allows possible optimizations when applied to enums. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct S { /// pub a: i32, diff --git a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/manual_ok_or.rs index 847c8c648b0..b2f287af697 100644 --- a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs +++ b/src/tools/clippy/clippy_lints/src/manual_ok_or.rs @@ -13,15 +13,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** + /// ### What it does + /// /// Finds patterns that reimplement `Option::ok_or`. /// - /// **Why is this bad?** + /// ### Why is this bad? + /// /// Concise code helps focusing on behavior instead of boilerplate. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust /// let foo: Option = None; /// foo.map_or(Err("error"), |v| Ok(v)); diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index 61b5fe81fa9..db12c377488 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -18,21 +18,17 @@ use rustc_span::source_map::Spanned; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using /// the pattern's length. /// - /// **Why is this bad?** + /// ### Why is this bad? /// Using `str:strip_{prefix,suffix}` is safer and may have better performance as there is no /// slicing which may panic and the compiler does not need to insert this panic code. It is /// also sometimes more readable as it removes the need for duplicating or storing the pattern /// used by `str::{starts,ends}_with` and in the slicing. /// - /// **Known problems:** - /// None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let s = "hello, world!"; /// if s.starts_with("hello, ") { diff --git a/src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs index 9d8d77cf8f0..426789742d5 100644 --- a/src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs @@ -15,15 +15,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`. /// - /// **Why is this bad?** + /// ### Why is this bad? /// Concise code helps focusing on behavior instead of boilerplate. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let foo: Option = None; /// match foo { diff --git a/src/tools/clippy/clippy_lints/src/map_clone.rs b/src/tools/clippy/clippy_lints/src/map_clone.rs index e1f80ab025c..394606200bb 100644 --- a/src/tools/clippy/clippy_lints/src/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/map_clone.rs @@ -15,16 +15,15 @@ use rustc_span::symbol::Ident; use rustc_span::{sym, Span}; declare_clippy_lint! { - /// **What it does:** Checks for usage of `map(|x| x.clone())` or + /// ### What it does + /// Checks for usage of `map(|x| x.clone())` or /// dereferencing closures for `Copy` types, on `Iterator` or `Option`, /// and suggests `cloned()` or `copied()` instead /// - /// **Why is this bad?** Readability, this can be written more concisely - /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Why is this bad? + /// Readability, this can be written more concisely /// + /// ### Example /// ```rust /// let x = vec![42, 43]; /// let y = x.iter(); diff --git a/src/tools/clippy/clippy_lints/src/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/map_err_ignore.rs index 425a9734e5f..82d3732326e 100644 --- a/src/tools/clippy/clippy_lints/src/map_err_ignore.rs +++ b/src/tools/clippy/clippy_lints/src/map_err_ignore.rs @@ -4,13 +4,13 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for instances of `map_err(|_| Some::Enum)` + /// ### What it does + /// Checks for instances of `map_err(|_| Some::Enum)` /// - /// **Why is this bad?** This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error + /// ### Why is this bad? + /// This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Before: /// ```rust /// use std::fmt; diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs index 57cd907e77e..fd40590d077 100644 --- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs +++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs @@ -12,16 +12,15 @@ use rustc_span::source_map::Span; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for usage of `option.map(f)` where f is a function + /// ### What it does + /// Checks for usage of `option.map(f)` where f is a function /// or closure that returns the unit type `()`. /// - /// **Why is this bad?** Readability, this can be written more clearly with + /// ### Why is this bad? + /// Readability, this can be written more clearly with /// an if let statement /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// # fn do_stuff() -> Option { Some(String::new()) } /// # fn log_err_msg(foo: String) -> Option { Some(foo) } @@ -54,16 +53,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `result.map(f)` where f is a function + /// ### What it does + /// Checks for usage of `result.map(f)` where f is a function /// or closure that returns the unit type `()`. /// - /// **Why is this bad?** Readability, this can be written more clearly with + /// ### Why is this bad? + /// Readability, this can be written more clearly with /// an if let statement /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// # fn do_stuff() -> Result { Ok(String::new()) } /// # fn log_err_msg(foo: String) -> Result { Ok(foo) } diff --git a/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs b/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs index ca6fb0831fe..e66a35452f0 100644 --- a/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs +++ b/src/tools/clippy/clippy_lints/src/match_on_vec_items.rs @@ -10,13 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for `match vec[idx]` or `match vec[n..m]`. + /// ### What it does + /// Checks for `match vec[idx]` or `match vec[n..m]`. /// - /// **Why is this bad?** This can panic at runtime. + /// ### Why is this bad? + /// This can panic at runtime. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust, no_run /// let arr = vec![0, 1, 2, 3]; /// let idx = 1; diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs index 66e3d957894..5360c02f905 100644 --- a/src/tools/clippy/clippy_lints/src/matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches.rs @@ -35,14 +35,14 @@ use std::iter; use std::ops::Bound; declare_clippy_lint! { - /// **What it does:** Checks for matches with a single arm where an `if let` + /// ### What it does + /// Checks for matches with a single arm where an `if let` /// will usually suffice. /// - /// **Why is this bad?** Just readability – `if let` nests less than a `match`. + /// ### Why is this bad? + /// Just readability – `if let` nests less than a `match`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn bar(stool: &str) {} /// # let x = Some("abc"); @@ -63,15 +63,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for matches with two arms where an `if let else` will + /// ### What it does + /// Checks for matches with two arms where an `if let else` will /// usually suffice. /// - /// **Why is this bad?** Just readability – `if let` nests less than a `match`. + /// ### Why is this bad? + /// Just readability – `if let` nests less than a `match`. /// - /// **Known problems:** Personal style preferences may differ. - /// - /// **Example:** + /// ### Known problems + /// Personal style preferences may differ. /// + /// ### Example /// Using `match`: /// /// ```rust @@ -102,16 +104,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for matches where all arms match a reference, + /// ### What it does + /// Checks for matches where all arms match a reference, /// suggesting to remove the reference and deref the matched expression /// instead. It also checks for `if let &foo = bar` blocks. /// - /// **Why is this bad?** It just makes the code less readable. That reference + /// ### Why is this bad? + /// It just makes the code less readable. That reference /// destructuring adds nothing to the code. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// match x { @@ -133,14 +135,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for matches where match expression is a `bool`. It + /// ### What it does + /// Checks for matches where match expression is a `bool`. It /// suggests to replace the expression with an `if...else` block. /// - /// **Why is this bad?** It makes the code less readable. + /// ### Why is this bad? + /// It makes the code less readable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn foo() {} /// # fn bar() {} @@ -167,14 +169,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for overlapping match arms. + /// ### What it does + /// Checks for overlapping match arms. /// - /// **Why is this bad?** It is likely to be an error and if not, makes the code + /// ### Why is this bad? + /// It is likely to be an error and if not, makes the code /// less obvious. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = 5; /// match x { @@ -189,15 +191,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for arm which matches all errors with `Err(_)` + /// ### What it does + /// Checks for arm which matches all errors with `Err(_)` /// and take drastic actions like `panic!`. /// - /// **Why is this bad?** It is generally a bad practice, similar to + /// ### Why is this bad? + /// It is generally a bad practice, similar to /// catching all exceptions in java with `catch(Exception)` /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x: Result = Ok(3); /// match x { @@ -211,14 +213,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for match which is used to add a reference to an + /// ### What it does + /// Checks for match which is used to add a reference to an /// `Option` value. /// - /// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter. + /// ### Why is this bad? + /// Using `as_ref()` or `as_mut()` instead is shorter. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x: Option<()> = None; /// @@ -237,14 +239,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for wildcard enum matches using `_`. + /// ### What it does + /// Checks for wildcard enum matches using `_`. /// - /// **Why is this bad?** New enum variants added by library updates can be missed. + /// ### Why is this bad? + /// New enum variants added by library updates can be missed. /// - /// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some + /// ### Known problems + /// Suggested replacements may be incorrect if guards exhaustively cover some /// variants, and also may not use correct path to enum if it's not present in the current scope. /// - /// **Example:** + /// ### Example /// ```rust /// # enum Foo { A(usize), B(usize) } /// # let x = Foo::B(1); @@ -266,15 +271,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for wildcard enum matches for a single variant. + /// ### What it does + /// Checks for wildcard enum matches for a single variant. /// - /// **Why is this bad?** New enum variants added by library updates can be missed. + /// ### Why is this bad? + /// New enum variants added by library updates can be missed. /// - /// **Known problems:** Suggested replacements may not use correct path to enum + /// ### Known problems + /// Suggested replacements may not use correct path to enum /// if it's not present in the current scope. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # enum Foo { A, B, C } /// # let x = Foo::B; @@ -298,14 +305,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for wildcard pattern used with others patterns in same match arm. + /// ### What it does + /// Checks for wildcard pattern used with others patterns in same match arm. /// - /// **Why is this bad?** Wildcard pattern already covers any other pattern as it will match anyway. + /// ### Why is this bad? + /// Wildcard pattern already covers any other pattern as it will match anyway. /// It makes the code less readable, especially to spot wildcard pattern use in match arm. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// match "foo" { @@ -325,14 +332,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for matches being used to destructure a single-variant enum + /// ### What it does + /// Checks for matches being used to destructure a single-variant enum /// or tuple struct where a `let` will suffice. /// - /// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does. + /// ### Why is this bad? + /// Just readability – `let` doesn't nest, whereas a `match` does. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// enum Wrapper { /// Data(i32), @@ -360,14 +367,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for useless match that binds to only one value. + /// ### What it does + /// Checks for useless match that binds to only one value. /// - /// **Why is this bad?** Readability and needless complexity. + /// ### Why is this bad? + /// Readability and needless complexity. /// - /// **Known problems:** Suggested replacements may be incorrect when `match` + /// ### Known problems + /// Suggested replacements may be incorrect when `match` /// is actually binding temporary value, bringing a 'dropped while borrowed' error. /// - /// **Example:** + /// ### Example /// ```rust /// # let a = 1; /// # let b = 2; @@ -388,14 +398,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched. + /// ### What it does + /// Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched. /// - /// **Why is this bad?** Correctness and readability. It's like having a wildcard pattern after + /// ### Why is this bad? + /// Correctness and readability. It's like having a wildcard pattern after /// matching all enum variants explicitly. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct A { a: i32 } /// let a = A { a: 5 }; @@ -418,21 +428,23 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Lint for redundant pattern matching over `Result`, `Option`, + /// ### What it does + /// Lint for redundant pattern matching over `Result`, `Option`, /// `std::task::Poll` or `std::net::IpAddr` /// - /// **Why is this bad?** It's more concise and clear to just use the proper + /// ### Why is this bad? + /// It's more concise and clear to just use the proper /// utility function /// - /// **Known problems:** This will change the drop order for the matched type. Both `if let` and + /// ### Known problems + /// This will change the drop order for the matched type. Both `if let` and /// `while let` will drop the value at the end of the block, both `if` and `while` will drop the /// value before entering the block. For most types this change will not matter, but for a few /// types this will not be an acceptable change (e.g. locks). See the /// [reference](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) for more about /// drop order. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # use std::task::Poll; /// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; @@ -471,15 +483,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `match` or `if let` expressions producing a + /// ### What it does + /// Checks for `match` or `if let` expressions producing a /// `bool` that could be written using `matches!` /// - /// **Why is this bad?** Readability and needless complexity. + /// ### Why is this bad? + /// Readability and needless complexity. /// - /// **Known problems:** This lint falsely triggers, if there are arms with + /// ### Known problems + /// This lint falsely triggers, if there are arms with /// `cfg` attributes that remove an arm evaluating to `false`. /// - /// **Example:** + /// ### Example /// ```rust /// let x = Some(5); /// @@ -504,17 +519,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `match` with identical arm bodies. + /// ### What it does + /// Checks for `match` with identical arm bodies. /// - /// **Why is this bad?** This is probably a copy & paste error. If arm bodies + /// ### Why is this bad? + /// This is probably a copy & paste error. If arm bodies /// are the same on purpose, you can factor them /// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns). /// - /// **Known problems:** False positive possible with order dependent `match` + /// ### Known problems + /// False positive possible with order dependent `match` /// (see issue /// [#860](https://github.com/rust-lang/rust-clippy/issues/860)). /// - /// **Example:** + /// ### Example /// ```rust,ignore /// match foo { /// Bar => bar(), @@ -1793,8 +1811,8 @@ mod redundant_pattern_match { || is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) || is_type_diagnostic_item(cx, ty, sym::cstring_type) - || match_type(cx, ty, &paths::BTREEMAP) - || match_type(cx, ty, &paths::LINKED_LIST) + || is_type_diagnostic_item(cx, ty, sym::BTreeMap) + || is_type_diagnostic_item(cx, ty, sym::LinkedList) || match_type(cx, ty, &paths::WEAK_RC) || match_type(cx, ty, &paths::WEAK_ARC) { diff --git a/src/tools/clippy/clippy_lints/src/mem_discriminant.rs b/src/tools/clippy/clippy_lints/src/mem_discriminant.rs index aca96e06ef2..59176c4b846 100644 --- a/src/tools/clippy/clippy_lints/src/mem_discriminant.rs +++ b/src/tools/clippy/clippy_lints/src/mem_discriminant.rs @@ -9,14 +9,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for calls of `mem::discriminant()` on a non-enum type. + /// ### What it does + /// Checks for calls of `mem::discriminant()` on a non-enum type. /// - /// **Why is this bad?** The value of `mem::discriminant()` on non-enum types + /// ### Why is this bad? + /// The value of `mem::discriminant()` on non-enum types /// is unspecified. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// use std::mem; /// diff --git a/src/tools/clippy/clippy_lints/src/mem_forget.rs b/src/tools/clippy/clippy_lints/src/mem_forget.rs index a28cb5f32fe..07202a59c4b 100644 --- a/src/tools/clippy/clippy_lints/src/mem_forget.rs +++ b/src/tools/clippy/clippy_lints/src/mem_forget.rs @@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is + /// ### What it does + /// Checks for usage of `std::mem::forget(t)` where `t` is /// `Drop`. /// - /// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its + /// ### Why is this bad? + /// `std::mem::forget(t)` prevents `t` from running its /// destructor, possibly causing leaks. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::mem; /// # use std::rc::Rc; diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs index 183daee3617..3d071c9081b 100644 --- a/src/tools/clippy/clippy_lints/src/mem_replace.rs +++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs @@ -14,16 +14,16 @@ use rustc_span::source_map::Span; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks for `mem::replace()` on an `Option` with + /// ### What it does + /// Checks for `mem::replace()` on an `Option` with /// `None`. /// - /// **Why is this bad?** `Option` already has the method `take()` for + /// ### Why is this bad? + /// `Option` already has the method `take()` for /// taking its current value (Some(..) or None) and replacing it with /// `None`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// use std::mem; /// @@ -41,17 +41,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `mem::replace(&mut _, mem::uninitialized())` + /// ### What it does + /// Checks for `mem::replace(&mut _, mem::uninitialized())` /// and `mem::replace(&mut _, mem::zeroed())`. /// - /// **Why is this bad?** This will lead to undefined behavior even if the + /// ### Why is this bad? + /// This will lead to undefined behavior even if the /// value is overwritten later, because the uninitialized value may be /// observed in the case of a panic. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ``` /// use std::mem; ///# fn may_panic(v: Vec) -> Vec { v } @@ -73,15 +72,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `std::mem::replace` on a value of type + /// ### What it does + /// Checks for `std::mem::replace` on a value of type /// `T` with `T::default()`. /// - /// **Why is this bad?** `std::mem` module already has the method `take` to + /// ### Why is this bad? + /// `std::mem` module already has the method `take` to /// take the current value and replace it with the default value of that type. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let mut text = String::from("foo"); /// let replaced = std::mem::replace(&mut text, String::default()); diff --git a/src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs b/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs similarity index 95% rename from src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs rename to src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs index e39a5a1efd1..57e10ce42f8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs +++ b/src/tools/clippy/clippy_lints/src/methods/extend_with_drain.rs @@ -7,7 +7,7 @@ use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; use rustc_span::symbol::sym; -use super::APPEND_INSTEAD_OF_EXTEND; +use super::EXTEND_WITH_DRAIN; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); @@ -25,7 +25,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, - APPEND_INSTEAD_OF_EXTEND, + EXTEND_WITH_DRAIN, expr.span, "use of `extend` instead of `append` for adding the full range of a second vector", "try this", diff --git a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs index 54f28064384..66fb85deae5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs @@ -1,8 +1,8 @@ use super::utils::derefs_to_slice; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; -use clippy_utils::{get_parent_expr, paths}; +use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -36,7 +36,7 @@ pub(super) fn check<'tcx>( } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::hashmap_type) { needs_ref = true; "HashMap" - } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { + } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::BTreeMap) { needs_ref = true; "BTreeMap" } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_count.rs b/src/tools/clippy/clippy_lints/src/methods/iter_count.rs index c6b7c7cd179..b69f57f50e0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_count.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_count.rs @@ -1,8 +1,7 @@ use super::utils::derefs_to_slice; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::paths; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; @@ -22,13 +21,13 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E "HashSet" } else if is_type_diagnostic_item(cx, ty, sym::hashmap_type) { "HashMap" - } else if match_type(cx, ty, &paths::BTREEMAP) { + } else if is_type_diagnostic_item(cx, ty, sym::BTreeMap) { "BTreeMap" - } else if match_type(cx, ty, &paths::BTREESET) { + } else if is_type_diagnostic_item(cx, ty, sym::BTreeSet) { "BTreeSet" - } else if match_type(cx, ty, &paths::LINKED_LIST) { + } else if is_type_diagnostic_item(cx, ty, sym::LinkedList) { "LinkedList" - } else if match_type(cx, ty, &paths::BINARY_HEAP) { + } else if is_type_diagnostic_item(cx, ty, sym::BinaryHeap) { "BinaryHeap" } else { return; diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 283fcf281df..5aa29424349 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -1,4 +1,3 @@ -mod append_instead_of_extend; mod bind_instead_of_map; mod bytes_nth; mod chars_cmp; @@ -12,6 +11,7 @@ mod clone_on_ref_ptr; mod cloned_instead_of_copied; mod expect_fun_call; mod expect_used; +mod extend_with_drain; mod filetype_is_file; mod filter_map; mod filter_map_identity; @@ -80,16 +80,15 @@ use rustc_span::{sym, Span}; use rustc_typeck::hir_ty_to_ty; declare_clippy_lint! { - /// **What it does:** Checks for usages of `cloned()` on an `Iterator` or `Option` where + /// ### What it does + /// Checks for usages of `cloned()` on an `Iterator` or `Option` where /// `copied()` could be used instead. /// - /// **Why is this bad?** `copied()` is better because it guarantees that the type being cloned + /// ### Why is this bad? + /// `copied()` is better because it guarantees that the type being cloned /// implements `Copy`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// [1, 2, 3].iter().cloned(); /// ``` @@ -103,16 +102,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usages of `Iterator::flat_map()` where `filter_map()` could be + /// ### What it does + /// Checks for usages of `Iterator::flat_map()` where `filter_map()` could be /// used instead. /// - /// **Why is this bad?** When applicable, `filter_map()` is more clear since it shows that + /// ### Why is this bad? + /// When applicable, `filter_map()` is more clear since it shows that /// `Option` is used to produce 0 or 1 items. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let nums: Vec = ["1", "2", "whee!"].iter().flat_map(|x| x.parse().ok()).collect(); /// ``` @@ -126,9 +124,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `.unwrap()` calls on `Option`s and on `Result`s. + /// ### What it does + /// Checks for `.unwrap()` calls on `Option`s and on `Result`s. /// - /// **Why is this bad?** It is better to handle the `None` or `Err` case, + /// ### Why is this bad? + /// It is better to handle the `None` or `Err` case, /// or at least call `.expect(_)` with a more helpful message. Still, for a lot of /// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is /// `Allow` by default. @@ -141,9 +141,7 @@ declare_clippy_lint! { /// messages on display. Therefore, it may be beneficial to look at the places /// where they may get displayed. Activate this lint to do just that. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust /// # let opt = Some(1); /// @@ -171,9 +169,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `.expect()` calls on `Option`s and `Result`s. + /// ### What it does + /// Checks for `.expect()` calls on `Option`s and `Result`s. /// - /// **Why is this bad?** Usually it is better to handle the `None` or `Err` case. + /// ### Why is this bad? + /// Usually it is better to handle the `None` or `Err` case. /// Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why /// this lint is `Allow` by default. /// @@ -181,9 +181,7 @@ declare_clippy_lint! { /// values. Normally, you want to implement more sophisticated error handling, /// and propagate errors upwards with `?` operator. /// - /// **Known problems:** None. - /// - /// **Examples:** + /// ### Examples /// ```rust,ignore /// # let opt = Some(1); /// @@ -213,20 +211,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for methods that should live in a trait + /// ### What it does + /// Checks for methods that should live in a trait /// implementation of a `std` trait (see [llogiq's blog /// post](http://llogiq.github.io/2015/07/30/traits.html) for further /// information) instead of an inherent implementation. /// - /// **Why is this bad?** Implementing the traits improve ergonomics for users of + /// ### Why is this bad? + /// Implementing the traits improve ergonomics for users of /// the code, often with very little cost. Also people seeing a `mul(...)` /// method /// may expect `*` to work equally, so you should have good reason to disappoint /// them. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// struct X; /// impl X { @@ -242,7 +240,8 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for methods with certain name prefixes and which + /// ### What it does + /// Checks for methods with certain name prefixes and which /// doesn't match how self is taken. The actual rules are: /// /// |Prefix |Postfix |`self` taken | `self` type | @@ -265,13 +264,12 @@ declare_clippy_lint! { /// Please find more info here: /// https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv /// - /// **Why is this bad?** Consistency breeds readability. If you follow the + /// ### Why is this bad? + /// Consistency breeds readability. If you follow the /// conventions, your users won't be surprised that they, e.g., need to supply a /// mutable reference to a `as_..` function. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct X; /// impl X { @@ -287,14 +285,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `ok().expect(..)`. + /// ### What it does + /// Checks for usage of `ok().expect(..)`. /// - /// **Why is this bad?** Because you usually call `expect()` on the `Result` + /// ### Why is this bad? + /// Because you usually call `expect()` on the `Result` /// directly to get a better error message. /// - /// **Known problems:** The error type needs to implement `Debug` + /// ### Known problems + /// The error type needs to implement `Debug` /// - /// **Example:** + /// ### Example /// ```rust /// # let x = Ok::<_, ()>(()); /// @@ -310,15 +311,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or + /// ### What it does + /// Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or /// `result.map(_).unwrap_or_else(_)`. /// - /// **Why is this bad?** Readability, these can be written more concisely (resp.) as + /// ### Why is this bad? + /// Readability, these can be written more concisely (resp.) as /// `option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`. /// - /// **Known problems:** The order of the arguments is not in execution order + /// ### Known problems + /// The order of the arguments is not in execution order /// - /// **Examples:** + /// ### Examples /// ```rust /// # let x = Some(1); /// @@ -347,14 +351,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.map_or(None, _)`. + /// ### What it does + /// Checks for usage of `_.map_or(None, _)`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.and_then(_)`. /// - /// **Known problems:** The order of the arguments is not in execution order. + /// ### Known problems + /// The order of the arguments is not in execution order. /// - /// **Example:** + /// ### Example /// ```rust /// # let opt = Some(1); /// @@ -370,15 +377,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.map_or(None, Some)`. + /// ### What it does + /// Checks for usage of `_.map_or(None, Some)`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.ok()`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// Bad: /// ```rust /// # let r: Result = Ok(1); @@ -396,16 +402,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or + /// ### What it does + /// Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or /// `_.or_else(|x| Err(y))`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.map(|x| y)` or `_.map_err(|x| y)`. /// - /// **Known problems:** None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// # fn opt() -> Option<&'static str> { Some("42") } /// # fn res() -> Result<&'static str, &'static str> { Ok("42") } @@ -429,14 +434,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.filter(_).next()`. + /// ### What it does + /// Checks for usage of `_.filter(_).next()`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.find(_)`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let vec = vec![1]; /// vec.iter().filter(|x| **x == 0).next(); @@ -452,14 +457,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.skip_while(condition).next()`. + /// ### What it does + /// Checks for usage of `_.skip_while(condition).next()`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.find(!condition)`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let vec = vec![1]; /// vec.iter().skip_while(|x| **x == 0).next(); @@ -475,14 +480,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option` + /// ### What it does + /// Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option` /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.flat_map(_)` /// - /// **Known problems:** - /// - /// **Example:** + /// ### Example /// ```rust /// let vec = vec![vec![1]]; /// @@ -498,15 +503,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.filter(_).map(_)` that can be written more simply + /// ### What it does + /// Checks for usage of `_.filter(_).map(_)` that can be written more simply /// as `filter_map(_)`. /// - /// **Why is this bad?** Redundant code in the `filter` and `map` operations is poor style and + /// ### Why is this bad? + /// Redundant code in the `filter` and `map` operations is poor style and /// less performant. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust /// (0_i32..10) @@ -524,15 +529,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.find(_).map(_)` that can be written more simply + /// ### What it does + /// Checks for usage of `_.find(_).map(_)` that can be written more simply /// as `find_map(_)`. /// - /// **Why is this bad?** Redundant code in the `find` and `map` operations is poor style and + /// ### Why is this bad? + /// Redundant code in the `find` and `map` operations is poor style and /// less performant. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust /// (0_i32..10) @@ -550,14 +555,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.filter_map(_).next()`. + /// ### What it does + /// Checks for usage of `_.filter_map(_).next()`. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.find_map(_)`. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next(); /// ``` @@ -572,13 +577,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `flat_map(|x| x)`. + /// ### What it does + /// Checks for usage of `flat_map(|x| x)`. /// - /// **Why is this bad?** Readability, this can be written more concisely by using `flatten`. + /// ### Why is this bad? + /// Readability, this can be written more concisely by using `flatten`. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// # let iter = vec![vec![0]].into_iter(); /// iter.flat_map(|x| x); @@ -594,16 +599,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for an iterator or string search (such as `find()`, + /// ### What it does + /// Checks for an iterator or string search (such as `find()`, /// `position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`. /// - /// **Why is this bad?** Readability, this can be written more concisely as: + /// ### Why is this bad? + /// Readability, this can be written more concisely as: /// * `_.any(_)`, or `_.contains(_)` for `is_some()`, /// * `!_.any(_)`, or `!_.contains(_)` for `is_none()`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let vec = vec![1]; /// vec.iter().find(|x| **x == 0).is_some(); @@ -623,15 +628,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.chars().next()` on a `str` to check + /// ### What it does + /// Checks for usage of `.chars().next()` on a `str` to check /// if it starts with a given char. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.starts_with(_)`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let name = "foo"; /// if name.chars().next() == Some('_') {}; @@ -647,17 +652,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`, + /// ### What it does + /// Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`, /// etc., and suggests to use `or_else`, `unwrap_or_else`, etc., or /// `unwrap_or_default` instead. /// - /// **Why is this bad?** The function will always be called and potentially + /// ### Why is this bad? + /// The function will always be called and potentially /// allocate an object acting as the default. /// - /// **Known problems:** If the function has side-effects, not calling it will + /// ### Known problems + /// If the function has side-effects, not calling it will /// change the semantic of the program, but you shouldn't rely on that anyway. /// - /// **Example:** + /// ### Example /// ```rust /// # let foo = Some(String::new()); /// foo.unwrap_or(String::new()); @@ -678,15 +686,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, + /// ### What it does + /// Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, /// etc., and suggests to use `unwrap_or_else` instead /// - /// **Why is this bad?** The function will always be called. + /// ### Why is this bad? + /// The function will always be called. /// - /// **Known problems:** If the function has side-effects, not calling it will + /// ### Known problems + /// If the function has side-effects, not calling it will /// change the semantics of the program, but you shouldn't rely on that anyway. /// - /// **Example:** + /// ### Example /// ```rust /// # let foo = Some(String::new()); /// # let err_code = "418"; @@ -713,14 +724,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.clone()` on a `Copy` type. + /// ### What it does + /// Checks for usage of `.clone()` on a `Copy` type. /// - /// **Why is this bad?** The only reason `Copy` types implement `Clone` is for + /// ### Why is this bad? + /// The only reason `Copy` types implement `Clone` is for /// generics, not for using the `clone` method on a concrete type. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// 42u64.clone(); /// ``` @@ -730,15 +741,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer, + /// ### What it does + /// Checks for usage of `.clone()` on a ref-counted pointer, /// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified /// function syntax instead (e.g., `Rc::clone(foo)`). /// - /// **Why is this bad?** Calling '.clone()' on an Rc, Arc, or Weak + /// ### Why is this bad? + /// Calling '.clone()' on an Rc, Arc, or Weak /// can obscure the fact that only the pointer is being cloned, not the underlying /// data. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::rc::Rc; /// let x = Rc::new(1); @@ -755,14 +768,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.clone()` on an `&&T`. + /// ### What it does + /// Checks for usage of `.clone()` on an `&&T`. /// - /// **Why is this bad?** Cloning an `&&T` copies the inner `&T`, instead of + /// ### Why is this bad? + /// Cloning an `&&T` copies the inner `&T`, instead of /// cloning the underlying `T`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn main() { /// let x = vec![1]; @@ -777,16 +790,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.to_string()` on an `&&T` where + /// ### What it does + /// Checks for usage of `.to_string()` on an `&&T` where /// `T` implements `ToString` directly (like `&&str` or `&&String`). /// - /// **Why is this bad?** This bypasses the specialized implementation of + /// ### Why is this bad? + /// This bypasses the specialized implementation of /// `ToString` and instead goes through the more expensive string formatting /// facilities. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Generic implementation for `T: Display` is used (slow) /// ["foo", "bar"].iter().map(|s| s.to_string()); @@ -800,14 +813,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `new` not returning a type that contains `Self`. + /// ### What it does + /// Checks for `new` not returning a type that contains `Self`. /// - /// **Why is this bad?** As a convention, `new` methods are used to make a new + /// ### Why is this bad? + /// As a convention, `new` methods are used to make a new /// instance of a type. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// In an impl block: /// ```rust /// # struct Foo; @@ -861,15 +874,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for string methods that receive a single-character + /// ### What it does + /// Checks for string methods that receive a single-character /// `str` as an argument, e.g., `_.split("x")`. /// - /// **Why is this bad?** Performing these methods using a `char` is faster than + /// ### Why is this bad? + /// Performing these methods using a `char` is faster than /// using a `str`. /// - /// **Known problems:** Does not catch multi-byte unicode characters. + /// ### Known problems + /// Does not catch multi-byte unicode characters. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// _.split("x"); @@ -882,14 +898,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calling `.step_by(0)` on iterators which panics. + /// ### What it does + /// Checks for calling `.step_by(0)` on iterators which panics. /// - /// **Why is this bad?** This very much looks like an oversight. Use `panic!()` instead if you + /// ### Why is this bad? + /// This very much looks like an oversight. Use `panic!()` instead if you /// actually intend to panic. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,should_panic /// for x in (0..100).step_by(0) { /// //.. @@ -901,15 +917,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for indirect collection of populated `Option` + /// ### What it does + /// Checks for indirect collection of populated `Option` /// - /// **Why is this bad?** `Option` is like a collection of 0-1 things, so `flatten` + /// ### Why is this bad? + /// `Option` is like a collection of 0-1 things, so `flatten` /// automatically does this without suspicious-looking `unwrap` calls. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let _ = std::iter::empty::>().filter(Option::is_some).map(Option::unwrap); /// ``` @@ -923,16 +938,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of `iter.nth(0)`. + /// ### What it does + /// Checks for the use of `iter.nth(0)`. /// - /// **Why is this bad?** `iter.next()` is equivalent to + /// ### Why is this bad? + /// `iter.next()` is equivalent to /// `iter.nth(0)`, as they both consume the next element, /// but is more readable. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// # use std::collections::HashSet; /// // Bad @@ -951,15 +965,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `.iter().nth()` (and the related + /// ### What it does + /// Checks for use of `.iter().nth()` (and the related /// `.iter_mut().nth()`) on standard library types with O(1) element access. /// - /// **Why is this bad?** `.get()` and `.get_mut()` are more efficient and more + /// ### Why is this bad? + /// `.get()` and `.get_mut()` are more efficient and more /// readable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.iter().nth(3); @@ -977,13 +991,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `.skip(x).next()` on iterators. + /// ### What it does + /// Checks for use of `.skip(x).next()` on iterators. /// - /// **Why is this bad?** `.nth(x)` is cleaner + /// ### Why is this bad? + /// `.nth(x)` is cleaner /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let some_vec = vec![0, 1, 2, 3]; /// let bad_vec = some_vec.iter().skip(3).next(); @@ -1001,13 +1015,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `.get().unwrap()` (or + /// ### What it does + /// Checks for use of `.get().unwrap()` (or /// `.get_mut().unwrap`) on a standard library type which implements `Index` /// - /// **Why is this bad?** Using the Index trait (`[]`) is more clear and more + /// ### Why is this bad? + /// Using the Index trait (`[]`) is more clear and more /// concise. /// - /// **Known problems:** Not a replacement for error handling: Using either + /// ### Known problems + /// Not a replacement for error handling: Using either /// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic` /// if the value being accessed is `None`. If the use of `.get().unwrap()` is a /// temporary placeholder for dealing with the `Option` type, then this does @@ -1016,7 +1033,7 @@ declare_clippy_lint! { /// is handled in a future refactor instead of using `.unwrap()` or the Index /// trait. /// - /// **Example:** + /// ### Example /// ```rust /// let mut some_vec = vec![0, 1, 2, 3]; /// let last = some_vec.get(3).unwrap(); @@ -1034,14 +1051,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for occurrences where one vector gets extended instead of append + /// ### What it does + /// Checks for occurrences where one vector gets extended instead of append /// - /// **Why is this bad?** Using `append` instead of `extend` is more concise and faster - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Using `append` instead of `extend` is more concise and faster /// + /// ### Example /// ```rust /// let mut a = vec![1, 2, 3]; /// let mut b = vec![4, 5, 6]; @@ -1052,20 +1068,20 @@ declare_clippy_lint! { /// // Good /// a.append(&mut b); /// ``` - pub APPEND_INSTEAD_OF_EXTEND, + pub EXTEND_WITH_DRAIN, perf, "using vec.append(&mut vec) to move the full range of a vecor to another" } declare_clippy_lint! { - /// **What it does:** Checks for the use of `.extend(s.chars())` where s is a + /// ### What it does + /// Checks for the use of `.extend(s.chars())` where s is a /// `&str` or `String`. /// - /// **Why is this bad?** `.push_str(s)` is clearer + /// ### Why is this bad? + /// `.push_str(s)` is clearer /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let abc = "abc"; /// let def = String::from("def"); @@ -1087,14 +1103,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of `.cloned().collect()` on slice to + /// ### What it does + /// Checks for the use of `.cloned().collect()` on slice to /// create a `Vec`. /// - /// **Why is this bad?** `.to_vec()` is clearer + /// ### Why is this bad? + /// `.to_vec()` is clearer /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let s = [1, 2, 3, 4, 5]; /// let s2: Vec = s[..].iter().cloned().collect(); @@ -1110,15 +1126,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.chars().last()` or + /// ### What it does + /// Checks for usage of `_.chars().last()` or /// `_.chars().next_back()` on a `str` to check if it ends with a given char. /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.ends_with(_)`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let name = "_"; /// @@ -1134,14 +1150,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `.as_ref()` or `.as_mut()` where the + /// ### What it does + /// Checks for usage of `.as_ref()` or `.as_mut()` where the /// types before and after the call are the same. /// - /// **Why is this bad?** The call is unnecessary. + /// ### Why is this bad? + /// The call is unnecessary. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn do_stuff(x: &[i32]) {} /// let x: &[i32] = &[1, 2, 3, 4, 5]; @@ -1159,15 +1175,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for using `fold` when a more succinct alternative exists. + /// ### What it does + /// Checks for using `fold` when a more succinct alternative exists. /// Specifically, this checks for `fold`s which could be replaced by `any`, `all`, /// `sum` or `product`. /// - /// **Why is this bad?** Readability. + /// ### Why is this bad? + /// Readability. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let _ = (0..3).fold(false, |acc, x| acc || x > 2); /// ``` @@ -1181,16 +1197,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `filter_map` calls which could be replaced by `filter` or `map`. + /// ### What it does + /// Checks for `filter_map` calls which could be replaced by `filter` or `map`. /// More specifically it checks if the closure provided is only performing one of the /// filter or map operations and suggests the appropriate option. /// - /// **Why is this bad?** Complexity. The intent is also clearer if only a single + /// ### Why is this bad? + /// Complexity. The intent is also clearer if only a single /// operation is being performed. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None }); /// @@ -1210,17 +1226,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `into_iter` calls on references which should be replaced by `iter` + /// ### What it does + /// Checks for `into_iter` calls on references which should be replaced by `iter` /// or `iter_mut`. /// - /// **Why is this bad?** Readability. Calling `into_iter` on a reference will not move out its + /// ### Why is this bad? + /// Readability. Calling `into_iter` on a reference will not move out its /// content into the resulting iterator, which is confusing. It is better just call `iter` or /// `iter_mut` directly. /// - /// **Known problems:** None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let _ = (&vec![3, 4, 5]).into_iter(); @@ -1234,16 +1249,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `map` followed by a `count`. + /// ### What it does + /// Checks for calls to `map` followed by a `count`. /// - /// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`. + /// ### Why is this bad? + /// It looks suspicious. Maybe `map` was confused with `filter`. /// If the `map` call is intentional, this should be rewritten. Or, if you intend to /// drive the iterator to completion, you can just use `for_each` instead. /// - /// **Known problems:** None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let _ = (0..3).map(|x| x + 2).count(); /// ``` @@ -1253,16 +1267,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `MaybeUninit::uninit().assume_init()`. + /// ### What it does + /// Checks for `MaybeUninit::uninit().assume_init()`. /// - /// **Why is this bad?** For most types, this is undefined behavior. + /// ### Why is this bad? + /// For most types, this is undefined behavior. /// - /// **Known problems:** For now, we accept empty tuples and tuples / arrays + /// ### Known problems + /// For now, we accept empty tuples and tuples / arrays /// of `MaybeUninit`. There may be other types that allow uninitialized /// data, but those are not yet rigorously defined. /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Beware the UB /// use std::mem::MaybeUninit; @@ -1285,12 +1301,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`. + /// ### What it does + /// Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`. /// - /// **Why is this bad?** These can be written simply with `saturating_add/sub` methods. - /// - /// **Example:** + /// ### Why is this bad? + /// These can be written simply with `saturating_add/sub` methods. /// + /// ### Example /// ```rust /// # let y: u32 = 0; /// # let x: u32 = 100; @@ -1312,14 +1329,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to + /// ### What it does + /// Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to /// zero-sized types /// - /// **Why is this bad?** This is a no-op, and likely unintended + /// ### Why is this bad? + /// This is a no-op, and likely unintended /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// unsafe { (&() as *const ()).offset(1) }; /// ``` @@ -1329,15 +1346,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `FileType::is_file()`. + /// ### What it does + /// Checks for `FileType::is_file()`. /// - /// **Why is this bad?** When people testing a file type with `FileType::is_file` + /// ### Why is this bad? + /// When people testing a file type with `FileType::is_file` /// they are testing whether a path is something they can get bytes from. But /// `is_file` doesn't cover special file types in unix-like systems, and doesn't cover /// symlink in windows. Using `!FileType::is_dir()` is a better way to that intention. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # || { /// let metadata = std::fs::metadata("foo.txt")?; @@ -1369,14 +1387,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str). + /// ### What it does + /// Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str). /// - /// **Why is this bad?** Readability, this can be written more concisely as + /// ### Why is this bad? + /// Readability, this can be written more concisely as /// `_.as_deref()`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let opt = Some("".to_string()); /// opt.as_ref().map(String::as_str) @@ -1394,13 +1412,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `iter().next()` on a Slice or an Array + /// ### What it does + /// Checks for usage of `iter().next()` on a Slice or an Array /// - /// **Why is this bad?** These can be shortened into `.get()` + /// ### Why is this bad? + /// These can be shortened into `.get()` /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let a = [1, 2, 3]; /// # let b = vec![1, 2, 3]; @@ -1420,14 +1438,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns when using `push_str`/`insert_str` with a single-character string literal + /// ### What it does + /// Warns when using `push_str`/`insert_str` with a single-character string literal /// where `push`/`insert` with a `char` would work fine. /// - /// **Why is this bad?** It's less clear that we are pushing a single character. + /// ### Why is this bad? + /// It's less clear that we are pushing a single character. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// let mut string = String::new(); /// string.insert_str(0, "R"); @@ -1445,7 +1463,8 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** As the counterpart to `or_fun_call`, this lint looks for unnecessary + /// ### What it does + /// As the counterpart to `or_fun_call`, this lint looks for unnecessary /// lazily evaluated closures on `Option` and `Result`. /// /// This lint suggests changing the following functions, when eager evaluation results in @@ -1456,13 +1475,14 @@ declare_clippy_lint! { /// - `get_or_insert_with` to `get_or_insert` /// - `ok_or_else` to `ok_or` /// - /// **Why is this bad?** Using eager evaluation is shorter and simpler in some cases. + /// ### Why is this bad? + /// Using eager evaluation is shorter and simpler in some cases. /// - /// **Known problems:** It is possible, but not recommended for `Deref` and `Index` to have + /// ### Known problems + /// It is possible, but not recommended for `Deref` and `Index` to have /// side effects. Eagerly evaluating them can change the semantics of the program. /// - /// **Example:** - /// + /// ### Example /// ```rust /// // example code where clippy issues a warning /// let opt: Option = None; @@ -1481,14 +1501,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.map(_).collect::()`. + /// ### What it does + /// Checks for usage of `_.map(_).collect::()`. /// - /// **Why is this bad?** Using `try_for_each` instead is more readable and idiomatic. - /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Why is this bad? + /// Using `try_for_each` instead is more readable and idiomatic. /// + /// ### Example /// ```rust /// (0..3).map(|t| Err(t)).collect::>(); /// ``` @@ -1502,16 +1521,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `from_iter()` function calls on types that implement the `FromIterator` + /// ### What it does + /// Checks for `from_iter()` function calls on types that implement the `FromIterator` /// trait. /// - /// **Why is this bad?** It is recommended style to use collect. See + /// ### Why is this bad? + /// It is recommended style to use collect. See /// [FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// use std::iter::FromIterator; /// @@ -1535,15 +1553,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `inspect().for_each()`. + /// ### What it does + /// Checks for usage of `inspect().for_each()`. /// - /// **Why is this bad?** It is the same as performing the computation + /// ### Why is this bad? + /// It is the same as performing the computation /// inside `inspect` at the beginning of the closure in `for_each`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// [1,2,3,4,5].iter() /// .inspect(|&x| println!("inspect the number: {}", x)) @@ -1565,14 +1582,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `filter_map(|x| x)`. + /// ### What it does + /// Checks for usage of `filter_map(|x| x)`. /// - /// **Why is this bad?** Readability, this can be written more concisely by using `flatten`. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Readability, this can be written more concisely by using `flatten`. /// + /// ### Example /// ```rust /// # let iter = vec![Some(1)].into_iter(); /// iter.filter_map(|x| x); @@ -1588,14 +1604,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function. + /// ### What it does + /// Checks for instances of `map(f)` where `f` is the identity function. /// - /// **Why is this bad?** It can be written more concisely without the call to `map`. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// It can be written more concisely without the call to `map`. /// + /// ### Example /// ```rust /// let x = [1, 2, 3]; /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect(); @@ -1611,15 +1626,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of `.bytes().nth()`. + /// ### What it does + /// Checks for the use of `.bytes().nth()`. /// - /// **Why is this bad?** `.as_bytes().get()` is more efficient and more + /// ### Why is this bad? + /// `.as_bytes().get()` is more efficient and more /// readable. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let _ = "Hello".bytes().nth(3); @@ -1633,15 +1647,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer. + /// ### What it does + /// Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer. /// - /// **Why is this bad?** These methods do the same thing as `_.clone()` but may be confusing as + /// ### Why is this bad? + /// These methods do the same thing as `_.clone()` but may be confusing as /// to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let a = vec![1, 2, 3]; /// let b = a.to_vec(); @@ -1659,15 +1672,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of `.iter().count()`. + /// ### What it does + /// Checks for the use of `.iter().count()`. /// - /// **Why is this bad?** `.len()` is more efficient and more + /// ### Why is this bad? + /// `.len()` is more efficient and more /// readable. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let some_vec = vec![0, 1, 2, 3]; @@ -1685,17 +1697,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to [`splitn`] + /// ### What it does + /// Checks for calls to [`splitn`] /// (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and /// related functions with either zero or one splits. /// - /// **Why is this bad?** These calls don't actually split the value and are + /// ### Why is this bad? + /// These calls don't actually split the value and are /// likely to be intended as a different number. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let s = ""; @@ -1715,14 +1726,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for manual implementations of `str::repeat` + /// ### What it does + /// Checks for manual implementations of `str::repeat` /// - /// **Why is this bad?** These are both harder to read, as well as less performant. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// These are both harder to read, as well as less performant. /// + /// ### Example /// ```rust /// // Bad /// let x: String = std::iter::repeat('x').take(10).collect(); @@ -1811,7 +1821,7 @@ impl_lint_pass!(Methods => [ IMPLICIT_CLONE, SUSPICIOUS_SPLITN, MANUAL_STR_REPEAT, - APPEND_INSTEAD_OF_EXTEND + EXTEND_WITH_DRAIN ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -2075,7 +2085,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio }, ("extend", [arg]) => { string_extend_chars::check(cx, expr, recv, arg); - append_instead_of_extend::check(cx, expr, recv, arg); + extend_with_drain::check(cx, expr, recv, arg); }, ("filter_map", [arg]) => { unnecessary_filter_map::check(cx, expr, arg); diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index 073c5570a88..ef615b0aa40 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::is_lazyness_candidate; use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_macro_callsite}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, match_type}; -use clippy_utils::{contains_return, get_trait_def_id, last_path_segment, paths}; +use clippy_utils::{contains_return, last_path_segment, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -41,7 +41,7 @@ pub(super) fn check<'tcx>( let path = last_path_segment(qpath).ident.name; if matches!(path, kw::Default | sym::new); let arg_ty = cx.typeck_results().expr_ty(arg); - if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); + if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default); if implements_trait(cx, arg_ty, default_trait_id, &[]); then { diff --git a/src/tools/clippy/clippy_lints/src/minmax.rs b/src/tools/clippy/clippy_lints/src/minmax.rs index ff3473b744e..dc2dd45e4ed 100644 --- a/src/tools/clippy/clippy_lints/src/minmax.rs +++ b/src/tools/clippy/clippy_lints/src/minmax.rs @@ -8,15 +8,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::cmp::Ordering; declare_clippy_lint! { - /// **What it does:** Checks for expressions where `std::cmp::min` and `max` are + /// ### What it does + /// Checks for expressions where `std::cmp::min` and `max` are /// used to clamp values, but switched so that the result is constant. /// - /// **Why is this bad?** This is in all probability not the intended outcome. At + /// ### Why is this bad? + /// This is in all probability not the intended outcome. At /// the least it hurts readability of the code. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```ignore /// min(0, max(100, x)) /// ``` diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index 7cfce2e61cc..c796abe9815 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -25,10 +25,12 @@ use clippy_utils::{ }; declare_clippy_lint! { - /// **What it does:** Checks for function arguments and let bindings denoted as + /// ### What it does + /// Checks for function arguments and let bindings denoted as /// `ref`. /// - /// **Why is this bad?** The `ref` declaration makes the function take an owned + /// ### Why is this bad? + /// The `ref` declaration makes the function take an owned /// value, but turns the argument into a reference (which means that the value /// is destroyed when exiting the function). This adds not much value: either /// take a reference type, or take an owned value and create references in the @@ -37,11 +39,12 @@ declare_clippy_lint! { /// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The /// type of `x` is more obvious with the former. /// - /// **Known problems:** If the argument is dereferenced within the function, + /// ### Known problems + /// If the argument is dereferenced within the function, /// removing the `ref` will lead to errors. This can be fixed by removing the /// dereferences, e.g., changing `*x` to `x` within the function. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// fn foo(ref x: u8) -> bool { @@ -59,14 +62,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for comparisons to NaN. + /// ### What it does + /// Checks for comparisons to NaN. /// - /// **Why is this bad?** NaN does not compare meaningfully to anything – not + /// ### Why is this bad? + /// NaN does not compare meaningfully to anything – not /// even itself – so those comparisons are simply wrong. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1.0; /// @@ -82,18 +85,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for (in-)equality comparisons on floating-point + /// ### What it does + /// Checks for (in-)equality comparisons on floating-point /// values (apart from zero), except in functions called `*eq*` (which probably /// implement equality for a type involving floats). /// - /// **Why is this bad?** Floating point calculations are usually imprecise, so + /// ### Why is this bad? + /// Floating point calculations are usually imprecise, so /// asking if two values are *exactly* equal is asking for trouble. For a good /// guide on what to do, see [the floating point /// guide](http://www.floating-point-gui.de/errors/comparison). /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = 1.2331f64; /// let y = 1.2332f64; @@ -115,16 +118,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for conversions to owned values just for the sake + /// ### What it does + /// Checks for conversions to owned values just for the sake /// of a comparison. /// - /// **Why is this bad?** The comparison can operate on a reference, so creating + /// ### Why is this bad? + /// The comparison can operate on a reference, so creating /// an owned value effectively throws it away directly afterwards, which is /// needlessly consuming code and heap space. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = "foo"; /// # let y = String::from("foo"); @@ -142,18 +145,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for getting the remainder of a division by one or minus + /// ### What it does + /// Checks for getting the remainder of a division by one or minus /// one. /// - /// **Why is this bad?** The result for a divisor of one can only ever be zero; for + /// ### Why is this bad? + /// The result for a divisor of one can only ever be zero; for /// minus one it can cause panic/overflow (if the left operand is the minimal value of /// the respective integer type) or results in zero. No one will write such code /// deliberately, unless trying to win an Underhanded Rust Contest. Even for that /// contest, it's probably a bad idea. Use something more underhanded. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// let a = x % 1; @@ -165,17 +168,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of bindings with a single leading + /// ### What it does + /// Checks for the use of bindings with a single leading /// underscore. /// - /// **Why is this bad?** A single leading underscore is usually used to indicate + /// ### Why is this bad? + /// A single leading underscore is usually used to indicate /// that a binding will not be used. Using such a binding breaks this /// expectation. /// - /// **Known problems:** The lint does not work properly with desugaring and + /// ### Known problems + /// The lint does not work properly with desugaring and /// macro, it has been allowed in the mean time. /// - /// **Example:** + /// ### Example /// ```rust /// let _x = 0; /// let y = _x + 1; // Here we are using `_x`, even though it has a leading @@ -187,17 +193,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the use of short circuit boolean conditions as + /// ### What it does + /// Checks for the use of short circuit boolean conditions as /// a /// statement. /// - /// **Why is this bad?** Using a short circuit boolean condition as a statement + /// ### Why is this bad? + /// Using a short circuit boolean condition as a statement /// may hide the fact that the second part is executed or not depending on the /// outcome of the first part. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// f() && g(); // We should write `if f() { g(); }`. /// ``` @@ -207,15 +213,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Catch casts from `0` to some pointer type + /// ### What it does + /// Catch casts from `0` to some pointer type /// - /// **Why is this bad?** This generally means `null` and is better expressed as + /// ### Why is this bad? + /// This generally means `null` and is better expressed as /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// let a = 0 as *const u32; @@ -229,18 +234,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for (in-)equality comparisons on floating-point + /// ### What it does + /// Checks for (in-)equality comparisons on floating-point /// value and constant, except in functions called `*eq*` (which probably /// implement equality for a type involving floats). /// - /// **Why is this bad?** Floating point calculations are usually imprecise, so + /// ### Why is this bad? + /// Floating point calculations are usually imprecise, so /// asking if two values are *exactly* equal is asking for trouble. For a good /// guide on what to do, see [the floating point /// guide](http://www.floating-point-gui.de/errors/comparison). /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x: f64 = 1.0; /// const ONE: f64 = 1.00; diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs index 050b6805b7c..06fe967dafc 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs @@ -18,14 +18,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; declare_clippy_lint! { - /// **What it does:** Checks for structure field patterns bound to wildcards. + /// ### What it does + /// Checks for structure field patterns bound to wildcards. /// - /// **Why is this bad?** Using `..` instead is shorter and leaves the focus on + /// ### Why is this bad? + /// Using `..` instead is shorter and leaves the focus on /// the fields that are actually bound. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct Foo { /// # a: i32, @@ -52,14 +52,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for function arguments having the similar names + /// ### What it does + /// Checks for function arguments having the similar names /// differing by an underscore. /// - /// **Why is this bad?** It affects code readability. + /// ### Why is this bad? + /// It affects code readability. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// fn foo(a: i32, _a: i32) {} @@ -73,14 +73,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Detects expressions of the form `--x`. + /// ### What it does + /// Detects expressions of the form `--x`. /// - /// **Why is this bad?** It can mislead C/C++ programmers to think `x` was + /// ### Why is this bad? + /// It can mislead C/C++ programmers to think `x` was /// decremented. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let mut x = 3; /// --x; @@ -91,14 +91,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns on hexadecimal literals with mixed-case letter + /// ### What it does + /// Warns on hexadecimal literals with mixed-case letter /// digits. /// - /// **Why is this bad?** It looks confusing. + /// ### Why is this bad? + /// It looks confusing. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let y = 0x1a9BAcD; @@ -112,14 +112,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if literal suffixes are not separated by an + /// ### What it does + /// Warns if literal suffixes are not separated by an /// underscore. /// - /// **Why is this bad?** It is much less readable. + /// ### Why is this bad? + /// It is much less readable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let y = 123832i32; @@ -133,17 +133,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if an integral constant literal starts with `0`. + /// ### What it does + /// Warns if an integral constant literal starts with `0`. /// - /// **Why is this bad?** In some languages (including the infamous C language + /// ### Why is this bad? + /// In some languages (including the infamous C language /// and most of its /// family), this marks an octal constant. In Rust however, this is a decimal /// constant. This could /// be confusing for both the writer and a reader of the constant. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// In Rust: /// ```rust @@ -171,13 +171,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Warns if a generic shadows a built-in type. + /// ### What it does + /// Warns if a generic shadows a built-in type. /// - /// **Why is this bad?** This gives surprising type errors. + /// ### Why is this bad? + /// This gives surprising type errors. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```ignore /// impl Foo { @@ -192,14 +192,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for patterns in the form `name @ _`. + /// ### What it does + /// Checks for patterns in the form `name @ _`. /// - /// **Why is this bad?** It's almost always more readable to just use direct + /// ### Why is this bad? + /// It's almost always more readable to just use direct /// bindings. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let v = Some("abc"); /// @@ -221,19 +221,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for tuple patterns with a wildcard + /// ### What it does + /// Checks for tuple patterns with a wildcard /// pattern (`_`) is next to a rest pattern (`..`). /// /// _NOTE_: While `_, ..` means there is at least one element left, `..` /// means there are 0 or more elements left. This can make a difference /// when refactoring, but shouldn't result in errors in the refactored code, /// since the wildcard pattern isn't used anyway. - /// **Why is this bad?** The wildcard pattern is unneeded as the rest pattern + /// ### Why is this bad? + /// The wildcard pattern is unneeded as the rest pattern /// can match that element as well. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct TupleStruct(u32, u32, u32); /// # let t = TupleStruct(1, 2, 3); diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 59cbc481ed4..5b2584d43a1 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -13,16 +13,13 @@ use rustc_span::Span; use rustc_typeck::hir_ty_to_ty; declare_clippy_lint! { - /// **What it does:** - /// + /// ### What it does /// Suggests the use of `const` in functions and methods where possible. /// - /// **Why is this bad?** - /// + /// ### Why is this bad? /// Not having the function const prevents callers of the function from being const as well. /// - /// **Known problems:** - /// + /// ### Known problems /// Const functions are currently still being worked on, with some features only being available /// on nightly. This lint does not consider all edge cases currently and the suggestions may be /// incorrect if you are using this lint on stable. @@ -42,8 +39,7 @@ declare_clippy_lint! { /// can't be const as it calls a non-const function. Making `a` const and running Clippy again, /// will suggest to make `b` const, too. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # struct Foo { /// # random_number: usize, diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 6ad702f8eaf..d358e9fb876 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -16,15 +16,15 @@ use rustc_span::source_map::Span; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Warns if there is missing doc for any documentable item + /// ### What it does + /// Warns if there is missing doc for any documentable item /// (public or private). /// - /// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS` + /// ### Why is this bad? + /// Doc is good. *rustc* has a `MISSING_DOCS` /// allowed-by-default lint for /// public members, but has no way to enforce documentation of private items. /// This lint fixes that. - /// - /// **Known problems:** None. pub MISSING_DOCS_IN_PRIVATE_ITEMS, restriction, "detects missing documentation for public and private members" diff --git a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs index 59565350f72..9d27870321c 100644 --- a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs +++ b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs @@ -10,17 +10,16 @@ use rustc_span::Symbol; use crate::utils::conf::Rename; declare_clippy_lint! { - /// **What it does:** Checks for imports that do not rename the item as specified + /// ### What it does + /// Checks for imports that do not rename the item as specified /// in the `enforce-import-renames` config option. /// - /// **Why is this bad?** Consistency is important, if a project has defined import + /// ### Why is this bad? + /// Consistency is important, if a project has defined import /// renames they should be followed. More practically, some item names are too /// vague outside of their defining scope this can enforce a more meaningful naming. /// - /// **Known problems:** None - /// - /// **Example:** - /// + /// ### Example /// An example clippy.toml configuration: /// ```toml /// # clippy.toml diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 041fe64a1a9..be5b4b4006f 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -7,10 +7,12 @@ use rustc_span::source_map::Span; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** it lints if an exported function, method, trait method with default impl, + /// ### What it does + /// it lints if an exported function, method, trait method with default impl, /// or trait method impl is not `#[inline]`. /// - /// **Why is this bad?** In general, it is not. Functions can be inlined across + /// ### Why is this bad? + /// In general, it is not. Functions can be inlined across /// crates when that's profitable as long as any form of LTO is used. When LTO is disabled, /// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates /// might intend for most of the methods in their public API to be able to be inlined across @@ -18,9 +20,7 @@ declare_clippy_lint! { /// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and /// then opt out for specific methods where this might not make sense. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// pub fn foo() {} // missing #[inline] /// fn ok() {} // ok diff --git a/src/tools/clippy/clippy_lints/src/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/modulo_arithmetic.rs index 1414fdc1b11..2d14943b56c 100644 --- a/src/tools/clippy/clippy_lints/src/modulo_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/modulo_arithmetic.rs @@ -9,18 +9,18 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::fmt::Display; declare_clippy_lint! { - /// **What it does:** Checks for modulo arithmetic. + /// ### What it does + /// Checks for modulo arithmetic. /// - /// **Why is this bad?** The results of modulo (%) operation might differ + /// ### Why is this bad? + /// The results of modulo (%) operation might differ /// depending on the language, when negative numbers are involved. /// If you interop with different languages it might be beneficial /// to double check all places that use modulo arithmetic. /// /// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = -17 % 3; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/multiple_crate_versions.rs b/src/tools/clippy/clippy_lints/src/multiple_crate_versions.rs index f5ce3e32551..1c61970fdc8 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_crate_versions.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_crate_versions.rs @@ -13,17 +13,20 @@ use if_chain::if_chain; use itertools::Itertools; declare_clippy_lint! { - /// **What it does:** Checks to see if multiple versions of a crate are being + /// ### What it does + /// Checks to see if multiple versions of a crate are being /// used. /// - /// **Why is this bad?** This bloats the size of targets, and can lead to + /// ### Why is this bad? + /// This bloats the size of targets, and can lead to /// confusing error messages when structs or traits are used interchangeably /// between different versions of a crate. /// - /// **Known problems:** Because this can be caused purely by the dependencies + /// ### Known problems + /// Because this can be caused purely by the dependencies /// themselves, it's not always possible to fix this issue. /// - /// **Example:** + /// ### Example /// ```toml /// # This will pull in both winapi v0.3.x and v0.2.x, triggering a warning. /// [dependencies] diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 4dbbb14c504..2c7681c45a4 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -1,26 +1,30 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::{match_def_path, paths, trait_ref_of_method}; +use clippy_utils::trait_ref_of_method; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{Adt, Array, RawPtr, Ref, Slice, Tuple, Ty, TypeAndMut}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use rustc_span::symbol::sym; use std::iter; declare_clippy_lint! { - /// **What it does:** Checks for sets/maps with mutable key types. + /// ### What it does + /// Checks for sets/maps with mutable key types. /// - /// **Why is this bad?** All of `HashMap`, `HashSet`, `BTreeMap` and + /// ### Why is this bad? + /// All of `HashMap`, `HashSet`, `BTreeMap` and /// `BtreeSet` rely on either the hash or the order of keys be unchanging, /// so having types with interior mutability is a bad idea. /// - /// **Known problems:** It's correct to use a struct, that contains interior mutability + /// ### Known problems + /// It's correct to use a struct, that contains interior mutability /// as a key, when its `Hash` implementation doesn't access any of the interior mutable types. /// However, this lint is unable to recognize this, so it causes a false positive in theses cases. /// The `bytes` crate is a great example of this. /// - /// **Example:** + /// ### Example /// ```rust /// use std::cmp::{PartialEq, Eq}; /// use std::collections::HashSet; @@ -99,9 +103,9 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir:: fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = ty.peel_refs(); if let Adt(def, substs) = ty.kind() { - if [&paths::HASHMAP, &paths::BTREEMAP, &paths::HASHSET, &paths::BTREESET] + if [sym::hashmap_type, sym::BTreeMap, sym::hashset_type, sym::BTreeMap] .iter() - .any(|path| match_def_path(cx, def.did, &**path)) + .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did)) && is_mutable_type(cx, substs.type_at(0), span) { span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type"); diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs index 4b9c51d0c16..d5032c5ba7f 100644 --- a/src/tools/clippy/clippy_lints/src/mut_mut.rs +++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs @@ -9,15 +9,15 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for instances of `mut mut` references. + /// ### What it does + /// Checks for instances of `mut mut` references. /// - /// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the + /// ### Why is this bad? + /// Multiple `mut`s don't add anything meaningful to the /// source. This is either a copy'n'paste error, or it shows a fundamental /// misunderstanding of references. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let mut y = 1; /// let x = &mut &mut y; diff --git a/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs index b9ba74c7d02..85e870632a5 100644 --- a/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs +++ b/src/tools/clippy/clippy_lints/src/mut_mutex_lock.rs @@ -8,17 +8,16 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for `&mut Mutex::lock` calls + /// ### What it does + /// Checks for `&mut Mutex::lock` calls /// - /// **Why is this bad?** `Mutex::lock` is less efficient than + /// ### Why is this bad? + /// `Mutex::lock` is less efficient than /// calling `Mutex::get_mut`. In addition you also have a statically /// guarantee that the mutex isn't locked, instead of just a runtime /// guarantee. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// use std::sync::{Arc, Mutex}; /// diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 6efe8ffcde0..8d5d7951fc5 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -7,15 +7,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::iter; declare_clippy_lint! { - /// **What it does:** Detects passing a mutable reference to a function that only + /// ### What it does + /// Detects passing a mutable reference to a function that only /// requires an immutable reference. /// - /// **Why is this bad?** The mutable reference rules out all other references to + /// ### Why is this bad? + /// The mutable reference rules out all other references to /// the value. Also the code misleads about the intent of the call site. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// // Bad /// my_vec.push(&mut value) diff --git a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs index 25645a0e7a2..9b44cf9d43a 100644 --- a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs +++ b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs @@ -9,17 +9,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for function/method calls with a mutable + /// ### What it does + /// Checks for function/method calls with a mutable /// parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros. /// - /// **Why is this bad?** In release builds `debug_assert!` macros are optimized out by the + /// ### Why is this bad? + /// In release builds `debug_assert!` macros are optimized out by the /// compiler. /// Therefore mutating something in a `debug_assert!` macro results in different behaviour /// between a release and debug build. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// debug_assert_eq!(vec![3].pop(), Some(3)); /// // or diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs index 354e2c3fb74..436ceec6cfa 100644 --- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs +++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs @@ -10,17 +10,20 @@ use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for usages of `Mutex` where an atomic will do. + /// ### What it does + /// Checks for usages of `Mutex` where an atomic will do. /// - /// **Why is this bad?** Using a mutex just to make access to a plain bool or + /// ### Why is this bad? + /// Using a mutex just to make access to a plain bool or /// reference sequential is shooting flies with cannons. /// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and /// faster. /// - /// **Known problems:** This lint cannot detect if the mutex is actually used + /// ### Known problems + /// This lint cannot detect if the mutex is actually used /// for waiting before a critical section. /// - /// **Example:** + /// ### Example /// ```rust /// # let y = true; /// @@ -38,17 +41,20 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usages of `Mutex` where `X` is an integral + /// ### What it does + /// Checks for usages of `Mutex` where `X` is an integral /// type. /// - /// **Why is this bad?** Using a mutex just to make access to a plain integer + /// ### Why is this bad? + /// Using a mutex just to make access to a plain integer /// sequential is /// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster. /// - /// **Known problems:** This lint cannot detect if the mutex is actually used + /// ### Known problems + /// This lint cannot detect if the mutex is actually used /// for waiting before a critical section. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::sync::Mutex; /// let x = Mutex::new(0usize); diff --git a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs index fe3c4455be5..9a3d9383cd9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs +++ b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs @@ -9,13 +9,13 @@ use rustc_span::symbol::kw; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** The lint checks for `self` in fn parameters that + /// ### What it does + /// The lint checks for `self` in fn parameters that /// specify the `Self`-type explicitly - /// **Why is this bad?** Increases the amount and decreases the readability of code + /// ### Why is this bad? + /// Increases the amount and decreases the readability of code /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// enum ValType { /// I32, diff --git a/src/tools/clippy/clippy_lints/src/needless_bitwise_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bitwise_bool.rs index b30bfbd4294..203da29cb91 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bitwise_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bitwise_bool.rs @@ -9,20 +9,19 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using /// a lazy and. /// - /// **Why is this bad?** + /// ### Why is this bad? /// The bitwise operators do not support short-circuiting, so it may hinder code performance. /// Additionally, boolean logic "masked" as bitwise logic is not caught by lints like `unnecessary_fold` /// - /// **Known problems:** + /// ### Known problems /// This lint evaluates only when the right side is determined to have no side effects. At this time, that /// determination is quite conservative. /// - /// **Example:** - /// + /// ### Example /// ```rust /// let (x,y) = (true, false); /// if x & !y {} // where both x and y are booleans diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs index 780690548e5..36f2829a5b9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs @@ -15,17 +15,20 @@ use rustc_span::source_map::Spanned; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for expressions of the form `if c { true } else { + /// ### What it does + /// Checks for expressions of the form `if c { true } else { /// false }` (or vice versa) and suggests using the condition directly. /// - /// **Why is this bad?** Redundant code. + /// ### Why is this bad? + /// Redundant code. /// - /// **Known problems:** Maybe false positives: Sometimes, the two branches are + /// ### Known problems + /// Maybe false positives: Sometimes, the two branches are /// painstakingly documented (which we, of course, do not detect), so they *may* /// have some value. Even then, the documentation can be rewritten to match the /// shorter code. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// if x { /// false @@ -43,15 +46,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for expressions of the form `x == true`, + /// ### What it does + /// Checks for expressions of the form `x == true`, /// `x != true` and order comparisons such as `x < true` (or vice versa) and /// suggest using the variable directly. /// - /// **Why is this bad?** Unnecessary code. + /// ### Why is this bad? + /// Unnecessary code. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// if x == true {} /// if y == false {} diff --git a/src/tools/clippy/clippy_lints/src/needless_borrow.rs b/src/tools/clippy/clippy_lints/src/needless_borrow.rs index dd1dfa2bdfb..3f0b23ee4d3 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrow.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrow.rs @@ -17,15 +17,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for address of operations (`&`) that are going to + /// ### What it does + /// Checks for address of operations (`&`) that are going to /// be dereferenced immediately by the compiler. /// - /// **Why is this bad?** Suggests that the receiver of the expression borrows + /// ### Why is this bad? + /// Suggests that the receiver of the expression borrows /// the expression. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let x: &i32 = &&&&&&5; @@ -39,13 +39,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `ref` bindings which create a reference to a reference. + /// ### What it does + /// Checks for `ref` bindings which create a reference to a reference. /// - /// **Why is this bad?** The address-of operator at the use site is clearer about the need for a reference. + /// ### Why is this bad? + /// The address-of operator at the use site is clearer about the need for a reference. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let x = Some(""); diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs index 0e976b130eb..36879eda7c0 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs @@ -7,12 +7,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for bindings that destructure a reference and borrow the inner + /// ### What it does + /// Checks for bindings that destructure a reference and borrow the inner /// value with `&ref`. /// - /// **Why is this bad?** This pattern has no effect in almost all cases. + /// ### Why is this bad? + /// This pattern has no effect in almost all cases. /// - /// **Known problems:** In some cases, `&ref` is needed to avoid a lifetime mismatch error. + /// ### Known problems + /// In some cases, `&ref` is needed to avoid a lifetime mismatch error. /// Example: /// ```rust /// fn foo(a: &Option, b: &Option) { @@ -23,7 +26,7 @@ declare_clippy_lint! { /// } /// ``` /// - /// **Example:** + /// ### Example /// Bad: /// ```rust /// let mut v = Vec::::new(); diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs index 91c97ef7c2a..5088b8bb0d3 100644 --- a/src/tools/clippy/clippy_lints/src/needless_continue.rs +++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs @@ -42,20 +42,20 @@ use rustc_span::source_map::{original_sp, DUMMY_SP}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** The lint checks for `if`-statements appearing in loops + /// ### What it does + /// The lint checks for `if`-statements appearing in loops /// that contain a `continue` statement in either their main blocks or their /// `else`-blocks, when omitting the `else`-block possibly with some /// rearrangement of code can make the code easier to understand. /// - /// **Why is this bad?** Having explicit `else` blocks for `if` statements + /// ### Why is this bad? + /// Having explicit `else` blocks for `if` statements /// containing `continue` in their THEN branch adds unnecessary branching and /// nesting to the code. Having an else block containing just `continue` can /// also be better written by grouping the statements following the whole `if` /// statement within the THEN block and omitting the else block completely. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// # fn condition() -> bool { false } /// # fn update_condition() {} @@ -273,6 +273,8 @@ struct LintData<'a> { block_stmts: &'a [ast::Stmt], } +const MSG_REDUNDANT_CONTINUE_EXPRESSION: &str = "this `continue` expression is redundant"; + const MSG_REDUNDANT_ELSE_BLOCK: &str = "this `else` block is redundant"; const MSG_ELSE_BLOCK_NOT_NEEDED: &str = "there is no need for an explicit `else` block for this `if` \ @@ -283,6 +285,8 @@ const DROP_ELSE_BLOCK_AND_MERGE_MSG: &str = "consider dropping the `else` clause const DROP_ELSE_BLOCK_MSG: &str = "consider dropping the `else` clause"; +const DROP_CONTINUE_EXPRESSION_MSG: &str = "consider dropping the `continue` expression"; + fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str, typ: LintType) { // snip is the whole *help* message that appears after the warning. // message is the warning message. @@ -364,6 +368,22 @@ fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data: } fn check_and_warn<'a>(cx: &EarlyContext<'_>, expr: &'a ast::Expr) { + if_chain! { + if let ast::ExprKind::Loop(loop_block, ..) = &expr.kind; + if let Some(last_stmt) = loop_block.stmts.last(); + if let ast::StmtKind::Expr(inner_expr) | ast::StmtKind::Semi(inner_expr) = &last_stmt.kind; + if let ast::ExprKind::Continue(_) = inner_expr.kind; + then { + span_lint_and_help( + cx, + NEEDLESS_CONTINUE, + last_stmt.span, + MSG_REDUNDANT_CONTINUE_EXPRESSION, + None, + DROP_CONTINUE_EXPRESSION_MSG, + ); + } + } with_loop_block(expr, |loop_block, label| { for (i, stmt) in loop_block.stmts.iter().enumerate() { with_if_expr(stmt, |if_expr, cond, then_block, else_expr| { diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs index a723a472a25..d9aa42fe8ee 100644 --- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs +++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs @@ -16,18 +16,17 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::has_iter_method; declare_clippy_lint! { - /// **What it does:** Checks for usage of `for_each` that would be more simply written as a + /// ### What it does + /// Checks for usage of `for_each` that would be more simply written as a /// `for` loop. /// - /// **Why is this bad?** `for_each` may be used after applying iterator transformers like + /// ### Why is this bad? + /// `for_each` may be used after applying iterator transformers like /// `filter` for better readability and performance. It may also be used to fit a simple /// operation on one line. /// But when none of these apply, a simple `for` loop is more idiomatic. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let v = vec![0, 1, 2]; /// v.iter().for_each(|elem| { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 57fd03f4e12..03eeb54d8d1 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -24,20 +24,22 @@ use rustc_typeck::expr_use_visitor as euv; use std::borrow::Cow; declare_clippy_lint! { - /// **What it does:** Checks for functions taking arguments by value, but not + /// ### What it does + /// Checks for functions taking arguments by value, but not /// consuming them in its /// body. /// - /// **Why is this bad?** Taking arguments by reference is more flexible and can + /// ### Why is this bad? + /// Taking arguments by reference is more flexible and can /// sometimes avoid /// unnecessary allocations. /// - /// **Known problems:** + /// ### Known problems /// * This lint suggests taking an argument by reference, /// however sometimes it is better to let users decide the argument type /// (by using `Borrow` trait, for example), depending on how the function is used. /// - /// **Example:** + /// ### Example /// ```rust /// fn foo(v: Vec) { /// assert_eq!(v.len(), 42); @@ -103,7 +105,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } // Allow `Borrow` or functions to be taken by value - let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT)); let allowed_traits = [ need!(cx.tcx.lang_items().fn_trait()), need!(cx.tcx.lang_items().fn_once_trait()), @@ -167,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let preds = preds.iter().filter(|t| t.self_ty() == ty).collect::>(); ( - preds.iter().any(|t| t.def_id() == borrow_trait), + preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())), !preds.is_empty() && { let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty); preds.iter().all(|t| { diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs index c64491c63e2..42e48336e15 100644 --- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs @@ -10,15 +10,13 @@ use rustc_middle::ty::TyS; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Suggests alternatives for useless applications of `?` in terminating expressions /// - /// **Why is this bad?** There's no reason to use `?` to short-circuit when execution of the body will end there anyway. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// There's no reason to use `?` to short-circuit when execution of the body will end there anyway. /// + /// ### Example /// ```rust /// struct TO { /// magic: Option, diff --git a/src/tools/clippy/clippy_lints/src/needless_update.rs b/src/tools/clippy/clippy_lints/src/needless_update.rs index 8f325404deb..2a33b7392ca 100644 --- a/src/tools/clippy/clippy_lints/src/needless_update.rs +++ b/src/tools/clippy/clippy_lints/src/needless_update.rs @@ -5,18 +5,18 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for needlessly including a base struct on update + /// ### What it does + /// Checks for needlessly including a base struct on update /// when all fields are changed anyway. /// /// This lint is not applied to structs marked with /// [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html). /// - /// **Why is this bad?** This will cost resources (because the base has to be + /// ### Why is this bad? + /// This will cost resources (because the base has to be /// somewhere), and make the code less readable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # struct Point { /// # x: i32, diff --git a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index c824f6f54b5..6ad49b70605 100644 --- a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -8,19 +8,16 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for the usage of negated comparison operators on types which only implement /// `PartialOrd` (e.g., `f64`). /// - /// **Why is this bad?** + /// ### Why is this bad? /// These operators make it easy to forget that the underlying types actually allow not only three /// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is /// especially easy to miss if the operator based comparison result is negated. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// use std::cmp::Ordering; /// diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs index d5e1ea6d242..fa36d8fb1b3 100644 --- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs +++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs @@ -7,13 +7,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; declare_clippy_lint! { - /// **What it does:** Checks for multiplication by -1 as a form of negation. + /// ### What it does + /// Checks for multiplication by -1 as a form of negation. /// - /// **Why is this bad?** It's more readable to just negate. + /// ### Why is this bad? + /// It's more readable to just negate. /// - /// **Known problems:** This only catches integers (for now). + /// ### Known problems + /// This only catches integers (for now). /// - /// **Example:** + /// ### Example /// ```ignore /// x * -1 /// ``` diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index a5f91eb035f..5c63d245bf1 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -1,31 +1,29 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::paths; +use clippy_utils::return_ty; use clippy_utils::source::snippet; use clippy_utils::sugg::DiagnosticBuilderExt; -use clippy_utils::{get_trait_def_id, return_ty}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::HirIdSet; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{Ty, TyS}; +use rustc_middle::ty::TyS; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for types with a `fn new() -> Self` method and no + /// ### What it does + /// Checks for types with a `fn new() -> Self` method and no /// implementation of /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html). /// - /// **Why is this bad?** The user might expect to be able to use + /// ### Why is this bad? + /// The user might expect to be able to use /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the /// type can be constructed without arguments. /// - /// **Known problems:** Hopefully none. - /// - /// **Example:** - /// + /// ### Example /// ```ignore /// struct Foo(Bar); /// @@ -65,6 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if let hir::ItemKind::Impl(hir::Impl { of_trait: None, ref generics, + self_ty: impl_self_ty, items, .. }) = item.kind @@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { let self_def_id = cx.tcx.hir().local_def_id(cx.tcx.hir().get_parent_item(id)); let self_ty = cx.tcx.type_of(self_def_id); if TyS::same_type(self_ty, return_ty(cx, id)); - if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); + if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default); then { if self.impling_types.is_none() { let mut impls = HirIdSet::default(); @@ -132,6 +131,8 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { } let generics_sugg = snippet(cx, generics.span, ""); + let self_ty_fmt = self_ty.to_string(); + let self_type_snip = snippet(cx, impl_self_ty.span, &self_ty_fmt); span_lint_hir_and_then( cx, NEW_WITHOUT_DEFAULT, @@ -139,14 +140,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { impl_item.span, &format!( "you should consider adding a `Default` implementation for `{}`", - self_ty + self_type_snip ), |diag| { diag.suggest_prepend_item( cx, item.span, - "try this", - &create_new_without_default_suggest_msg(self_ty, &generics_sugg), + "try adding this", + &create_new_without_default_suggest_msg(&self_type_snip, &generics_sugg), Applicability::MaybeIncorrect, ); }, @@ -160,12 +161,12 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { } } -fn create_new_without_default_suggest_msg(ty: Ty<'_>, generics_sugg: &str) -> String { +fn create_new_without_default_suggest_msg(self_type_snip: &str, generics_sugg: &str) -> String { #[rustfmt::skip] format!( "impl{} Default for {} {{ fn default() -> Self {{ Self::new() }} -}}", generics_sugg, ty) +}}", generics_sugg, self_type_snip) } diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 910b0536092..e07518b2586 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -9,15 +9,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::ops::Deref; declare_clippy_lint! { - /// **What it does:** Checks for statements which have no effect. + /// ### What it does + /// Checks for statements which have no effect. /// - /// **Why is this bad?** Similar to dead code, these statements are actually + /// ### Why is this bad? + /// Similar to dead code, these statements are actually /// executed. However, as they have no effect, all they do is make the code less /// readable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// 0; /// ``` @@ -27,15 +27,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for expression statements that can be reduced to a + /// ### What it does + /// Checks for expression statements that can be reduced to a /// sub-expression. /// - /// **Why is this bad?** Expressions by themselves often have no side-effects. + /// ### Why is this bad? + /// Expressions by themselves often have no side-effects. /// Having such expressions reduces readability. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// compute_array()[0]; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index d775cd7c7f7..aa3067876eb 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -24,10 +24,12 @@ use rustc_typeck::hir_ty_to_ty; // FIXME: this is a correctness problem but there's no suitable // warn-by-default category. declare_clippy_lint! { - /// **What it does:** Checks for declaration of `const` items which is interior + /// ### What it does + /// Checks for declaration of `const` items which is interior /// mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.). /// - /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e., + /// ### Why is this bad? + /// Consts are copied everywhere they are referenced, i.e., /// every time you refer to the const a fresh instance of the `Cell` or `Mutex` /// or `AtomicXxxx` will be created, which defeats the whole purpose of using /// these types in the first place. @@ -35,7 +37,8 @@ declare_clippy_lint! { /// The `const` should better be replaced by a `static` item if a global /// variable is wanted, or replaced by a `const fn` if a constructor is wanted. /// - /// **Known problems:** A "non-constant" const item is a legacy way to supply an + /// ### Known problems + /// A "non-constant" const item is a legacy way to supply an /// initialized value to downstream `static` items (e.g., the /// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit, /// and this lint should be suppressed. @@ -52,7 +55,7 @@ declare_clippy_lint! { /// the interior mutable field is used or not. See issues /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and /// - /// **Example:** + /// ### Example /// ```rust /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// @@ -74,17 +77,20 @@ declare_clippy_lint! { // FIXME: this is a correctness problem but there's no suitable // warn-by-default category. declare_clippy_lint! { - /// **What it does:** Checks if `const` items which is interior mutable (e.g., + /// ### What it does + /// Checks if `const` items which is interior mutable (e.g., /// contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly. /// - /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e., + /// ### Why is this bad? + /// Consts are copied everywhere they are referenced, i.e., /// every time you refer to the const a fresh instance of the `Cell` or `Mutex` /// or `AtomicXxxx` will be created, which defeats the whole purpose of using /// these types in the first place. /// /// The `const` value should be stored inside a `static` item. /// - /// **Known problems:** When an enum has variants with interior mutability, use of its non + /// ### Known problems + /// When an enum has variants with interior mutability, use of its non /// interior mutable variants can generate false positives. See issue /// [#3962](https://github.com/rust-lang/rust-clippy/issues/3962) /// @@ -93,7 +99,7 @@ declare_clippy_lint! { /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and /// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825) /// - /// **Example:** + /// ### Example /// ```rust /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 1a23e6afe28..06c431babc2 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -13,14 +13,14 @@ use rustc_span::symbol::{Ident, Symbol}; use std::cmp::Ordering; declare_clippy_lint! { - /// **What it does:** Checks for names that are very similar and thus confusing. + /// ### What it does + /// Checks for names that are very similar and thus confusing. /// - /// **Why is this bad?** It's hard to distinguish between names that differ only + /// ### Why is this bad? + /// It's hard to distinguish between names that differ only /// by a single character. /// - /// **Known problems:** None? - /// - /// **Example:** + /// ### Example /// ```ignore /// let checked_exp = something; /// let checked_expr = something_else; @@ -31,15 +31,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for too many variables whose name consists of a + /// ### What it does + /// Checks for too many variables whose name consists of a /// single character. /// - /// **Why is this bad?** It's hard to memorize what a variable means without a + /// ### Why is this bad? + /// It's hard to memorize what a variable means without a /// descriptive name. /// - /// **Known problems:** None? - /// - /// **Example:** + /// ### Example /// ```ignore /// let (a, b, c, d, e, f, g) = (...); /// ``` @@ -49,15 +49,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks if you have variables whose name consists of just + /// ### What it does + /// Checks if you have variables whose name consists of just /// underscores and digits. /// - /// **Why is this bad?** It's hard to memorize what a variable means without a + /// ### Why is this bad? + /// It's hard to memorize what a variable means without a /// descriptive name. /// - /// **Known problems:** None? - /// - /// **Example:** + /// ### Example /// ```rust /// let _1 = 1; /// let ___1 = 1; @@ -218,7 +218,6 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { if allowed_to_be_similar(&interned_name, existing_name.exemptions) { continue; } - let mut split_at = None; match existing_name.len.cmp(&count) { Ordering::Greater => { if existing_name.len - count != 1 @@ -269,7 +268,6 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { // or too many chars differ (foo_x, boo_y) or (foox, booy) continue; } - split_at = interned_name.char_indices().rev().next().map(|(i, _)| i); } } else { let second_i = interned_chars.next().expect("we know we have at least two chars"); @@ -282,7 +280,6 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { // or too many chars differ (x_foo, y_boo) or (xfoo, yboo) continue; } - split_at = interned_name.chars().next().map(char::len_utf8); } }, } @@ -293,17 +290,6 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { "binding's name is too similar to existing binding", |diag| { diag.span_note(existing_name.span, "existing binding defined here"); - if let Some(split) = split_at { - diag.span_help( - ident.span, - &format!( - "separate the discriminating character by an \ - underscore like: `{}_{}`", - &interned_name[..split], - &interned_name[split..] - ), - ); - } }, ); return; diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs index a83daea97bf..3b74f69d375 100644 --- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs +++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs @@ -9,15 +9,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for non-octal values used to set Unix file permissions. + /// ### What it does + /// Checks for non-octal values used to set Unix file permissions. /// - /// **Why is this bad?** They will be converted into octal, creating potentially + /// ### Why is this bad? + /// They will be converted into octal, creating potentially /// unintended file permissions. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// use std::fs::OpenOptions; /// use std::os::unix::fs::OpenOptionsExt; diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs index 043e7fa30d6..dbe9cbe0ded 100644 --- a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs +++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs @@ -13,16 +13,14 @@ use rustc_span::Span; use serde::{de, Deserialize}; declare_clippy_lint! { - /// **What it does:** Checks that common macros are used with consistent bracing. + /// ### What it does + /// Checks that common macros are used with consistent bracing. /// - /// **Why is this bad?** This is mostly a consistency lint although using () or [] + /// ### Why is this bad? + /// This is mostly a consistency lint although using () or [] /// doesn't give you a semicolon in item position, which can be unexpected. /// - /// **Known problems:** - /// None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// vec!{1, 2, 3}; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/open_options.rs b/src/tools/clippy/clippy_lints/src/open_options.rs index fded48038e3..4064d94da2a 100644 --- a/src/tools/clippy/clippy_lints/src/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/open_options.rs @@ -8,15 +8,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::{Span, Spanned}; declare_clippy_lint! { - /// **What it does:** Checks for duplicate open options as well as combinations + /// ### What it does + /// Checks for duplicate open options as well as combinations /// that make no sense. /// - /// **Why is this bad?** In the best case, the code will be harder to read than + /// ### Why is this bad? + /// In the best case, the code will be harder to read than /// necessary. I don't know the worst case. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// use std::fs::OpenOptions; /// diff --git a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs index b6f518661bd..d7306628030 100644 --- a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs @@ -7,17 +7,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for usage of `option_env!(...).unwrap()` and + /// ### What it does + /// Checks for usage of `option_env!(...).unwrap()` and /// suggests usage of the `env!` macro. /// - /// **Why is this bad?** Unwrapping the result of `option_env!` will panic + /// ### Why is this bad? + /// Unwrapping the result of `option_env!` will panic /// at run-time if the environment variable doesn't exist, whereas `env!` /// catches it at compile-time. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,no_run /// let _ = option_env!("HOME").unwrap(); /// ``` diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs index b2be35bdddb..7aef3a5f34c 100644 --- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs @@ -12,24 +12,23 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Lints usage of `if let Some(v) = ... { y } else { x }` which is more /// idiomatically done with `Option::map_or` (if the else bit is a pure /// expression) or `Option::map_or_else` (if the else bit is an impure /// expression). /// - /// **Why is this bad?** + /// ### Why is this bad? /// Using the dedicated functions of the Option type is clearer and /// more concise than an `if let` expression. /// - /// **Known problems:** + /// ### Known problems /// This lint uses a deliberately conservative metric for checking /// if the inside of either body contains breaks or continues which will /// cause it to not suggest a fix if either block contains a loop with /// continues or breaks contained within the loop. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # let optional: Option = Some(0); /// # fn do_complicated_function() -> u32 { 5 }; diff --git a/src/tools/clippy/clippy_lints/src/overflow_check_conditional.rs b/src/tools/clippy/clippy_lints/src/overflow_check_conditional.rs index e222782c2cc..34755afdb72 100644 --- a/src/tools/clippy/clippy_lints/src/overflow_check_conditional.rs +++ b/src/tools/clippy/clippy_lints/src/overflow_check_conditional.rs @@ -6,14 +6,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Detects classic underflow/overflow checks. + /// ### What it does + /// Detects classic underflow/overflow checks. /// - /// **Why is this bad?** Most classic C underflow/overflow checks will fail in + /// ### Why is this bad? + /// Most classic C underflow/overflow checks will fail in /// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let a = 1; /// # let b = 2; diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs index cef74d87e7c..e2b6ba8e2d2 100644 --- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs +++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs @@ -8,14 +8,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span}; declare_clippy_lint! { - /// **What it does:** Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result. + /// ### What it does + /// Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result. /// - /// **Why is this bad?** For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided. + /// ### Why is this bad? + /// For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided. /// - /// **Known problems:** Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked. - /// - /// **Example:** + /// ### Known problems + /// Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked. /// + /// ### Example /// ```rust /// fn result_with_panic() -> Result /// { diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs index dc28874c16e..d8d9081d6f1 100644 --- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs +++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs @@ -7,13 +7,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for usage of `panic!`. + /// ### What it does + /// Checks for usage of `panic!`. /// - /// **Why is this bad?** `panic!` will stop the execution of the executable + /// ### Why is this bad? + /// `panic!` will stop the execution of the executable /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// panic!("even with a good reason"); /// ``` @@ -23,13 +23,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `unimplemented!`. + /// ### What it does + /// Checks for usage of `unimplemented!`. /// - /// **Why is this bad?** This macro should not be present in production code + /// ### Why is this bad? + /// This macro should not be present in production code /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// unimplemented!(); /// ``` @@ -39,13 +39,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `todo!`. + /// ### What it does + /// Checks for usage of `todo!`. /// - /// **Why is this bad?** This macro should not be present in production code + /// ### Why is this bad? + /// This macro should not be present in production code /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// todo!(); /// ``` @@ -55,13 +55,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `unreachable!`. + /// ### What it does + /// Checks for usage of `unreachable!`. /// - /// **Why is this bad?** This macro can cause code to panic + /// ### Why is this bad? + /// This macro can cause code to panic /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```no_run /// unreachable!(); /// ``` diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs index 1251ddd9a02..4ec493e5f45 100644 --- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs +++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs @@ -7,16 +7,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for manual re-implementations of `PartialEq::ne`. + /// ### What it does + /// Checks for manual re-implementations of `PartialEq::ne`. /// - /// **Why is this bad?** `PartialEq::ne` is required to always return the + /// ### Why is this bad? + /// `PartialEq::ne` is required to always return the /// negated result of `PartialEq::eq`, which is exactly what the default /// implementation does. Therefore, there should never be any need to /// re-implement it. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// struct Foo; /// diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index f6a70478559..f738ac25417 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -20,15 +20,18 @@ use rustc_target::spec::abi::Abi; use rustc_target::spec::Target; declare_clippy_lint! { - /// **What it does:** Checks for functions taking arguments by reference, where + /// ### What it does + /// Checks for functions taking arguments by reference, where /// the argument type is `Copy` and small enough to be more efficient to always /// pass by value. /// - /// **Why is this bad?** In many calling conventions instances of structs will + /// ### Why is this bad? + /// In many calling conventions instances of structs will /// be passed through registers if they fit into two or less general purpose /// registers. /// - /// **Known problems:** This lint is target register size dependent, it is + /// ### Known problems + /// This lint is target register size dependent, it is /// limited to 32-bit to try and reduce portability problems between 32 and /// 64-bit, but if you are compiling for 8 or 16-bit targets then the limit /// will be different. @@ -50,7 +53,7 @@ declare_clippy_lint! { /// that explains a real case in which this false positive /// led to an **undefined behaviour** introduced with unsafe code. /// - /// **Example:** + /// ### Example /// /// ```rust /// // Bad @@ -67,18 +70,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for functions taking arguments by value, where + /// ### What it does + /// Checks for functions taking arguments by value, where /// the argument type is `Copy` and large enough to be worth considering /// passing by reference. Does not trigger if the function is being exported, /// because that might induce API breakage, if the parameter is declared as mutable, /// or if the argument is a `self`. /// - /// **Why is this bad?** Arguments passed by value might result in an unnecessary + /// ### Why is this bad? + /// Arguments passed by value might result in an unnecessary /// shallow copy, taking up more space in the stack and requiring a call to /// `memcpy`, which can be expensive. /// - /// **Example:** - /// + /// ### Example /// ```rust /// #[derive(Clone, Copy)] /// struct TooLarge([u8; 2048]); diff --git a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs index 00245926381..3df7a72d295 100644 --- a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs @@ -10,15 +10,15 @@ use rustc_span::symbol::sym; use std::path::{Component, Path}; declare_clippy_lint! { - /// **What it does:*** Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push) + /// ### What it does + ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push) /// calls on `PathBuf` that can cause overwrites. /// - /// **Why is this bad?** Calling `push` with a root path at the start can overwrite the + /// ### Why is this bad? + /// Calling `push` with a root path at the start can overwrite the /// previous defined path. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// use std::path::PathBuf; /// diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs index ea4065d371b..4534f6e2516 100644 --- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs @@ -13,7 +13,8 @@ use rustc_span::source_map::Span; use std::iter; declare_clippy_lint! { - /// **What it does:** Checks for patterns that aren't exact representations of the types + /// ### What it does + /// Checks for patterns that aren't exact representations of the types /// they are applied to. /// /// To satisfy this lint, you will have to adjust either the expression that is matched @@ -32,14 +33,12 @@ declare_clippy_lint! { /// this lint can still be used to highlight areas of interest and ensure a good understanding /// of ownership semantics. /// - /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable + /// ### Why is this bad? + /// It isn't bad in general. But in some contexts it can be desirable /// because it increases ownership hints in the code, and will guard against some changes /// in ownership. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// This example shows the basic adjustments necessary to satisfy the lint. Note how /// the matched expression is explicitly dereferenced with `*` and the `inner` variable /// is bound to a shared borrow via `ref inner`. diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs index 9cf00c953b9..1a8da00d9d6 100644 --- a/src/tools/clippy/clippy_lints/src/precedence.rs +++ b/src/tools/clippy/clippy_lints/src/precedence.rs @@ -25,7 +25,8 @@ const ALLOWED_ODD_FUNCTIONS: [&str; 14] = [ ]; declare_clippy_lint! { - /// **What it does:** Checks for operations where precedence may be unclear + /// ### What it does + /// Checks for operations where precedence may be unclear /// and suggests to add parentheses. Currently it catches the following: /// * mixed usage of arithmetic and bit shifting/combining operators without /// parentheses @@ -33,13 +34,12 @@ declare_clippy_lint! { /// numeric literal) /// followed by a method call /// - /// **Why is this bad?** Not everyone knows the precedence of those operators by + /// ### Why is this bad? + /// Not everyone knows the precedence of those operators by /// heart, so expressions like these may trip others trying to reason about the /// code. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 /// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1 pub PRECEDENCE, diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index dba3b1805cd..c0d1f1eb6e6 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the use clippy_utils::ptr::get_spans; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{is_type_diagnostic_item, match_type, walk_ptrs_hir_ty}; -use clippy_utils::{expr_path_res, is_lint_allowed, match_any_def_paths, paths}; +use clippy_utils::{expr_path_res, is_lint_allowed, match_any_diagnostic_items, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{ @@ -20,16 +20,19 @@ use rustc_span::{sym, MultiSpan}; use std::borrow::Cow; declare_clippy_lint! { - /// **What it does:** This lint checks for function arguments of type `&String` + /// ### What it does + /// This lint checks for function arguments of type `&String` /// or `&Vec` unless the references are mutable. It will also suggest you /// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()` /// calls. /// - /// **Why is this bad?** Requiring the argument to be of the specific size + /// ### Why is this bad? + /// Requiring the argument to be of the specific size /// makes the function less useful for no benefit; slices in the form of `&[T]` /// or `&str` usually suffice and can be obtained from other types, too. /// - /// **Known problems:** The lint does not follow data. So if you have an + /// ### Known problems + /// The lint does not follow data. So if you have an /// argument `x` and write `let y = x; y.clone()` the lint will not suggest /// changing that `.clone()` to `.to_owned()`. /// @@ -59,7 +62,7 @@ declare_clippy_lint! { /// other crates referencing it, of which you may not be aware. Carefully /// deprecate the function before applying the lint suggestions in this case. /// - /// **Example:** + /// ### Example /// ```ignore /// // Bad /// fn foo(&Vec) { .. } @@ -73,15 +76,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint checks for equality comparisons with `ptr::null` + /// ### What it does + /// This lint checks for equality comparisons with `ptr::null` /// - /// **Why is this bad?** It's easier and more readable to use the inherent + /// ### Why is this bad? + /// It's easier and more readable to use the inherent /// `.is_null()` /// method instead /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// // Bad /// if x == ptr::null { @@ -99,19 +102,22 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint checks for functions that take immutable + /// ### What it does + /// This lint checks for functions that take immutable /// references and return mutable ones. /// - /// **Why is this bad?** This is trivially unsound, as one can create two + /// ### Why is this bad? + /// This is trivially unsound, as one can create two /// mutable references from the same (immutable!) source. /// This [error](https://github.com/rust-lang/rust/issues/39465) /// actually lead to an interim Rust release 1.15.1. /// - /// **Known problems:** To be on the conservative side, if there's at least one + /// ### Known problems + /// To be on the conservative side, if there's at least one /// mutable reference with the output lifetime, this lint will not trigger. /// In practice, this case is unlikely anyway. /// - /// **Example:** + /// ### Example /// ```ignore /// fn foo(&Foo) -> &mut Bar { .. } /// ``` @@ -121,13 +127,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint checks for invalid usages of `ptr::null`. + /// ### What it does + /// This lint checks for invalid usages of `ptr::null`. /// - /// **Why is this bad?** This causes undefined behavior. + /// ### Why is this bad? + /// This causes undefined behavior. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// // Bad. Undefined behavior /// unsafe { std::slice::from_raw_parts(ptr::null(), 0); } @@ -419,7 +425,7 @@ fn get_rptr_lm<'tcx>(ty: &'tcx Ty<'tcx>) -> Option<(&'tcx Lifetime, Mutability, fn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ExprKind::Call(pathexp, []) = expr.kind { expr_path_res(cx, pathexp).opt_def_id().map_or(false, |id| { - match_any_def_paths(cx, id, &[&paths::PTR_NULL, &paths::PTR_NULL_MUT]).is_some() + match_any_diagnostic_items(cx, id, &[sym::ptr_null, sym::ptr_null_mut]).is_some() }) } else { false diff --git a/src/tools/clippy/clippy_lints/src/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/ptr_eq.rs index 77cfa3f6b17..d6d7049fb61 100644 --- a/src/tools/clippy/clippy_lints/src/ptr_eq.rs +++ b/src/tools/clippy/clippy_lints/src/ptr_eq.rs @@ -8,16 +8,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Use `std::ptr::eq` when applicable + /// ### What it does + /// Use `std::ptr::eq` when applicable /// - /// **Why is this bad?** `ptr::eq` can be used to compare `&T` references + /// ### Why is this bad? + /// `ptr::eq` can be used to compare `&T` references /// (which coerce to `*const T` implicitly) by their address rather than /// comparing the values they point to. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let a = &[1, 2, 3]; /// let b = &[1, 2, 3]; diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs index afb198f4955..f1975056ddc 100644 --- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs +++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs @@ -8,15 +8,15 @@ use rustc_span::sym; use std::fmt; declare_clippy_lint! { - /// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an + /// ### What it does + /// Checks for usage of the `offset` pointer method with a `usize` casted to an /// `isize`. /// - /// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric + /// ### Why is this bad? + /// If we’re always increasing the pointer address, we can avoid the numeric /// cast by using the `add` method instead. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// let vec = vec![b'a', b'b', b'c']; /// let ptr = vec.as_ptr(); diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index d66bac52243..0e682c692c7 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -13,13 +13,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for expressions that could be replaced by the question mark operator. + /// ### What it does + /// Checks for expressions that could be replaced by the question mark operator. /// - /// **Why is this bad?** Question mark usage is more idiomatic. + /// ### Why is this bad? + /// Question mark usage is more idiomatic. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```ignore /// if option.is_none() { /// return None; diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index b41c478c266..0179bd48ee3 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -18,14 +18,14 @@ use rustc_span::symbol::Ident; use std::cmp::Ordering; declare_clippy_lint! { - /// **What it does:** Checks for zipping a collection with the range of + /// ### What it does + /// Checks for zipping a collection with the range of /// `0.._.len()`. /// - /// **Why is this bad?** The code is better expressed with `.enumerate()`. + /// ### Why is this bad? + /// The code is better expressed with `.enumerate()`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let x = vec![1]; /// x.iter().zip(0..x.len()); @@ -41,13 +41,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for exclusive ranges where 1 is added to the + /// ### What it does + /// Checks for exclusive ranges where 1 is added to the /// upper bound, e.g., `x..(y+1)`. /// - /// **Why is this bad?** The code is more readable with an inclusive range + /// ### Why is this bad? + /// The code is more readable with an inclusive range /// like `x..=y`. /// - /// **Known problems:** Will add unnecessary pair of parentheses when the + /// ### Known problems + /// Will add unnecessary pair of parentheses when the /// expression is not wrapped in a pair but starts with a opening parenthesis /// and ends with a closing one. /// I.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`. @@ -61,7 +64,7 @@ declare_clippy_lint! { /// `RangeBounds` trait /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). /// - /// **Example:** + /// ### Example /// ```rust,ignore /// for x..(y+1) { .. } /// ``` @@ -75,18 +78,21 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for inclusive ranges where 1 is subtracted from + /// ### What it does + /// Checks for inclusive ranges where 1 is subtracted from /// the upper bound, e.g., `x..=(y-1)`. /// - /// **Why is this bad?** The code is more readable with an exclusive range + /// ### Why is this bad? + /// The code is more readable with an exclusive range /// like `x..y`. /// - /// **Known problems:** This will cause a warning that cannot be fixed if + /// ### Known problems + /// This will cause a warning that cannot be fixed if /// the consumer of the range only accepts a specific range type, instead of /// the generic `RangeBounds` trait /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). /// - /// **Example:** + /// ### Example /// ```rust,ignore /// for x..=(y-1) { .. } /// ``` @@ -100,16 +106,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for range expressions `x..y` where both `x` and `y` + /// ### What it does + /// Checks for range expressions `x..y` where both `x` and `y` /// are constant and `x` is greater or equal to `y`. /// - /// **Why is this bad?** Empty ranges yield no values so iterating them is a no-op. + /// ### Why is this bad? + /// Empty ranges yield no values so iterating them is a no-op. /// Moreover, trying to use a reversed range to index a slice will panic at run-time. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,no_run /// fn main() { /// (10..=0).for_each(|x| println!("{}", x)); @@ -133,16 +138,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for expressions like `x >= 3 && x < 8` that could + /// ### What it does + /// Checks for expressions like `x >= 3 && x < 8` that could /// be more readably expressed as `(3..8).contains(x)`. /// - /// **Why is this bad?** `contains` expresses the intent better and has less + /// ### Why is this bad? + /// `contains` expresses the intent better and has less /// failure modes (such as fencepost errors or using `||` instead of `&&`). /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // given /// let x = 6; diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 7ba7ff3a353..eeeac35a6d5 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -32,17 +32,18 @@ macro_rules! unwrap_or_continue { } declare_clippy_lint! { - /// **What it does:** Checks for a redundant `clone()` (and its relatives) which clones an owned + /// ### What it does + /// Checks for a redundant `clone()` (and its relatives) which clones an owned /// value that is going to be dropped without further use. /// - /// **Why is this bad?** It is not always possible for the compiler to eliminate useless + /// ### Why is this bad? + /// It is not always possible for the compiler to eliminate useless /// allocations and deallocations generated by redundant `clone()`s. /// - /// **Known problems:** - /// + /// ### Known problems /// False-negatives: analysis performed by this lint is conservative and limited. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::path::Path; /// # #[derive(Clone)] diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs index 8f56a21ac5b..a79b2fe76e2 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs @@ -14,15 +14,15 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Detects closures called in the same expression where they + /// ### What it does + /// Detects closures called in the same expression where they /// are defined. /// - /// **Why is this bad?** It is unnecessarily adding to the expression's + /// ### Why is this bad? + /// It is unnecessarily adding to the expression's /// complexity. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// let a = (|| 42)() diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs index 061526c6f09..68b256d2944 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_else.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs @@ -6,14 +6,16 @@ use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for `else` blocks that can be removed without changing semantics. + /// ### What it does + /// Checks for `else` blocks that can be removed without changing semantics. /// - /// **Why is this bad?** The `else` block adds unnecessary indentation and verbosity. + /// ### Why is this bad? + /// The `else` block adds unnecessary indentation and verbosity. /// - /// **Known problems:** Some may prefer to keep the `else` block for clarity. - /// - /// **Example:** + /// ### Known problems + /// Some may prefer to keep the `else` block for clarity. /// + /// ### Example /// ```rust /// fn my_func(count: u32) { /// if count == 0 { diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs index d5ee8d3468d..47df4917510 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs @@ -8,15 +8,15 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; declare_clippy_lint! { - /// **What it does:** Checks for fields in struct literals where shorthands + /// ### What it does + /// Checks for fields in struct literals where shorthands /// could be used. /// - /// **Why is this bad?** If the field and variable names are the same, + /// ### Why is this bad? + /// If the field and variable names are the same, /// the field name is redundant. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let bar: u8 = 123; /// diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs index 05f9e01acb4..59a55b9dffa 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs @@ -5,16 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; declare_clippy_lint! { - /// **What it does:** Checks for items declared `pub(crate)` that are not crate visible because they + /// ### What it does + /// Checks for items declared `pub(crate)` that are not crate visible because they /// are inside a private module. /// - /// **Why is this bad?** Writing `pub(crate)` is misleading when it's redundant due to the parent + /// ### Why is this bad? + /// Writing `pub(crate)` is misleading when it's redundant due to the parent /// module's visibility. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// mod internal { /// pub(crate) fn internal_fn() { } diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 9c6cd7b4fa6..290348c4509 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -10,17 +10,19 @@ use rustc_middle::ty::TyS; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for redundant slicing expressions which use the full range, and + /// ### What it does + /// Checks for redundant slicing expressions which use the full range, and /// do not change the type. /// - /// **Why is this bad?** It unnecessarily adds complexity to the expression. + /// ### Why is this bad? + /// It unnecessarily adds complexity to the expression. /// - /// **Known problems:** If the type being sliced has an implementation of `Index` + /// ### Known problems + /// If the type being sliced has an implementation of `Index` /// that actually changes anything then it can't be removed. However, this would be surprising /// to people reading the code and should have a note with it. /// - /// **Example:** - /// + /// ### Example /// ```ignore /// fn get_slice(x: &[u32]) -> &[u32] { /// &x[..] diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index 48107d9c037..d5a1a61da6b 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -8,14 +8,14 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; declare_clippy_lint! { - /// **What it does:** Checks for constants and statics with an explicit `'static` lifetime. + /// ### What it does + /// Checks for constants and statics with an explicit `'static` lifetime. /// - /// **Why is this bad?** Adding `'static` to every reference can create very + /// ### Why is this bad? + /// Adding `'static` to every reference can create very /// complicated types. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] = /// &[...] diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs index 0cf4e0ce7fe..65ab6cac442 100644 --- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs +++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs @@ -9,16 +9,18 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks for usage of `&Option<&T>`. + /// ### What it does + /// Checks for usage of `&Option<&T>`. /// - /// **Why is this bad?** Since `&` is Copy, it's useless to have a + /// ### Why is this bad? + /// Since `&` is Copy, it's useless to have a /// reference on `Option<&T>`. /// - /// **Known problems:** It may be irrelevant to use this lint on + /// ### Known problems + /// It may be irrelevant to use this lint on /// public API code as it will make a breaking change to apply it. /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// let x: &Option<&u32> = &Some(&0u32); /// ``` diff --git a/src/tools/clippy/clippy_lints/src/reference.rs b/src/tools/clippy/clippy_lints/src/reference.rs index d6336389b0a..e0930d69ab9 100644 --- a/src/tools/clippy/clippy_lints/src/reference.rs +++ b/src/tools/clippy/clippy_lints/src/reference.rs @@ -10,15 +10,18 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::BytePos; declare_clippy_lint! { - /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. + /// ### What it does + /// Checks for usage of `*&` and `*&mut` in expressions. /// - /// **Why is this bad?** Immediately dereferencing a reference is no-op and + /// ### Why is this bad? + /// Immediately dereferencing a reference is no-op and /// makes the code less clear. /// - /// **Known problems:** Multiple dereference/addrof pairs are not handled so + /// ### Known problems + /// Multiple dereference/addrof pairs are not handled so /// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// let a = f(*&mut b); @@ -101,13 +104,15 @@ impl EarlyLintPass for DerefAddrOf { } declare_clippy_lint! { - /// **What it does:** Checks for references in expressions that use + /// ### What it does + /// Checks for references in expressions that use /// auto dereference. /// - /// **Why is this bad?** The reference is a no-op and is automatically + /// ### Why is this bad? + /// The reference is a no-op and is automatically /// dereferenced by the compiler and makes the code less clear. /// - /// **Example:** + /// ### Example /// ```rust /// struct Point(u32, u32); /// let point = Point(30, 20); diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs index 75151167454..eab09733730 100644 --- a/src/tools/clippy/clippy_lints/src/regex.rs +++ b/src/tools/clippy/clippy_lints/src/regex.rs @@ -11,15 +11,15 @@ use rustc_span::source_map::{BytePos, Span}; use std::convert::TryFrom; declare_clippy_lint! { - /// **What it does:** Checks [regex](https://crates.io/crates/regex) creation + /// ### What it does + /// Checks [regex](https://crates.io/crates/regex) creation /// (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct /// regex syntax. /// - /// **Why is this bad?** This will lead to a runtime panic. + /// ### Why is this bad? + /// This will lead to a runtime panic. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// Regex::new("|") /// ``` @@ -29,18 +29,21 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for trivial [regex](https://crates.io/crates/regex) + /// ### What it does + /// Checks for trivial [regex](https://crates.io/crates/regex) /// creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`). /// - /// **Why is this bad?** Matching the regex can likely be replaced by `==` or + /// ### Why is this bad? + /// Matching the regex can likely be replaced by `==` or /// `str::starts_with`, `str::ends_with` or `std::contains` or other `str` /// methods. /// - /// **Known problems:** If the same regex is going to be applied to multiple + /// ### Known problems + /// If the same regex is going to be applied to multiple /// inputs, the precomputations done by `Regex` construction can give /// significantly better performance than any of the `str`-based methods. /// - /// **Example:** + /// ### Example /// ```ignore /// Regex::new("^foobar") /// ``` diff --git a/src/tools/clippy/clippy_lints/src/repeat_once.rs b/src/tools/clippy/clippy_lints/src/repeat_once.rs index b479c40bca6..54b9c8b3275 100644 --- a/src/tools/clippy/clippy_lints/src/repeat_once.rs +++ b/src/tools/clippy/clippy_lints/src/repeat_once.rs @@ -11,17 +11,20 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for usage of `.repeat(1)` and suggest the following method for each types. + /// ### What it does + /// Checks for usage of `.repeat(1)` and suggest the following method for each types. /// - `.to_string()` for `str` /// - `.clone()` for `String` /// - `.to_vec()` for `slice` /// - /// **Why is this bad?** For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning the string is the intention behind this, `clone()` should be used. + /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if + /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306)) /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning + /// the string is the intention behind this, `clone()` should be used. /// + /// ### Example /// ```rust /// fn main() { /// let x = String::from("hello world").repeat(1); diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 251d527c265..db4b1002ce1 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -15,15 +15,15 @@ use rustc_span::source_map::Span; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for `let`-bindings, which are subsequently + /// ### What it does + /// Checks for `let`-bindings, which are subsequently /// returned. /// - /// **Why is this bad?** It is just extraneous code. Remove it to make your code + /// ### Why is this bad? + /// It is just extraneous code. Remove it to make your code /// more rusty. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn foo() -> String { /// let x = String::new(); @@ -42,14 +42,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for return statements at the end of a block. + /// ### What it does + /// Checks for return statements at the end of a block. /// - /// **Why is this bad?** Removing the `return` and semicolon will make the code + /// ### Why is this bad? + /// Removing the `return` and semicolon will make the code /// more rusty. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn foo(x: usize) -> usize { /// return x; diff --git a/src/tools/clippy/clippy_lints/src/self_assignment.rs b/src/tools/clippy/clippy_lints/src/self_assignment.rs index e7925c4fbde..fbd65fef7d1 100644 --- a/src/tools/clippy/clippy_lints/src/self_assignment.rs +++ b/src/tools/clippy/clippy_lints/src/self_assignment.rs @@ -6,16 +6,18 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for explicit self-assignments. + /// ### What it does + /// Checks for explicit self-assignments. /// - /// **Why is this bad?** Self-assignments are redundant and unlikely to be + /// ### Why is this bad? + /// Self-assignments are redundant and unlikely to be /// intentional. /// - /// **Known problems:** If expression contains any deref coercions or + /// ### Known problems + /// If expression contains any deref coercions or /// indexing operations they are assumed not to have any side effects. /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct Event { /// id: usize, diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructor.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs similarity index 85% rename from src/tools/clippy/clippy_lints/src/self_named_constructor.rs rename to src/tools/clippy/clippy_lints/src/self_named_constructors.rs index da991e1d90c..4472edecbed 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -6,14 +6,13 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Warns when constructors have the same name as their types. + /// ### What it does + /// Warns when constructors have the same name as their types. /// - /// **Why is this bad?** Repeating the name of the type is redundant. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Repeating the name of the type is redundant. /// + /// ### Example /// ```rust,ignore /// struct Foo {} /// @@ -33,14 +32,14 @@ declare_clippy_lint! { /// } /// } /// ``` - pub SELF_NAMED_CONSTRUCTOR, + pub SELF_NAMED_CONSTRUCTORS, style, "method should not have the same name as the type it is implemented for" } -declare_lint_pass!(SelfNamedConstructor => [SELF_NAMED_CONSTRUCTOR]); +declare_lint_pass!(SelfNamedConstructors => [SELF_NAMED_CONSTRUCTORS]); -impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructor { +impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { match impl_item.kind { ImplItemKind::Fn(ref sig, _) => { @@ -81,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructor { then { span_lint( cx, - SELF_NAMED_CONSTRUCTOR, + SELF_NAMED_CONSTRUCTORS, impl_item.span, &format!("constructor `{}` has the same name as the type", impl_item.ident.name), ); diff --git a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs index da3e30af35c..6966230156c 100644 --- a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs @@ -9,16 +9,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Looks for blocks of expressions and fires if the last expression returns + /// ### What it does + /// Looks for blocks of expressions and fires if the last expression returns /// `()` but is not followed by a semicolon. /// - /// **Why is this bad?** The semicolon might be optional but when extending the block with new + /// ### Why is this bad? + /// The semicolon might be optional but when extending the block with new /// code, it doesn't require a change in previous last line. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// fn main() { /// println!("Hello world") diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs index 169f7d26285..2cd0f85999c 100644 --- a/src/tools/clippy/clippy_lints/src/serde_api.rs +++ b/src/tools/clippy/clippy_lints/src/serde_api.rs @@ -5,14 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for mis-uses of the serde API. + /// ### What it does + /// Checks for mis-uses of the serde API. /// - /// **Why is this bad?** Serde is very finnicky about how its API should be + /// ### Why is this bad? + /// Serde is very finnicky about how its API should be /// used, but the type system can't be used to enforce it (yet?). /// - /// **Known problems:** None. - /// - /// **Example:** Implementing `Visitor::visit_string` but not + /// ### Example + /// Implementing `Visitor::visit_string` but not /// `Visitor::visit_str`. pub SERDE_API_MISUSE, correctness, diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index ac3f7ebd14b..b28a37cabd4 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -14,17 +14,20 @@ use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; declare_clippy_lint! { - /// **What it does:** Checks for bindings that shadow other bindings already in + /// ### What it does + /// Checks for bindings that shadow other bindings already in /// scope, while just changing reference level or mutability. /// - /// **Why is this bad?** Not much, in fact it's a very common pattern in Rust + /// ### Why is this bad? + /// Not much, in fact it's a very common pattern in Rust /// code. Still, some may opt to avoid it in their code base, they can set this /// lint to `Warn`. /// - /// **Known problems:** This lint, as the other shadowing related lints, + /// ### Known problems + /// This lint, as the other shadowing related lints, /// currently only catches very simple patterns. /// - /// **Example:** + /// ### Example /// ```rust /// # let x = 1; /// // Bad @@ -39,18 +42,21 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for bindings that shadow other bindings already in + /// ### What it does + /// Checks for bindings that shadow other bindings already in /// scope, while reusing the original value. /// - /// **Why is this bad?** Not too much, in fact it's a common pattern in Rust + /// ### Why is this bad? + /// Not too much, in fact it's a common pattern in Rust /// code. Still, some argue that name shadowing like this hurts readability, /// because a value may be bound to different things depending on position in /// the code. /// - /// **Known problems:** This lint, as the other shadowing related lints, + /// ### Known problems + /// This lint, as the other shadowing related lints, /// currently only catches very simple patterns. /// - /// **Example:** + /// ### Example /// ```rust /// let x = 2; /// let x = x + 1; @@ -66,21 +72,24 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for bindings that shadow other bindings already in + /// ### What it does + /// Checks for bindings that shadow other bindings already in /// scope, either without a initialization or with one that does not even use /// the original value. /// - /// **Why is this bad?** Name shadowing can hurt readability, especially in + /// ### Why is this bad? + /// Name shadowing can hurt readability, especially in /// large code bases, because it is easy to lose track of the active binding at /// any place in the code. This can be alleviated by either giving more specific /// names to bindings or introducing more scopes to contain the bindings. /// - /// **Known problems:** This lint, as the other shadowing related lints, + /// ### Known problems + /// This lint, as the other shadowing related lints, /// currently only catches very simple patterns. Note that /// `allow`/`warn`/`deny`/`forbid` attributes only work on the function level /// for this lint. /// - /// **Example:** + /// ### Example /// ```rust /// # let y = 1; /// # let z = 2; diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs index 1eaad438237..f6487b8c46b 100644 --- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs +++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs @@ -7,15 +7,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{edition::Edition, symbol::kw, Span, Symbol}; declare_clippy_lint! { - /// **What it does:** Checking for imports with single component use path. + /// ### What it does + /// Checking for imports with single component use path. /// - /// **Why is this bad?** Import with single component use path such as `use cratename;` + /// ### Why is this bad? + /// Import with single component use path such as `use cratename;` /// is not necessary, and thus should be removed. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// use regex; /// diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs index cd2bdec1707..3e4e4a8d0c0 100644 --- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs +++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs @@ -11,16 +11,16 @@ use rustc_middle::ty::{self, Ty, TyS, TypeAndMut}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Detects expressions where + /// ### What it does + /// Detects expressions where /// `size_of::` or `size_of_val::` is used as a /// count of elements of type `T` /// - /// **Why is this bad?** These functions expect a count + /// ### Why is this bad? + /// These functions expect a count /// of `T` and not a number of bytes /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,no_run /// # use std::ptr::copy_nonoverlapping; /// # use std::mem::size_of; @@ -67,7 +67,7 @@ fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) - const FUNCTIONS: [&[&str]; 8] = [ &paths::PTR_COPY_NONOVERLAPPING, &paths::PTR_COPY, - &paths::WRITE_BYTES, + &paths::PTR_WRITE_BYTES, &paths::PTR_SWAP_NONOVERLAPPING, &paths::PTR_SLICE_FROM_RAW_PARTS, &paths::PTR_SLICE_FROM_RAW_PARTS_MUT, diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs index e5c58d70b60..3d039e13065 100644 --- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs +++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs @@ -13,14 +13,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks slow zero-filled vector initialization + /// ### What it does + /// Checks slow zero-filled vector initialization /// - /// **Why is this bad?** These structures are non-idiomatic and less efficient than simply using + /// ### Why is this bad? + /// These structures are non-idiomatic and less efficient than simply using /// `vec![0; len]`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use core::iter::repeat; /// # let len = 4; diff --git a/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs index 65790375c73..4ea1293d504 100644 --- a/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs +++ b/src/tools/clippy/clippy_lints/src/stable_sort_primitive.rs @@ -7,22 +7,18 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// When sorting primitive values (integers, bools, chars, as well /// as arrays, slices, and tuples of such items), it is better to /// use an unstable sort than a stable sort. /// - /// **Why is this bad?** + /// ### Why is this bad? /// Using a stable sort consumes more memory and cpu cycles. Because /// values which compare equal are identical, preserving their /// relative order (the guarantee that a stable sort provides) means /// nothing, while the extra costs still apply. /// - /// **Known problems:** - /// None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let mut vec = vec![2, 1, 3]; /// vec.sort(); diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 958e462125e..1a78a4968e5 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -14,16 +14,15 @@ use rustc_span::source_map::Spanned; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for string appends of the form `x = x + y` (without + /// ### What it does + /// Checks for string appends of the form `x = x + y` (without /// `let`!). /// - /// **Why is this bad?** It's not really bad, but some people think that the + /// ### Why is this bad? + /// It's not really bad, but some people think that the /// `.push_str(_)` method is more readable. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let mut x = "Hello".to_owned(); /// x = x + ", World"; @@ -38,11 +37,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for all instances of `x + _` where `x` is of type + /// ### What it does + /// Checks for all instances of `x + _` where `x` is of type /// `String`, but only if [`string_add_assign`](#string_add_assign) does *not* /// match. /// - /// **Why is this bad?** It's not bad in and of itself. However, this particular + /// ### Why is this bad? + /// It's not bad in and of itself. However, this particular /// `Add` implementation is asymmetric (the other operand need not be `String`, /// but `x` does), while addition as mathematically defined is symmetric, also /// the `String::push_str(_)` function is a perfectly good replacement. @@ -52,10 +53,7 @@ declare_clippy_lint! { /// in other languages is actually fine, which is why we decided to make this /// particular lint `allow` by default. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let x = "Hello".to_owned(); /// x + ", World"; @@ -66,13 +64,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for the `as_bytes` method called on string literals + /// ### What it does + /// Checks for the `as_bytes` method called on string literals /// that contain only ASCII characters. /// - /// **Why is this bad?** Byte string literals (e.g., `b"foo"`) can be used + /// ### Why is this bad? + /// Byte string literals (e.g., `b"foo"`) can be used /// instead. They are shorter but less discoverable than `as_bytes()`. /// - /// **Known Problems:** + /// ### Known problems /// `"str".as_bytes()` and the suggested replacement of `b"str"` are not /// equivalent because they have different types. The former is `&[u8]` /// while the latter is `&[u8; 3]`. That means in general they will have a @@ -94,7 +94,7 @@ declare_clippy_lint! { /// `b"str"` but `&b"str"[..]`, which is a great deal of punctuation and not /// more readable than a function call. /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let bs = "a byte string".as_bytes(); @@ -177,13 +177,13 @@ fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { } declare_clippy_lint! { - /// **What it does:** Check if the string is transformed to byte array and casted back to string. + /// ### What it does + /// Check if the string is transformed to byte array and casted back to string. /// - /// **Why is this bad?** It's unnecessary, the string can be used directly. + /// ### Why is this bad? + /// It's unnecessary, the string can be used directly. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]).unwrap(); /// ``` @@ -317,16 +317,15 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { } declare_clippy_lint! { - /// **What it does:** This lint checks for `.to_string()` method calls on values of type `&str`. + /// ### What it does + /// This lint checks for `.to_string()` method calls on values of type `&str`. /// - /// **Why is this bad?** The `to_string` method is also used on other types to convert them to a string. + /// ### Why is this bad? + /// The `to_string` method is also used on other types to convert them to a string. /// When called on a `&str` it turns the `&str` into the owned variant `String`, which can be better /// expressed with `.to_owned()`. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // example code where clippy issues a warning /// let _ = "str".to_string(); @@ -366,14 +365,14 @@ impl LateLintPass<'_> for StrToString { } declare_clippy_lint! { - /// **What it does:** This lint checks for `.to_string()` method calls on values of type `String`. + /// ### What it does + /// This lint checks for `.to_string()` method calls on values of type `String`. /// - /// **Why is this bad?** The `to_string` method is also used on other types to convert them to a string. + /// ### Why is this bad? + /// The `to_string` method is also used on other types to convert them to a string. /// When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`. - /// **Known problems:** None. - /// - /// **Example:** /// + /// ### Example /// ```rust /// // example code where clippy issues a warning /// let msg = String::from("Hello World"); diff --git a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs index 2ccf3a3796d..516fa3d95b4 100644 --- a/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs +++ b/src/tools/clippy/clippy_lints/src/strlen_on_c_strings.rs @@ -11,16 +11,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::{sym, Symbol}; declare_clippy_lint! { - /// **What it does:** Checks for usage of `libc::strlen` on a `CString` or `CStr` value, + /// ### What it does + /// Checks for usage of `libc::strlen` on a `CString` or `CStr` value, /// and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead. /// - /// **Why is this bad?** This avoids calling an unsafe `libc` function. + /// ### Why is this bad? + /// This avoids calling an unsafe `libc` function. /// Currently, it also avoids calculating the length. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust, ignore /// use std::ffi::CString; /// let cstring = CString::new("foo").expect("CString::new failed"); diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index bb707f78fcc..a8e962d1af3 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -13,20 +13,21 @@ use rustc_span::symbol::Ident; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for unlikely usages of binary operators that are almost /// certainly typos and/or copy/paste errors, given the other usages /// of binary operators nearby. - /// **Why is this bad?** + /// + /// ### Why is this bad? /// They are probably bugs and if they aren't then they look like bugs /// and you should add a comment explaining why you are doing such an /// odd set of operations. - /// **Known problems:** + /// + /// ### Known problems /// There may be some false positives if you are trying to do something /// unusual that happens to look like a typo. /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct Vec3 { /// x: f64, diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs index f2bffd55321..682fad00a13 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs @@ -8,14 +8,14 @@ use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Lints for suspicious operations in impls of arithmetic operators, e.g. + /// ### What it does + /// Lints for suspicious operations in impls of arithmetic operators, e.g. /// subtracting elements in an Add impl. /// - /// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. + /// ### Why is this bad? + /// This is probably a typo or copy-and-paste error and not intended. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// impl Add for Foo { /// type Output = Foo; @@ -31,14 +31,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Lints for suspicious operations in impls of OpAssign, e.g. + /// ### What it does + /// Lints for suspicious operations in impls of OpAssign, e.g. /// subtracting elements in an AddAssign impl. /// - /// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. + /// ### Why is this bad? + /// This is probably a typo or copy-and-paste error and not intended. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```ignore /// impl AddAssign for Foo { /// fn add_assign(&mut self, other: Foo) { diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs index 19967e2c970..4fa8e77a67b 100644 --- a/src/tools/clippy/clippy_lints/src/swap.rs +++ b/src/tools/clippy/clippy_lints/src/swap.rs @@ -12,14 +12,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for manual swapping. + /// ### What it does + /// Checks for manual swapping. /// - /// **Why is this bad?** The `std::mem::swap` function exposes the intent better + /// ### Why is this bad? + /// The `std::mem::swap` function exposes the intent better /// without deinitializing or copying either variable. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let mut a = 42; /// let mut b = 1337; @@ -40,13 +40,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `foo = bar; bar = foo` sequences. + /// ### What it does + /// Checks for `foo = bar; bar = foo` sequences. /// - /// **Why is this bad?** This looks like a failed attempt to swap. + /// ### Why is this bad? + /// This looks like a failed attempt to swap. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let mut a = 1; /// # let mut b = 2; diff --git a/src/tools/clippy/clippy_lints/src/tabs_in_doc_comments.rs b/src/tools/clippy/clippy_lints/src/tabs_in_doc_comments.rs index e2c144709f5..6a73b94d87e 100644 --- a/src/tools/clippy/clippy_lints/src/tabs_in_doc_comments.rs +++ b/src/tools/clippy/clippy_lints/src/tabs_in_doc_comments.rs @@ -7,16 +7,16 @@ use rustc_span::source_map::{BytePos, Span}; use std::convert::TryFrom; declare_clippy_lint! { - /// **What it does:** Checks doc comments for usage of tab characters. + /// ### What it does + /// Checks doc comments for usage of tab characters. /// - /// **Why is this bad?** The rust style-guide promotes spaces instead of tabs for indentation. + /// ### Why is this bad? + /// The rust style-guide promotes spaces instead of tabs for indentation. /// To keep a consistent view on the source, also doc comments should not have tabs. /// Also, explaining ascii-diagrams containing tabs can get displayed incorrectly when the /// display settings of the author and reader differ. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// /// /// /// Struct to hold two strings: diff --git a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs index 8ef25dc816c..a9da690339c 100644 --- a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs +++ b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs @@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for construction of a structure or tuple just to + /// ### What it does + /// Checks for construction of a structure or tuple just to /// assign a value in it. /// - /// **Why is this bad?** Readability. If the structure is only created to be + /// ### Why is this bad? + /// Readability. If the structure is only created to be /// updated, why not write the structure you want in the first place? /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// (0, 0).0 = 1 /// ``` diff --git a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs index c66a596c784..1c14a919995 100644 --- a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs @@ -9,12 +9,14 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for `.to_digit(..).is_some()` on `char`s. + /// ### What it does + /// Checks for `.to_digit(..).is_some()` on `char`s. /// - /// **Why is this bad?** This is a convoluted way of checking if a `char` is a digit. It's + /// ### Why is this bad? + /// This is a convoluted way of checking if a `char` is a digit. It's /// more straight forward to use the dedicated `is_digit` method. /// - /// **Example:** + /// ### Example /// ```rust /// # let c = 'c'; /// # let radix = 10; diff --git a/src/tools/clippy/clippy_lints/src/to_string_in_display.rs b/src/tools/clippy/clippy_lints/src/to_string_in_display.rs index 4fb297ac6c6..b036ed9a3d2 100644 --- a/src/tools/clippy/clippy_lints/src/to_string_in_display.rs +++ b/src/tools/clippy/clippy_lints/src/to_string_in_display.rs @@ -7,15 +7,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks for uses of `to_string()` in `Display` traits. + /// ### What it does + /// Checks for uses of `to_string()` in `Display` traits. /// - /// **Why is this bad?** Usually `to_string` is implemented indirectly + /// ### Why is this bad? + /// Usually `to_string` is implemented indirectly /// via `Display`. Hence using it while implementing `Display` would /// lead to infinite recursion. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```rust /// use std::fmt; diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 74a94db1800..79367c4230c 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -11,14 +11,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** This lint warns about unnecessary type repetitions in trait bounds + /// ### What it does + /// This lint warns about unnecessary type repetitions in trait bounds /// - /// **Why is this bad?** Repeating the type for every bound makes the code + /// ### Why is this bad? + /// Repeating the type for every bound makes the code /// less readable than combining the bounds /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// pub fn foo(t: T) where T: Copy, T: Clone {} /// ``` @@ -34,15 +34,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for cases where generics are being used and multiple + /// ### What it does + /// Checks for cases where generics are being used and multiple /// syntax specifications for trait bounds are used simultaneously. /// - /// **Why is this bad?** Duplicate bounds makes the code + /// ### Why is this bad? + /// Duplicate bounds makes the code /// less readable than specifing them only once. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn func(arg: T) where T: Clone + Default {} /// ``` diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs index 569113910c9..33ec9c331ce 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs @@ -12,22 +12,26 @@ mod useless_transmute; mod utils; mod wrong_transmute; -use clippy_utils::{in_constant, match_def_path, paths}; +use clippy_utils::in_constant; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks for transmutes that can't ever be correct on any + /// ### What it does + /// Checks for transmutes that can't ever be correct on any /// architecture. /// - /// **Why is this bad?** It's basically guaranteed to be undefined behaviour. + /// ### Why is this bad? + /// It's basically guaranteed to be undefined behaviour. /// - /// **Known problems:** When accessing C, users might want to store pointer + /// ### Known problems + /// When accessing C, users might want to store pointer /// sized objects in `extradata` arguments to save an allocation. /// - /// **Example:** + /// ### Example /// ```ignore /// let ptr: *const T = core::intrinsics::transmute('x') /// ``` @@ -38,15 +42,15 @@ declare_clippy_lint! { // FIXME: Move this to `complexity` again, after #5343 is fixed declare_clippy_lint! { - /// **What it does:** Checks for transmutes to the original type of the object + /// ### What it does + /// Checks for transmutes to the original type of the object /// and transmutes that could be a cast. /// - /// **Why is this bad?** Readability. The code tricks people into thinking that + /// ### Why is this bad? + /// Readability. The code tricks people into thinking that /// something complex is going on. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// core::intrinsics::transmute(t); // where the result type is the same as `t`'s /// ``` @@ -57,14 +61,14 @@ declare_clippy_lint! { // FIXME: Merge this lint with USELESS_TRANSMUTE once that is out of the nursery. declare_clippy_lint! { - /// **What it does:**Checks for transmutes that could be a pointer cast. + /// ### What it does + ///Checks for transmutes that could be a pointer cast. /// - /// **Why is this bad?** Readability. The code tricks people into thinking that + /// ### Why is this bad? + /// Readability. The code tricks people into thinking that /// something complex is going on. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// /// ```rust /// # let p: *const [i32] = &[]; @@ -81,14 +85,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes between a type `T` and `*T`. + /// ### What it does + /// Checks for transmutes between a type `T` and `*T`. /// - /// **Why is this bad?** It's easy to mistakenly transmute between a type and a + /// ### Why is this bad? + /// It's easy to mistakenly transmute between a type and a /// pointer to that type. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// core::intrinsics::transmute(t) // where the result type is the same as /// // `*t` or `&t`'s @@ -99,17 +103,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from a pointer to a reference. + /// ### What it does + /// Checks for transmutes from a pointer to a reference. /// - /// **Why is this bad?** This can always be rewritten with `&` and `*`. + /// ### Why is this bad? + /// This can always be rewritten with `&` and `*`. /// - /// **Known problems:** + /// ### Known problems /// - `mem::transmute` in statics and constants is stable from Rust 1.46.0, /// while dereferencing raw pointer is not stable yet. /// If you need to do this in those places, /// you would have to use `transmute` instead. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// unsafe { /// let _: &T = std::mem::transmute(p); // where p: *const T @@ -124,11 +130,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from an integer to a `char`. + /// ### What it does + /// Checks for transmutes from an integer to a `char`. /// - /// **Why is this bad?** Not every integer is a Unicode scalar value. + /// ### Why is this bad? + /// Not every integer is a Unicode scalar value. /// - /// **Known problems:** + /// ### Known problems /// - [`from_u32`] which this lint suggests using is slower than `transmute` /// as it needs to validate the input. /// If you are certain that the input is always a valid Unicode scalar value, @@ -139,7 +147,7 @@ declare_clippy_lint! { /// [`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html /// [`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html /// - /// **Example:** + /// ### Example /// ```rust /// let x = 1_u32; /// unsafe { @@ -155,11 +163,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from a `&[u8]` to a `&str`. + /// ### What it does + /// Checks for transmutes from a `&[u8]` to a `&str`. /// - /// **Why is this bad?** Not every byte slice is a valid UTF-8 string. + /// ### Why is this bad? + /// Not every byte slice is a valid UTF-8 string. /// - /// **Known problems:** + /// ### Known problems /// - [`from_utf8`] which this lint suggests using is slower than `transmute` /// as it needs to validate the input. /// If you are certain that the input is always a valid UTF-8, @@ -170,7 +180,7 @@ declare_clippy_lint! { /// [`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html /// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html /// - /// **Example:** + /// ### Example /// ```rust /// let b: &[u8] = &[1_u8, 2_u8]; /// unsafe { @@ -186,13 +196,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from an integer to a `bool`. + /// ### What it does + /// Checks for transmutes from an integer to a `bool`. /// - /// **Why is this bad?** This might result in an invalid in-memory representation of a `bool`. + /// ### Why is this bad? + /// This might result in an invalid in-memory representation of a `bool`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = 1_u8; /// unsafe { @@ -208,14 +218,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from an integer to a float. + /// ### What it does + /// Checks for transmutes from an integer to a float. /// - /// **Why is this bad?** Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive + /// ### Why is this bad? + /// Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive /// and safe. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// unsafe { /// let _: f32 = std::mem::transmute(1_u32); // where x: u32 @@ -230,14 +240,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from a float to an integer. + /// ### What it does + /// Checks for transmutes from a float to an integer. /// - /// **Why is this bad?** Transmutes are dangerous and error-prone, whereas `to_bits` is intuitive + /// ### Why is this bad? + /// Transmutes are dangerous and error-prone, whereas `to_bits` is intuitive /// and safe. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// unsafe { /// let _: u32 = std::mem::transmute(1f32); @@ -252,15 +262,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes from a pointer to a pointer, or + /// ### What it does + /// Checks for transmutes from a pointer to a pointer, or /// from a reference to a reference. /// - /// **Why is this bad?** Transmutes are dangerous, and these can instead be + /// ### Why is this bad? + /// Transmutes are dangerous, and these can instead be /// written as casts. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let ptr = &1u32 as *const u32; /// unsafe { @@ -279,15 +289,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for transmutes between collections whose + /// ### What it does + /// Checks for transmutes between collections whose /// types have different ABI, size or alignment. /// - /// **Why is this bad?** This is undefined behavior. + /// ### Why is this bad? + /// This is undefined behavior. /// - /// **Known problems:** Currently, we cannot know whether a type is a + /// ### Known problems + /// Currently, we cannot know whether a type is a /// collection, so we just lint the ones that come with `std`. /// - /// **Example:** + /// ### Example /// ```rust /// // different size, therefore likely out-of-bounds memory access /// // You absolutely do not want this in your code! @@ -328,7 +341,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if let ExprKind::Call(path_expr, args) = e.kind; if let ExprKind::Path(ref qpath) = path_expr.kind; if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::TRANSMUTE); + if cx.tcx.is_diagnostic_item(sym::transmute, def_id); then { // Avoid suggesting from/to bits and dereferencing raw pointers in const contexts. // See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`. diff --git a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs index de9277e016e..868c41aab43 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs @@ -1,20 +1,21 @@ use super::utils::is_layout_incompatible; use super::UNSOUND_COLLECTION_TRANSMUTE; use clippy_utils::diagnostics::span_lint; -use clippy_utils::{match_def_path, paths}; +use clippy_utils::match_any_diagnostic_items; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; +use rustc_span::symbol::{sym, Symbol}; // used to check for UNSOUND_COLLECTION_TRANSMUTE -static COLLECTIONS: &[&[&str]] = &[ - &paths::VEC, - &paths::VEC_DEQUE, - &paths::BINARY_HEAP, - &paths::BTREESET, - &paths::BTREEMAP, - &paths::HASHSET, - &paths::HASHMAP, +static COLLECTIONS: &[Symbol] = &[ + sym::vec_type, + sym::vecdeque_type, + sym::BinaryHeap, + sym::BTreeSet, + sym::BTreeMap, + sym::hashset_type, + sym::hashmap_type, ]; /// Checks for `unsound_collection_transmute` lint. @@ -22,7 +23,7 @@ static COLLECTIONS: &[&[&str]] = &[ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { match (&from_ty.kind(), &to_ty.kind()) { (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { - if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) { + if from_adt.did != to_adt.did || match_any_diagnostic_items(cx, to_adt.did, COLLECTIONS).is_none() { return false; } if from_substs diff --git a/src/tools/clippy/clippy_lints/src/transmuting_null.rs b/src/tools/clippy/clippy_lints/src/transmuting_null.rs index b57d158293d..a67fa792205 100644 --- a/src/tools/clippy/clippy_lints/src/transmuting_null.rs +++ b/src/tools/clippy/clippy_lints/src/transmuting_null.rs @@ -1,23 +1,27 @@ use clippy_utils::consts::{constant_context, Constant}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::{is_expr_path_def_path, paths}; +use clippy_utils::is_expr_diagnostic_item; use if_chain::if_chain; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; declare_clippy_lint! { - /// **What it does:** Checks for transmute calls which would receive a null pointer. + /// ### What it does + /// Checks for transmute calls which would receive a null pointer. /// - /// **Why is this bad?** Transmuting a null pointer is undefined behavior. + /// ### Why is this bad? + /// Transmuting a null pointer is undefined behavior. /// - /// **Known problems:** Not all cases can be detected at the moment of this writing. + /// ### Known problems + /// Not all cases can be detected at the moment of this writing. /// For example, variables which hold a null pointer and are then fed to a `transmute` /// call, aren't detectable yet. /// - /// **Example:** + /// ### Example /// ```rust /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) }; /// ``` @@ -38,7 +42,7 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull { if_chain! { if let ExprKind::Call(func, [arg]) = expr.kind; - if is_expr_path_def_path(cx, func, &paths::TRANSMUTE); + if is_expr_diagnostic_item(cx, func, sym::transmute); then { // Catching transmute over constants that resolve to `null`. @@ -67,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull { // `std::mem::transmute(std::ptr::null::())` if_chain! { if let ExprKind::Call(func1, []) = arg.kind; - if is_expr_path_def_path(cx, func1, &paths::PTR_NULL); + if is_expr_diagnostic_item(cx, func1, sym::ptr_null); then { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG) } diff --git a/src/tools/clippy/clippy_lints/src/try_err.rs b/src/tools/clippy/clippy_lints/src/try_err.rs index f2ba2b2ecf6..1196271d5dd 100644 --- a/src/tools/clippy/clippy_lints/src/try_err.rs +++ b/src/tools/clippy/clippy_lints/src/try_err.rs @@ -13,16 +13,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for usages of `Err(x)?`. + /// ### What it does + /// Checks for usages of `Err(x)?`. /// - /// **Why is this bad?** The `?` operator is designed to allow calls that + /// ### Why is this bad? + /// The `?` operator is designed to allow calls that /// can fail to be easily chained. For example, `foo()?.bar()` or /// `foo(bar()?)`. Because `Err(x)?` can't be used that way (it will /// always return), it is more clear to write `return Err(x)`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn foo(fail: bool) -> Result { /// if fail { diff --git a/src/tools/clippy/clippy_lints/src/types/linked_list.rs b/src/tools/clippy/clippy_lints/src/types/linked_list.rs index a9fbe7aa315..5fb708741e5 100644 --- a/src/tools/clippy/clippy_lints/src/types/linked_list.rs +++ b/src/tools/clippy/clippy_lints/src/types/linked_list.rs @@ -1,12 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{match_def_path, paths}; use rustc_hir::{self as hir, def_id::DefId}; use rustc_lint::LateContext; +use rustc_span::symbol::sym; use super::LINKEDLIST; pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, def_id: DefId) -> bool { - if match_def_path(cx, def_id, &paths::LINKED_LIST) { + if cx.tcx.is_diagnostic_item(sym::LinkedList, def_id) { span_lint_and_help( cx, LINKEDLIST, diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 7d629b5455b..ad7409fe3a9 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -20,16 +20,16 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; declare_clippy_lint! { - /// **What it does:** Checks for use of `Box>` anywhere in the code. + /// ### What it does + /// Checks for use of `Box>` anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// - /// **Why is this bad?** `Vec` already keeps its contents in a separate area on + /// ### Why is this bad? + /// `Vec` already keeps its contents in a separate area on /// the heap. So if you `Box` it, you just add another level of indirection /// without any benefit whatsoever. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// struct X { /// values: Box>, @@ -49,16 +49,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `Vec>` where T: Sized anywhere in the code. + /// ### What it does + /// Checks for use of `Vec>` where T: Sized anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// - /// **Why is this bad?** `Vec` already keeps its contents in a separate area on + /// ### Why is this bad? + /// `Vec` already keeps its contents in a separate area on /// the heap. So if you `Box` its contents, you just add another level of indirection. /// - /// **Known problems:** Vec> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530), + /// ### Known problems + /// Vec> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530), /// 1st comment). /// - /// **Example:** + /// ### Example /// ```rust /// struct X { /// values: Vec>, @@ -78,19 +81,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `Option>` in function signatures and type + /// ### What it does + /// Checks for use of `Option>` in function signatures and type /// definitions /// - /// **Why is this bad?** `Option<_>` represents an optional value. `Option>` + /// ### Why is this bad? + /// `Option<_>` represents an optional value. `Option>` /// represents an optional optional value which is logically the same thing as an optional /// value but has an unneeded extra level of wrapping. /// /// If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases, /// consider a custom `enum` instead, with clear names for each case. /// - /// **Known problems:** None. - /// - /// **Example** + /// ### Example /// ```rust /// fn get_data() -> Option> { /// None @@ -116,10 +119,12 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of any `LinkedList`, suggesting to use a + /// ### What it does + /// Checks for usage of any `LinkedList`, suggesting to use a /// `Vec` or a `VecDeque` (formerly called `RingBuf`). /// - /// **Why is this bad?** Gankro says: + /// ### Why is this bad? + /// Gankro says: /// /// > The TL;DR of `LinkedList` is that it's built on a massive amount of /// pointers and indirection. @@ -138,10 +143,11 @@ declare_clippy_lint! { /// can still be better /// > because of how expensive it is to seek to the middle of a `LinkedList`. /// - /// **Known problems:** False positives – the instances where using a + /// ### Known problems + /// False positives – the instances where using a /// `LinkedList` makes sense are few and far between, but they can still happen. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::collections::LinkedList; /// let x: LinkedList = LinkedList::new(); @@ -152,15 +158,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `&Box` anywhere in the code. + /// ### What it does + /// Checks for use of `&Box` anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// - /// **Why is this bad?** Any `&Box` can also be a `&T`, which is more + /// ### Why is this bad? + /// Any `&Box` can also be a `&T`, which is more /// general. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// fn foo(bar: &Box) { ... } /// ``` @@ -176,14 +182,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of redundant allocations anywhere in the code. + /// ### What it does + /// Checks for use of redundant allocations anywhere in the code. /// - /// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc>`, `Rc>`, `Rc>`, Arc<&T>`, `Arc>`, + /// ### Why is this bad? + /// Expressions such as `Rc<&T>`, `Rc>`, `Rc>`, `Rc>`, Arc<&T>`, `Arc>`, /// `Arc>`, `Arc>`, `Box<&T>`, `Box>`, `Box>`, `Box>`, add an unnecessary level of indirection. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::rc::Rc; /// fn foo(bar: Rc<&usize>) {} @@ -200,9 +206,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `Rc` and `Arc` when `T` is a mutable buffer type such as `String` or `Vec`. + /// ### What it does + /// Checks for `Rc` and `Arc` when `T` is a mutable buffer type such as `String` or `Vec`. /// - /// **Why is this bad?** Expressions such as `Rc` usually have no advantage over `Rc`, since + /// ### Why is this bad? + /// Expressions such as `Rc` usually have no advantage over `Rc`, since /// it is larger and involves an extra level of indirection, and doesn't implement `Borrow`. /// /// While mutating a buffer type would still be possible with `Rc::get_mut()`, it only @@ -211,10 +219,11 @@ declare_clippy_lint! { /// type with an interior mutable container (such as `RefCell` or `Mutex`) would normally /// be used. /// - /// **Known problems:** This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for + /// ### Known problems + /// This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for /// cases where mutation only happens before there are any additional references. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// # use std::rc::Rc; /// fn foo(interned: Rc) { ... } @@ -231,15 +240,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for types used in structs, parameters and `let` + /// ### What it does + /// Checks for types used in structs, parameters and `let` /// declarations above a certain complexity threshold. /// - /// **Why is this bad?** Too complex types make the code less readable. Consider + /// ### Why is this bad? + /// Too complex types make the code less readable. Consider /// using a `type` definition to simplify them. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::rc::Rc; /// struct Foo { @@ -252,16 +261,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `Rc>`. + /// ### What it does + /// Checks for `Rc>`. /// - /// **Why is this bad?** `Rc` is used in single thread and `Mutex` is used in multi thread. + /// ### Why is this bad? + /// `Rc` is used in single thread and `Mutex` is used in multi thread. /// Consider using `Rc>` in single thread or `Arc>` in multi thread. /// - /// **Known problems:** Sometimes combining generic types can lead to the requirement that a + /// ### Known problems + /// Sometimes combining generic types can lead to the requirement that a /// type use Rc in conjunction with Mutex. We must consider those cases false positives, but /// alas they are quite hard to rule out. Luckily they are also rare. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// use std::rc::Rc; /// use std::sync::Mutex; diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs index b438d680d2c..20c136407a1 100644 --- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use rustc_hir as hir; -use rustc_hir::intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}; +use rustc_hir::intravisit::{walk_inf, walk_ty, NestedVisitorMap, Visitor}; use rustc_hir::{GenericParamKind, TyKind}; use rustc_lint::LateContext; use rustc_middle::hir::map::Map; @@ -40,8 +40,8 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { type Map = Map<'tcx>; fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { - self.score += 1; - walk_inf(self, inf); + self.score += 1; + walk_inf(self, inf); } fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) { diff --git a/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs b/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs index f4f5e1233e3..47571e608c7 100644 --- a/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs +++ b/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs @@ -6,15 +6,17 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`. + /// ### What it does + /// Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`. /// - /// **Why is this bad?** The safe `drop` function does not drop the inner value of a `ManuallyDrop`. + /// ### Why is this bad? + /// The safe `drop` function does not drop the inner value of a `ManuallyDrop`. /// - /// **Known problems:** Does not catch cases if the user binds `std::mem::drop` + /// ### Known problems + /// Does not catch cases if the user binds `std::mem::drop` /// to a different name and calls it that way. /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct S; /// drop(std::mem::ManuallyDrop::new(S)); diff --git a/src/tools/clippy/clippy_lints/src/unicode.rs b/src/tools/clippy/clippy_lints/src/unicode.rs index 2f0a61898ba..f337dec8f2b 100644 --- a/src/tools/clippy/clippy_lints/src/unicode.rs +++ b/src/tools/clippy/clippy_lints/src/unicode.rs @@ -10,14 +10,15 @@ use rustc_span::source_map::Span; use unicode_normalization::UnicodeNormalization; declare_clippy_lint! { - /// **What it does:** Checks for invisible Unicode characters in the code. + /// ### What it does + /// Checks for invisible Unicode characters in the code. /// - /// **Why is this bad?** Having an invisible character in the code makes for all + /// ### Why is this bad? + /// Having an invisible character in the code makes for all /// sorts of April fools, but otherwise is very much frowned upon. /// - /// **Known problems:** None. - /// - /// **Example:** You don't see it, but there may be a zero-width space or soft hyphen + /// ### Example + /// You don't see it, but there may be a zero-width space or soft hyphen /// some­where in this text. pub INVISIBLE_CHARACTERS, correctness, @@ -25,17 +26,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for non-ASCII characters in string literals. + /// ### What it does + /// Checks for non-ASCII characters in string literals. /// - /// **Why is this bad?** Yeah, we know, the 90's called and wanted their charset + /// ### Why is this bad? + /// Yeah, we know, the 90's called and wanted their charset /// back. Even so, there still are editors and other programs out there that /// don't work well with Unicode. So if the code is meant to be used /// internationally, on multiple operating systems, or has other portability /// requirements, activating this lint could be useful. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = String::from("€"); /// ``` @@ -49,16 +50,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for string literals that contain Unicode in a form + /// ### What it does + /// Checks for string literals that contain Unicode in a form /// that is not equal to its /// [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms). /// - /// **Why is this bad?** If such a string is compared to another, the results + /// ### Why is this bad? + /// If such a string is compared to another, the results /// may be surprising. /// - /// **Known problems** None. - /// - /// **Example:** You may not see it, but "à"" and "à"" aren't the same string. The + /// ### Example + /// You may not see it, but "à"" and "à"" aren't the same string. The /// former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`. pub UNICODE_NOT_NFC, pedantic, diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 1c420a50427..900d4531760 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -10,20 +10,22 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{BytePos, Span}; declare_clippy_lint! { - /// **What it does:** Checks for functions that expect closures of type + /// ### What it does + /// Checks for functions that expect closures of type /// Fn(...) -> Ord where the implemented closure returns the unit type. /// The lint also suggests to remove the semi-colon at the end of the statement if present. /// - /// **Why is this bad?** Likely, returning the unit type is unintentional, and + /// ### Why is this bad? + /// Likely, returning the unit type is unintentional, and /// could simply be caused by an extra semi-colon. Since () implements Ord /// it doesn't cause a compilation error. /// This is the same reasoning behind the unit_cmp lint. /// - /// **Known problems:** If returning unit is intentional, then there is no + /// ### Known problems + /// If returning unit is intentional, then there is no /// way of specifying this without triggering needless_return lint /// - /// **Example:** - /// + /// ### Example /// ```rust /// let mut twins = vec!((1, 1), (2, 2)); /// twins.sort_by_key(|x| { x.1; }); diff --git a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs index 64420a03933..66b1abbe50b 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs @@ -8,14 +8,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for binding a unit value. + /// ### What it does + /// Checks for binding a unit value. /// - /// **Why is this bad?** A unit value cannot usefully be used anywhere. So + /// ### Why is this bad? + /// A unit value cannot usefully be used anywhere. So /// binding one is kind of pointless. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// let x = { /// 1; @@ -27,16 +27,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for comparisons to unit. This includes all binary + /// ### What it does + /// Checks for comparisons to unit. This includes all binary /// comparisons (like `==` and `<`) and asserts. /// - /// **Why is this bad?** Unit is always equal to itself, and thus is just a + /// ### Why is this bad? + /// Unit is always equal to itself, and thus is just a /// clumsily written constant. Mostly this happens when someone accidentally /// adds semicolons at the end of the operands. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn foo() {}; /// # fn bar() {}; @@ -74,14 +74,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for passing a unit value as an argument to a function without using a + /// ### What it does + /// Checks for passing a unit value as an argument to a function without using a /// unit literal (`()`). /// - /// **Why is this bad?** This is likely the result of an accidental semicolon. + /// ### Why is this bad? + /// This is likely the result of an accidental semicolon. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// foo({ /// let a = bar(); diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs index 9cca05b1f1a..1eafdee0352 100644 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ b/src/tools/clippy/clippy_lints/src/unnamed_address.rs @@ -7,16 +7,15 @@ use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for comparisons with an address of a function item. + /// ### What it does + /// Checks for comparisons with an address of a function item. /// - /// **Why is this bad?** Function item address is not guaranteed to be unique and could vary + /// ### Why is this bad? + /// Function item address is not guaranteed to be unique and could vary /// between different code generation units. Furthermore different function items could have /// the same address after being merged together. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// type F = fn(); /// fn a() {} @@ -31,17 +30,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for comparisons with an address of a trait vtable. + /// ### What it does + /// Checks for comparisons with an address of a trait vtable. /// - /// **Why is this bad?** Comparing trait objects pointers compares an vtable addresses which + /// ### Why is this bad? + /// Comparing trait objects pointers compares an vtable addresses which /// are not guaranteed to be unique and could vary between different code generation units. /// Furthermore vtables for different types could have the same address after being merged /// together. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// let a: Rc = ... /// let b: Rc = ... diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs index 48c54d79cf1..4cfd2df551f 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs @@ -7,16 +7,18 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::kw; declare_clippy_lint! { - /// **What it does:** Checks for imports ending in `::{self}`. + /// ### What it does + /// Checks for imports ending in `::{self}`. /// - /// **Why is this bad?** In most cases, this can be written much more cleanly by omitting `::{self}`. + /// ### Why is this bad? + /// In most cases, this can be written much more cleanly by omitting `::{self}`. /// - /// **Known problems:** Removing `::{self}` will cause any non-module items at the same path to also be imported. + /// ### Known problems + /// Removing `::{self}` will cause any non-module items at the same path to also be imported. /// This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt /// to detect this scenario and that is why it is a restriction lint. /// - /// **Example:** - /// + /// ### Example /// ```rust /// use std::io::{self}; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs index 347d858b640..6fc5707a4ee 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs @@ -12,21 +12,20 @@ use rustc_span::symbol::Ident; use std::iter; declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Detects uses of `Vec::sort_by` passing in a closure /// which compares the two arguments, either directly or indirectly. /// - /// **Why is this bad?** + /// ### Why is this bad? /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if /// possible) than to use `Vec::sort_by` and a more complicated /// closure. /// - /// **Known problems:** + /// ### Known problems /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already /// imported by a use statement, then it will need to be added manually. /// - /// **Example:** - /// + /// ### Example /// ```rust /// # struct A; /// # impl A { fn foo(&self) {} } diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs index a85ffa6aa95..7a62b21937f 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs @@ -13,15 +13,17 @@ use rustc_span::symbol::sym; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for private functions that only return `Ok` or `Some`. + /// ### What it does + /// Checks for private functions that only return `Ok` or `Some`. /// - /// **Why is this bad?** It is not meaningful to wrap values when no `None` or `Err` is returned. + /// ### Why is this bad? + /// It is not meaningful to wrap values when no `None` or `Err` is returned. /// - /// **Known problems:** There can be false positives if the function signature is designed to + /// ### Known problems + /// There can be false positives if the function signature is designed to /// fit some external requirement. /// - /// **Example:** - /// + /// ### Example /// ```rust /// fn get_cool_number(a: bool, b: bool) -> Option { /// if a && b { diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 07a4e294049..9acfbc994b3 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -17,22 +17,17 @@ use std::cell::Cell; use std::mem; declare_clippy_lint! { - /// **What it does:** - /// + /// ### What it does /// Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and /// suggests replacing the pattern with a nested one, `Some(0 | 2)`. /// /// Another way to think of this is that it rewrites patterns in /// *disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*. /// - /// **Why is this bad?** - /// + /// ### Why is this bad? /// In the example above, `Some` is repeated, which unncessarily complicates the pattern. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// fn main() { /// if let Some(0) | Some(2) = Some(0) {} diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs index 16ad9d2dfd3..3c694af2b9d 100644 --- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs +++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs @@ -6,15 +6,15 @@ use rustc_span::source_map::Span; use rustc_span::symbol::Ident; declare_clippy_lint! { - /// **What it does:** Checks for imports that remove "unsafe" from an item's + /// ### What it does + /// Checks for imports that remove "unsafe" from an item's /// name. /// - /// **Why is this bad?** Renaming makes it less clear which traits and + /// ### Why is this bad? + /// Renaming makes it less clear which traits and /// structures are unsafe. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// use std::cell::{UnsafeCell as TotallySafeCell}; /// diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs index 18ee07d3a95..3a6a07c5226 100644 --- a/src/tools/clippy/clippy_lints/src/unused_async.rs +++ b/src/tools/clippy/clippy_lints/src/unused_async.rs @@ -7,16 +7,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; declare_clippy_lint! { - /// **What it does:** Checks for functions that are declared `async` but have no `.await`s inside of them. + /// ### What it does + /// Checks for functions that are declared `async` but have no `.await`s inside of them. /// - /// **Why is this bad?** Async functions with no async code create overhead, both mentally and computationally. + /// ### Why is this bad? + /// Async functions with no async code create overhead, both mentally and computationally. /// Callers of async methods either need to be calling from an async function themselves or run it on an executor, both of which /// causes runtime overhead and hassle for the caller. /// - /// **Known problems:** None - /// - /// **Example:** - /// + /// ### Example /// ```rust /// // Bad /// async fn get_random_number() -> i64 { diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index ee082d30d93..82bc4a6d153 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -5,9 +5,11 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for unused written/read amount. + /// ### What it does + /// Checks for unused written/read amount. /// - /// **Why is this bad?** `io::Write::write(_vectored)` and + /// ### Why is this bad? + /// `io::Write::write(_vectored)` and /// `io::Read::read(_vectored)` are not guaranteed to /// process the entire buffer. They return how many bytes were processed, which /// might be smaller @@ -15,9 +17,10 @@ declare_clippy_lint! { /// partial-write/read, use /// `write_all`/`read_exact` instead. /// - /// **Known problems:** Detects only common patterns. + /// ### Known problems + /// Detects only common patterns. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// use std::io; /// fn foo(w: &mut W) -> io::Result<()> { diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 15343cf90f2..658ac81f6ea 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -6,14 +6,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks methods that contain a `self` argument but don't use it + /// ### What it does + /// Checks methods that contain a `self` argument but don't use it /// - /// **Why is this bad?** It may be clearer to define the method as an associated function instead + /// ### Why is this bad? + /// It may be clearer to define the method as an associated function instead /// of an instance method if it doesn't require `self`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust,ignore /// struct A; /// impl A { diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs index ab0cdf75ffe..9ed5e585f84 100644 --- a/src/tools/clippy/clippy_lints/src/unused_unit.rs +++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs @@ -10,15 +10,15 @@ use rustc_span::source_map::Span; use rustc_span::BytePos; declare_clippy_lint! { - /// **What it does:** Checks for unit (`()`) expressions that can be removed. + /// ### What it does + /// Checks for unit (`()`) expressions that can be removed. /// - /// **Why is this bad?** Such expressions add no value, but can make the code + /// ### Why is this bad? + /// Such expressions add no value, but can make the code /// less readable. Depending on formatting they can make a `break` or `return` /// statement look like a function call. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// fn return_unit() -> () { /// () diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index d4efee56eff..c5b8acb9982 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -13,13 +13,13 @@ use rustc_span::source_map::Span; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for calls of `unwrap[_err]()` that cannot fail. + /// ### What it does + /// Checks for calls of `unwrap[_err]()` that cannot fail. /// - /// **Why is this bad?** Using `if let` or `match` is more idiomatic. + /// ### Why is this bad? + /// Using `if let` or `match` is more idiomatic. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// ```rust /// # let option = Some(0); /// # fn do_something_with(_x: usize) {} @@ -43,14 +43,17 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls of `unwrap[_err]()` that will always fail. + /// ### What it does + /// Checks for calls of `unwrap[_err]()` that will always fail. /// - /// **Why is this bad?** If panicking is desired, an explicit `panic!()` should be used. + /// ### Why is this bad? + /// If panicking is desired, an explicit `panic!()` should be used. /// - /// **Known problems:** This lint only checks `if` conditions not assignments. + /// ### Known problems + /// This lint only checks `if` conditions not assignments. /// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized. /// - /// **Example:** + /// ### Example /// ```rust /// # let option = Some(0); /// # fn do_something_with(_x: usize) {} diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs index d17aa6d8424..6eadd1fc1c9 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs @@ -12,13 +12,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span}; declare_clippy_lint! { - /// **What it does:** Checks for functions of type Result that contain `expect()` or `unwrap()` + /// ### What it does + /// Checks for functions of type Result that contain `expect()` or `unwrap()` /// - /// **Why is this bad?** These functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics. + /// ### Why is this bad? + /// These functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics. /// - /// **Known problems:** This can cause false positives in functions that handle both recoverable and non recoverable errors. + /// ### Known problems + /// This can cause false positives in functions that handle both recoverable and non recoverable errors. /// - /// **Example:** + /// ### Example /// Before: /// ```rust /// fn divisible_by_3(i_str: String) -> Result<(), String> { diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs index 0b58c6c0917..7fa0e23ee73 100644 --- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs +++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs @@ -8,9 +8,11 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::Ident; declare_clippy_lint! { - /// **What it does:** Checks for fully capitalized names and optionally names containing a capitalized acronym. + /// ### What it does + /// Checks for fully capitalized names and optionally names containing a capitalized acronym. /// - /// **Why is this bad?** In CamelCase, acronyms count as one word. + /// ### Why is this bad? + /// In CamelCase, acronyms count as one word. /// See [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case) /// for more. /// @@ -18,12 +20,12 @@ declare_clippy_lint! { /// You can use the `upper-case-acronyms-aggressive: true` config option to enable linting /// on all camel case names /// - /// **Known problems:** When two acronyms are contiguous, the lint can't tell where + /// ### Known problems + /// When two acronyms are contiguous, the lint can't tell where /// the first acronym ends and the second starts, so it suggests to lowercase all of /// the letters in the second acronym. /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct HTTPResponse; /// ``` diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index d5ee717accd..a3601cca2ef 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -8,9 +8,8 @@ use rustc_hir::{ self as hir, def::{CtorOf, DefKind, Res}, def_id::LocalDefId, - intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, - QPath, TyKind, + intravisit::{walk_inf, walk_ty, NestedVisitorMap, Visitor}, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -21,19 +20,20 @@ use rustc_span::Span; use rustc_typeck::hir_ty_to_ty; declare_clippy_lint! { - /// **What it does:** Checks for unnecessary repetition of structure name when a + /// ### What it does + /// Checks for unnecessary repetition of structure name when a /// replacement with `Self` is applicable. /// - /// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct + /// ### Why is this bad? + /// Unnecessary repetition. Mixed use of `Self` and struct /// name /// feels inconsistent. /// - /// **Known problems:** + /// ### Known problems /// - Unaddressed false negative in fn bodies of trait implementations /// - False positive with assotiated types in traits (#4140) /// - /// **Example:** - /// + /// ### Example /// ```rust /// struct Foo {} /// impl Foo { @@ -265,9 +265,9 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector { type Map = Map<'tcx>; fn visit_infer(&mut self, inf: &hir::InferArg) { - self.types_to_skip.push(inf.hir_id); + self.types_to_skip.push(inf.hir_id); - walk_inf(self, inf) + walk_inf(self, inf); } fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) { self.types_to_skip.push(hir_ty.hir_id); diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index c97f7e1626e..2861b432919 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::source::{snippet, snippet_with_macro_callsite}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts}; -use clippy_utils::{get_parent_expr, match_def_path, match_trait_method, paths}; +use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, HirId, MatchSource}; @@ -12,15 +12,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls + /// ### What it does + /// Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls /// which uselessly convert to the same type. /// - /// **Why is this bad?** Redundant code. - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// Redundant code. /// + /// ### Example /// ```rust /// // Bad /// // format!() returns a `String` @@ -64,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { }, ExprKind::MethodCall(name, .., args, _) => { - if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" { + if is_trait_method(cx, e, sym::into_trait) && &*name.ident.as_str() == "into" { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(&args[0]); if same_type_and_consts(a, b) { @@ -80,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { ); } } - if match_trait_method(cx, e, &paths::INTO_ITERATOR) && name.ident.name == sym::into_iter { + if is_trait_method(cx, e, sym::IntoIterator) && name.ident.name == sym::into_iter { if let Some(parent_expr) = get_parent_expr(cx, e) { if let ExprKind::MethodCall(parent_name, ..) = parent_expr.kind { if parent_name.ident.name != sym::into_iter { @@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { } } if_chain! { - if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && name.ident.name == sym::try_into; + if is_trait_method(cx, e, sym::try_into_trait) && name.ident.name == sym::try_into; let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(&args[0]); if is_type_diagnostic_item(cx, a, sym::result_type); diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 39ef170ae36..61fd375a989 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -7,15 +7,16 @@ use rustc_ast::walk_list; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind}; +use rustc_hir::{Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Generates clippy code that detects the offending pattern + /// ### What it does + /// Generates clippy code that detects the offending pattern /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // ./tests/ui/my_lint.rs /// fn foo() { @@ -132,6 +133,10 @@ impl<'tcx> LateLintPass<'tcx> for Author { if !has_attr(cx, stmt.hir_id) { return; } + match stmt.kind { + StmtKind::Expr(e) | StmtKind::Semi(e) if has_attr(cx, e.hir_id) => return, + _ => {}, + } prelude(); PrintVisitor::new("stmt").visit_stmt(stmt); done(); @@ -316,11 +321,13 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { self.current = cast_pat; self.visit_expr(expr); }, - ExprKind::Loop(body, _, desugaring, _) => { + ExprKind::Loop(body, _, des, _) => { let body_pat = self.next("body"); - let des = loop_desugaring_name(desugaring); let label_pat = self.next("label"); - println!("Loop(ref {}, ref {}, {}) = {};", body_pat, label_pat, des, current); + println!( + "Loop(ref {}, ref {}, LoopSource::{:?}) = {};", + body_pat, label_pat, des, current + ); self.current = body_pat; self.visit_block(body); }, @@ -343,11 +350,13 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { self.current = then_pat; self.visit_expr(then); }, - ExprKind::Match(expr, arms, desugaring) => { - let des = desugaring_name(desugaring); + ExprKind::Match(expr, arms, des) => { let expr_pat = self.next("expr"); let arms_pat = self.next("arms"); - println!("Match(ref {}, ref {}, {}) = {};", expr_pat, arms_pat, des, current); + println!( + "Match(ref {}, ref {}, MatchSource::{:?}) = {};", + expr_pat, arms_pat, des, current + ); self.current = expr_pat; self.visit_expr(expr); println!(" if {}.len() == {};", arms_pat, arms.len()); @@ -536,14 +545,19 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { } fn visit_block(&mut self, block: &Block<'_>) { - let trailing_pat = self.next("trailing_expr"); - println!(" if let Some({}) = &{}.expr;", trailing_pat, self.current); println!(" if {}.stmts.len() == {};", self.current, block.stmts.len()); - let current = self.current.clone(); + let block_name = self.current.clone(); for (i, stmt) in block.stmts.iter().enumerate() { - self.current = format!("{}.stmts[{}]", current, i); + self.current = format!("{}.stmts[{}]", block_name, i); self.visit_stmt(stmt); } + if let Some(expr) = block.expr { + self.current = self.next("trailing_expr"); + println!(" if let Some({}) = &{}.expr;", self.current, block_name); + self.visit_expr(expr); + } else { + println!(" if {}.expr.is_none();", block_name); + } } #[allow(clippy::too_many_lines)] @@ -553,12 +567,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { match pat.kind { PatKind::Wild => println!("Wild = {};", current), PatKind::Binding(anno, .., ident, ref sub) => { - let anno_pat = match anno { - BindingAnnotation::Unannotated => "BindingAnnotation::Unannotated", - BindingAnnotation::Mutable => "BindingAnnotation::Mutable", - BindingAnnotation::Ref => "BindingAnnotation::Ref", - BindingAnnotation::RefMut => "BindingAnnotation::RefMut", - }; + let anno_pat = &format!("BindingAnnotation::{:?}", anno); let name_pat = self.next("name"); if let Some(sub) = *sub { let sub_pat = self.next("sub"); @@ -723,33 +732,6 @@ fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { get_attr(cx.sess(), attrs, "author").count() > 0 } -#[must_use] -fn desugaring_name(des: hir::MatchSource) -> String { - match des { - hir::MatchSource::ForLoopDesugar => "MatchSource::ForLoopDesugar".to_string(), - hir::MatchSource::TryDesugar => "MatchSource::TryDesugar".to_string(), - hir::MatchSource::WhileDesugar => "MatchSource::WhileDesugar".to_string(), - hir::MatchSource::WhileLetDesugar => "MatchSource::WhileLetDesugar".to_string(), - hir::MatchSource::Normal => "MatchSource::Normal".to_string(), - hir::MatchSource::IfLetDesugar { contains_else_clause } => format!( - "MatchSource::IfLetDesugar {{ contains_else_clause: {} }}", - contains_else_clause - ), - hir::MatchSource::IfLetGuardDesugar => "MatchSource::IfLetGuardDesugar".to_string(), - hir::MatchSource::AwaitDesugar => "MatchSource::AwaitDesugar".to_string(), - } -} - -#[must_use] -fn loop_desugaring_name(des: hir::LoopSource) -> &'static str { - match des { - hir::LoopSource::ForLoop => "LoopSource::ForLoop", - hir::LoopSource::Loop => "LoopSource::Loop", - hir::LoopSource::While => "LoopSource::While", - hir::LoopSource::WhileLet => "LoopSource::WhileLet", - } -} - fn print_path(path: &QPath<'_>, first: &mut bool) { match *path { QPath::Resolved(_, path) => { diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 4665eeeff7b..f7ddee12dcf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -8,10 +8,11 @@ use rustc_session::Session; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Dumps every ast/hir node which has the `#[clippy::dump]` + /// ### What it does + /// Dumps every ast/hir node which has the `#[clippy::dump]` /// attribute /// - /// **Example:** + /// ### Example /// ```rust,ignore /// #[clippy::dump] /// extern crate foo; diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs index 668807f499f..d660008e7d1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs @@ -36,29 +36,33 @@ use std::borrow::{Borrow, Cow}; pub mod metadata_collector; declare_clippy_lint! { - /// **What it does:** Checks for various things we like to keep tidy in clippy. + /// ### What it does + /// Checks for various things we like to keep tidy in clippy. /// - /// **Why is this bad?** We like to pretend we're an example of tidy code. + /// ### Why is this bad? + /// We like to pretend we're an example of tidy code. /// - /// **Known problems:** None. - /// - /// **Example:** Wrong ordering of the util::paths constants. + /// ### Example + /// Wrong ordering of the util::paths constants. pub CLIPPY_LINTS_INTERNAL, internal, "various things that will negatively affect your clippy experience" } declare_clippy_lint! { - /// **What it does:** Ensures every lint is associated to a `LintPass`. + /// ### What it does + /// Ensures every lint is associated to a `LintPass`. /// - /// **Why is this bad?** The compiler only knows lints via a `LintPass`. Without + /// ### Why is this bad? + /// The compiler only knows lints via a `LintPass`. Without /// putting a lint to a `LintPass::get_lints()`'s return, the compiler will not /// know the name of the lint. /// - /// **Known problems:** Only checks for lints associated using the + /// ### Known problems + /// Only checks for lints associated using the /// `declare_lint_pass!`, `impl_lint_pass!`, and `lint_array!` macros. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// declare_lint! { pub LINT_1, ... } /// declare_lint! { pub LINT_2, ... } @@ -73,15 +77,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `cx.span_lint*` and suggests to use the `utils::*` + /// ### What it does + /// Checks for calls to `cx.span_lint*` and suggests to use the `utils::*` /// variant of the function. /// - /// **Why is this bad?** The `utils::*` variants also add a link to the Clippy documentation to the + /// ### Why is this bad? + /// The `utils::*` variants also add a link to the Clippy documentation to the /// warning/error messages. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// cx.span_lint(LINT_NAME, "message"); @@ -97,14 +101,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `cx.outer().expn_data()` and suggests to use + /// ### What it does + /// Checks for calls to `cx.outer().expn_data()` and suggests to use /// the `cx.outer_expn_data()` /// - /// **Why is this bad?** `cx.outer_expn_data()` is faster and more concise. + /// ### Why is this bad? + /// `cx.outer_expn_data()` is faster and more concise. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// expr.span.ctxt().outer().expn_data() @@ -120,14 +124,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Not an actual lint. This lint is only meant for testing our customized internal compiler + /// ### What it does + /// Not an actual lint. This lint is only meant for testing our customized internal compiler /// error message by calling `panic`. /// - /// **Why is this bad?** ICE in large quantities can damage your teeth + /// ### Why is this bad? + /// ICE in large quantities can damage your teeth /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// 🍦🍦🍦🍦🍦 @@ -138,14 +142,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for cases of an auto-generated lint without an updated description, + /// ### What it does + /// Checks for cases of an auto-generated lint without an updated description, /// i.e. `default lint description`. /// - /// **Why is this bad?** Indicates that the lint is not finished. + /// ### Why is this bad? + /// Indicates that the lint is not finished. /// - /// **Known problems:** None - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// declare_lint! { pub COOL_LINT, nursery, "default lint description" } @@ -161,7 +165,8 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Lints `span_lint_and_then` function calls, where the + /// ### What it does + /// Lints `span_lint_and_then` function calls, where the /// closure argument has only one statement and that statement is a method /// call to `span_suggestion`, `span_help`, `span_note` (using the same /// span), `help` or `note`. @@ -170,12 +175,11 @@ declare_clippy_lint! { /// wrapper functions `span_lint_and_sugg`, span_lint_and_help`, or /// `span_lint_and_note`. /// - /// **Why is this bad?** Using the wrapper `span_lint_and_*` functions, is more + /// ### Why is this bad? + /// Using the wrapper `span_lint_and_*` functions, is more /// convenient, readable and less error prone. /// - /// **Known problems:** None - /// - /// *Example:** + /// ### Example /// Bad: /// ```rust,ignore /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| { @@ -222,14 +226,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for calls to `utils::match_type()` on a type diagnostic item + /// ### What it does + /// Checks for calls to `utils::match_type()` on a type diagnostic item /// and suggests to use `utils::is_type_diagnostic_item()` instead. /// - /// **Why is this bad?** `utils::is_type_diagnostic_item()` does not require hardcoded paths. + /// ### Why is this bad? + /// `utils::is_type_diagnostic_item()` does not require hardcoded paths. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// utils::match_type(cx, ty, &paths::VEC) @@ -245,30 +249,27 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks the paths module for invalid paths. /// - /// **Why is this bad?** + /// ### Why is this bad? /// It indicates a bug in the code. /// - /// **Known problems:** None. - /// - /// **Example:** None. + /// ### Example + /// None. pub INVALID_PATHS, internal, "invalid path" } declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// Checks for interning symbols that have already been pre-interned and defined as constants. /// - /// **Why is this bad?** + /// ### Why is this bad? /// It's faster and easier to use the symbol constant. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// let _ = sym!(f32); @@ -284,13 +285,13 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for unnecessary conversion from Symbol to a string. + /// ### What it does + /// Checks for unnecessary conversion from Symbol to a string. /// - /// **Why is this bad?** It's faster use symbols directly intead of strings. + /// ### Why is this bad? + /// It's faster use symbols directly intead of strings. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// Bad: /// ```rust,ignore /// symbol.as_str() == "clippy"; diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs index 3eccc89cdeb..47336459d7d 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -32,7 +32,7 @@ use clippy_utils::{ }; /// This is the output file of the lint collector. -const OUTPUT_FILE: &str = "../util/gh-pages/metadata_collection.json"; +const OUTPUT_FILE: &str = "../util/gh-pages/lints.json"; /// These lints are excluded from the export. const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "internal_metadata_collector"]; /// These groups will be ignored by the lint group matcher. This is useful for collections like @@ -68,7 +68,7 @@ const CLIPPY_LINT_GROUP_PREFIX: &str = "clippy::"; macro_rules! CONFIGURATION_SECTION_TEMPLATE { () => { r#" -**Configuration** +### Configuration This lint has the following configuration variables: {configurations} @@ -114,20 +114,25 @@ const DEPRECATED_LINT_TYPE: [&str; 3] = ["clippy_lints", "deprecated_lints", "Cl /// The index of the applicability name of `paths::APPLICABILITY_VALUES` const APPLICABILITY_NAME_INDEX: usize = 2; +/// This applicability will be set for unresolved applicability values. +const APPLICABILITY_UNRESOLVED_STR: &str = "Unresolved"; declare_clippy_lint! { - /// **What it does:** Collects metadata about clippy lints for the website. + /// ### What it does + /// Collects metadata about clippy lints for the website. /// /// This lint will be used to report problems of syntax parsing. You should hopefully never /// see this but never say never I guess ^^ /// - /// **Why is this bad?** This is not a bad thing but definitely a hacky way to do it. See + /// ### Why is this bad? + /// This is not a bad thing but definitely a hacky way to do it. See /// issue [#4310](https://github.com/rust-lang/rust-clippy/issues/4310) for a discussion /// about the implementation. /// - /// **Known problems:** Hopefully none. It would be pretty uncool to have a problem here :) + /// ### Known problems + /// Hopefully none. It would be pretty uncool to have a problem here :) /// - /// **Example output:** + /// ### Example output /// ```json,ignore /// { /// "id": "internal_metadata_collector", @@ -136,7 +141,7 @@ declare_clippy_lint! { /// "line": 1 /// }, /// "group": "clippy::internal", - /// "docs": " **What it does:** Collects metadata about clippy lints for the website. [...] " + /// "docs": " ### What it does\nCollects metadata about clippy lints for the website. [...] " /// } /// ``` pub INTERNAL_METADATA_COLLECTOR, @@ -192,7 +197,7 @@ impl Drop for MetadataCollector { let mut lints = std::mem::take(&mut self.lints).into_sorted_vec(); lints .iter_mut() - .for_each(|x| x.applicability = applicability_info.remove(&x.id)); + .for_each(|x| x.applicability = Some(applicability_info.remove(&x.id).unwrap_or_default())); // Outputting if Path::new(OUTPUT_FILE).exists() { @@ -208,7 +213,7 @@ struct LintMetadata { id: String, id_span: SerializableSpan, group: String, - level: &'static str, + level: String, docs: String, /// This field is only used in the output and will only be /// mapped shortly before the actual output. @@ -221,7 +226,7 @@ impl LintMetadata { id, id_span, group, - level, + level: level.to_string(), docs, applicability: None, } @@ -269,14 +274,16 @@ impl Serialize for ApplicabilityInfo { where S: Serializer, { - let index = self.applicability.unwrap_or_default(); - let mut s = serializer.serialize_struct("ApplicabilityInfo", 2)?; s.serialize_field("is_multi_part_suggestion", &self.is_multi_part_suggestion)?; - s.serialize_field( - "applicability", - &paths::APPLICABILITY_VALUES[index][APPLICABILITY_NAME_INDEX], - )?; + if let Some(index) = self.applicability { + s.serialize_field( + "applicability", + &paths::APPLICABILITY_VALUES[index][APPLICABILITY_NAME_INDEX], + )?; + } else { + s.serialize_field("applicability", APPLICABILITY_UNRESOLVED_STR)?; + } s.end() } } @@ -374,7 +381,8 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector { /// Collecting lint declarations like: /// ```rust, ignore /// declare_clippy_lint! { - /// /// **What it does:** Something IDK. + /// /// ### What it does + /// /// Something IDK. /// pub SOME_LINT, /// internal, /// "Who am I?" @@ -486,6 +494,13 @@ fn extract_attr_docs_or_lint(cx: &LateContext<'_>, item: &Item<'_>) -> Option, item: &Item<'_>) -> Option { let attrs = cx.tcx.hir().attrs(item.hir_id()); let mut lines = attrs.iter().filter_map(ast::Attribute::doc_str); @@ -510,7 +525,12 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option { continue; } } - docs.push_str(line); + // This removes the leading space that the macro translation introduces + if let Some(stripped_doc) = line.strip_prefix(' ') { + docs.push_str(stripped_doc); + } else if !line.is_empty() { + docs.push_str(line); + } } Some(docs) } diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs index 1d5b7c98d31..32fa46f042c 100644 --- a/src/tools/clippy/clippy_lints/src/vec.rs +++ b/src/tools/clippy/clippy_lints/src/vec.rs @@ -19,14 +19,14 @@ pub struct UselessVec { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would + /// ### What it does + /// Checks for usage of `&vec![..]` when using `&[..]` would /// be possible. /// - /// **Why is this bad?** This is less efficient. + /// ### Why is this bad? + /// This is less efficient. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # fn foo(my_vec: &[u8]) {} /// diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs index c7190e2f979..0413c02b230 100644 --- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs +++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs @@ -13,15 +13,14 @@ use rustc_span::{symbol::sym, Span}; use std::convert::TryInto; declare_clippy_lint! { - /// **What it does:** Checks for calls to `push` immediately after creating a new `Vec`. + /// ### What it does + /// Checks for calls to `push` immediately after creating a new `Vec`. /// - /// **Why is this bad?** The `vec![]` macro is both more performant and easier to read than + /// ### Why is this bad? + /// The `vec![]` macro is both more performant and easier to read than /// multiple `push` calls. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust /// let mut v = Vec::new(); /// v.push(0); diff --git a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs index 5540e87405f..5c0429db6b8 100644 --- a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs @@ -10,13 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; declare_clippy_lint! { - /// **What it does:** Finds occurrences of `Vec::resize(0, an_int)` + /// ### What it does + /// Finds occurrences of `Vec::resize(0, an_int)` /// - /// **Why is this bad?** This is probably an argument inversion mistake. + /// ### Why is this bad? + /// This is probably an argument inversion mistake. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// vec!(1, 2, 3, 4, 5).resize(0, 5) /// ``` diff --git a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs b/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs index 3ab68df2b6d..e07c12f4f16 100644 --- a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs +++ b/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs @@ -7,15 +7,14 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for use of File::read_to_end and File::read_to_string. + /// ### What it does + /// Checks for use of File::read_to_end and File::read_to_string. /// - /// **Why is this bad?** `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values. + /// ### Why is this bad? + /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values. /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html) /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```rust,no_run /// # use std::io::Read; /// # use std::fs::File; diff --git a/src/tools/clippy/clippy_lints/src/wildcard_dependencies.rs b/src/tools/clippy/clippy_lints/src/wildcard_dependencies.rs index 1ca1117a41e..fd3872bacbe 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_dependencies.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_dependencies.rs @@ -7,16 +7,15 @@ use rustc_span::source_map::DUMMY_SP; use if_chain::if_chain; declare_clippy_lint! { - /// **What it does:** Checks for wildcard dependencies in the `Cargo.toml`. + /// ### What it does + /// Checks for wildcard dependencies in the `Cargo.toml`. /// - /// **Why is this bad?** [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html), + /// ### Why is this bad? + /// [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html), /// it is highly unlikely that you work with any possible version of your dependency, /// and wildcard dependencies would cause unnecessary breakage in the ecosystem. /// - /// **Known problems:** None. - /// - /// **Example:** - /// + /// ### Example /// ```toml /// [dependencies] /// regex = "*" diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs index 520586b3a1f..bafb9d3e3b1 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs @@ -13,15 +13,18 @@ use rustc_span::symbol::kw; use rustc_span::{sym, BytePos}; declare_clippy_lint! { - /// **What it does:** Checks for `use Enum::*`. + /// ### What it does + /// Checks for `use Enum::*`. /// - /// **Why is this bad?** It is usually better style to use the prefixed name of + /// ### Why is this bad? + /// It is usually better style to use the prefixed name of /// an enumeration variant, rather than importing variants. /// - /// **Known problems:** Old-style enumerations that prefix the variants are + /// ### Known problems + /// Old-style enumerations that prefix the variants are /// still around. /// - /// **Example:** + /// ### Example /// ```rust,ignore /// // Bad /// use std::cmp::Ordering::*; @@ -37,9 +40,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for wildcard imports `use _::*`. + /// ### What it does + /// Checks for wildcard imports `use _::*`. /// - /// **Why is this bad?** wildcard imports can pollute the namespace. This is especially bad if + /// ### Why is this bad? + /// wildcard imports can pollute the namespace. This is especially bad if /// you try to import something through a wildcard, that already has been imported by name from /// a different source: /// @@ -52,8 +57,7 @@ declare_clippy_lint! { /// /// This can lead to confusing error messages at best and to unexpected behavior at worst. /// - /// **Exceptions:** - /// + /// ### Exceptions /// Wildcard imports are allowed from modules named `prelude`. Many crates (including the standard library) /// provide modules named "prelude" specifically designed for wildcard import. /// @@ -61,14 +65,14 @@ declare_clippy_lint! { /// /// These exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag. /// - /// **Known problems:** If macros are imported through the wildcard, this macro is not included + /// ### Known problems + /// If macros are imported through the wildcard, this macro is not included /// by the suggestion and has to be added by hand. /// /// Applying the suggestion when explicit imports of the things imported with a glob import /// exist, may result in `unused_imports` warnings. /// - /// **Example:** - /// + /// ### Example /// ```rust,ignore /// // Bad /// use crate1::*; diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs index 5229a705865..4553ac704a2 100644 --- a/src/tools/clippy/clippy_lints/src/write.rs +++ b/src/tools/clippy/clippy_lints/src/write.rs @@ -16,14 +16,14 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, Span, DUMMY_SP}; declare_clippy_lint! { - /// **What it does:** This lint warns when you use `println!("")` to + /// ### What it does + /// This lint warns when you use `println!("")` to /// print a newline. /// - /// **Why is this bad?** You should use `println!()`, which is simpler. + /// ### Why is this bad? + /// You should use `println!()`, which is simpler. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// println!(""); @@ -37,15 +37,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint warns when you use `print!()` with a format + /// ### What it does + /// This lint warns when you use `print!()` with a format /// string that ends in a newline. /// - /// **Why is this bad?** You should use `println!()` instead, which appends the + /// ### Why is this bad? + /// You should use `println!()` instead, which appends the /// newline. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # let name = "World"; /// print!("Hello {}!\n", name); @@ -61,15 +61,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for printing on *stdout*. The purpose of this lint + /// ### What it does + /// Checks for printing on *stdout*. The purpose of this lint /// is to catch debugging remnants. /// - /// **Why is this bad?** People often print on *stdout* while debugging an + /// ### Why is this bad? + /// People often print on *stdout* while debugging an /// application and might forget to remove those prints afterward. /// - /// **Known problems:** Only catches `print!` and `println!` calls. + /// ### Known problems + /// Only catches `print!` and `println!` calls. /// - /// **Example:** + /// ### Example /// ```rust /// println!("Hello world!"); /// ``` @@ -79,15 +82,18 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for printing on *stderr*. The purpose of this lint + /// ### What it does + /// Checks for printing on *stderr*. The purpose of this lint /// is to catch debugging remnants. /// - /// **Why is this bad?** People often print on *stderr* while debugging an + /// ### Why is this bad? + /// People often print on *stderr* while debugging an /// application and might forget to remove those prints afterward. /// - /// **Known problems:** Only catches `eprint!` and `eprintln!` calls. + /// ### Known problems + /// Only catches `eprint!` and `eprintln!` calls. /// - /// **Example:** + /// ### Example /// ```rust /// eprintln!("Hello world!"); /// ``` @@ -97,13 +103,15 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for use of `Debug` formatting. The purpose of this + /// ### What it does + /// Checks for use of `Debug` formatting. The purpose of this /// lint is to catch debugging remnants. /// - /// **Why is this bad?** The purpose of the `Debug` trait is to facilitate + /// ### Why is this bad? + /// The purpose of the `Debug` trait is to facilitate /// debugging Rust code. It should not be used in user-facing output. /// - /// **Example:** + /// ### Example /// ```rust /// # let foo = "bar"; /// println!("{:?}", foo); @@ -114,16 +122,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint warns about the use of literals as `print!`/`println!` args. + /// ### What it does + /// This lint warns about the use of literals as `print!`/`println!` args. /// - /// **Why is this bad?** Using literals as `println!` args is inefficient + /// ### Why is this bad? + /// Using literals as `println!` args is inefficient /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary /// (i.e., just put the literal in the format string) /// - /// **Known problems:** Will also warn with macro calls as arguments that expand to literals + /// ### Known problems + /// Will also warn with macro calls as arguments that expand to literals /// -- e.g., `println!("{}", env!("FOO"))`. /// - /// **Example:** + /// ### Example /// ```rust /// println!("{}", "foo"); /// ``` @@ -137,14 +148,14 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint warns when you use `writeln!(buf, "")` to + /// ### What it does + /// This lint warns when you use `writeln!(buf, "")` to /// print a newline. /// - /// **Why is this bad?** You should use `writeln!(buf)`, which is simpler. + /// ### Why is this bad? + /// You should use `writeln!(buf)`, which is simpler. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::fmt::Write; /// # let mut buf = String::new(); @@ -160,16 +171,16 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint warns when you use `write!()` with a format + /// ### What it does + /// This lint warns when you use `write!()` with a format /// string that /// ends in a newline. /// - /// **Why is this bad?** You should use `writeln!()` instead, which appends the + /// ### Why is this bad? + /// You should use `writeln!()` instead, which appends the /// newline. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// # use std::fmt::Write; /// # let mut buf = String::new(); @@ -186,16 +197,19 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** This lint warns about the use of literals as `write!`/`writeln!` args. + /// ### What it does + /// This lint warns about the use of literals as `write!`/`writeln!` args. /// - /// **Why is this bad?** Using literals as `writeln!` args is inefficient + /// ### Why is this bad? + /// Using literals as `writeln!` args is inefficient /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary /// (i.e., just put the literal in the format string) /// - /// **Known problems:** Will also warn with macro calls as arguments that expand to literals + /// ### Known problems + /// Will also warn with macro calls as arguments that expand to literals /// -- e.g., `writeln!(buf, "{}", env!("FOO"))`. /// - /// **Example:** + /// ### Example /// ```rust /// # use std::fmt::Write; /// # let mut buf = String::new(); diff --git a/src/tools/clippy/clippy_lints/src/zero_div_zero.rs b/src/tools/clippy/clippy_lints/src/zero_div_zero.rs index a1ea743ba80..b29ced28ac4 100644 --- a/src/tools/clippy/clippy_lints/src/zero_div_zero.rs +++ b/src/tools/clippy/clippy_lints/src/zero_div_zero.rs @@ -6,13 +6,13 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for `0.0 / 0.0`. + /// ### What it does + /// Checks for `0.0 / 0.0`. /// - /// **Why is this bad?** It's less readable than `f32::NAN` or `f64::NAN`. + /// ### Why is this bad? + /// It's less readable than `f32::NAN` or `f64::NAN`. /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Example /// ```rust /// // Bad /// let nan = 0.0f32 / 0.0; diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 053bbc9aea6..2fbe27f9479 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::paths; -use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item, match_type}; +use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item}; use if_chain::if_chain; use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; @@ -11,18 +10,19 @@ use rustc_target::abi::LayoutOf as _; use rustc_typeck::hir_ty_to_ty; declare_clippy_lint! { - /// **What it does:** Checks for maps with zero-sized value types anywhere in the code. + /// ### What it does + /// Checks for maps with zero-sized value types anywhere in the code. /// - /// **Why is this bad?** Since there is only a single value for a zero-sized type, a map + /// ### Why is this bad? + /// Since there is only a single value for a zero-sized type, a map /// containing zero sized values is effectively a set. Using a set in that case improves /// readability and communicates intent more clearly. /// - /// **Known problems:** + /// ### Known problems /// * A zero-sized type cannot be recovered later if it contains private fields. /// * This lints the signature of public items /// - /// **Example:** - /// + /// ### Example /// ```rust /// # use std::collections::HashMap; /// fn unique_words(text: &str) -> HashMap<&str, ()> { @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { if !hir_ty.span.from_expansion(); if !in_trait_impl(cx, hir_ty.hir_id); let ty = ty_from_hir_ty(cx, hir_ty); - if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP); + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || is_type_diagnostic_item(cx, ty, sym::BTreeMap); if let Adt(_, substs) = ty.kind(); let ty = substs.type_at(1); // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml index 6ede9011208..8bd859c97ad 100644 --- a/src/tools/clippy/clippy_utils/Cargo.toml +++ b/src/tools/clippy/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.55" +version = "0.1.56" authors = ["The Rust Clippy Developers"] edition = "2018" publish = false diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 6ea360a88a6..fd70553e064 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -288,8 +288,7 @@ impl HirEqInterExpr<'_, '_, '_> { (GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body), (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt), (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty), - (GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => - self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()), + (GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 00db52a9457..59f878f8b20 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -72,7 +72,7 @@ use rustc_hir::LangItem::{ResultErr, ResultOk}; use rustc_hir::{ def, Arm, BindingAnnotation, Block, Body, Constness, Destination, Expr, ExprKind, FnDecl, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Node, Param, Pat, PatKind, Path, - PathSegment, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp, + PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp, }; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::exports::Export; @@ -411,12 +411,22 @@ pub fn is_qpath_def_path(cx: &LateContext<'_>, path: &QPath<'_>, hir_id: HirId, } /// If the expression is a path, resolves it to a `DefId` and checks if it matches the given path. +/// +/// Please use `is_expr_diagnostic_item` if the target is a diagnostic item. pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[&str]) -> bool { expr_path_res(cx, expr) .opt_def_id() .map_or(false, |id| match_def_path(cx, id, segments)) } +/// If the expression is a path, resolves it to a `DefId` and checks if it matches the given +/// diagnostic item. +pub fn is_expr_diagnostic_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool { + expr_path_res(cx, expr) + .opt_def_id() + .map_or(false, |id| cx.tcx.is_diagnostic_item(diag_item, id)) +} + /// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the /// entire path or resolved `DefId`. Prefer using `match_def_path`. Consider getting a `DefId` from /// `QPath::Resolved.1.res.opt_def_id()`. @@ -480,6 +490,9 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res { let (krate, first, path) = match *path { [krate, first, ref path @ ..] => (krate, first, path), + [primitive] => { + return PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy); + }, _ => return Res::Err, }; let tcx = cx.tcx; @@ -1231,6 +1244,8 @@ pub fn match_function_call<'tcx>( /// Checks if the given `DefId` matches any of the paths. Returns the index of matching path, if /// any. +/// +/// Please use `match_any_diagnostic_items` if the targets are all diagnostic items. pub fn match_any_def_paths(cx: &LateContext<'_>, did: DefId, paths: &[&[&str]]) -> Option { let search_path = cx.get_def_path(did); paths @@ -1238,6 +1253,14 @@ pub fn match_any_def_paths(cx: &LateContext<'_>, did: DefId, paths: &[&[&str]]) .position(|p| p.iter().map(|x| Symbol::intern(x)).eq(search_path.iter().copied())) } +/// Checks if the given `DefId` matches any of provided diagnostic items. Returns the index of +/// matching path, if any. +pub fn match_any_diagnostic_items(cx: &LateContext<'_>, def_id: DefId, diag_items: &[Symbol]) -> Option { + diag_items + .iter() + .position(|item| cx.tcx.is_diagnostic_item(*item, def_id)) +} + /// Checks if the given `DefId` matches the path. pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool { // We should probably move to Symbols in Clippy as well rather than interning every time. diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index c960eec3064..b0c3fe1e5a7 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -21,21 +21,19 @@ pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"]; pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; -pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"]; +/// Preferably use the diagnostic item `sym::Borrow` where possible pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; -pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"]; pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"]; pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"]; pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"]; -pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"]; pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"]; pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"]; pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"]; pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"]; -pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; +/// Preferably use the diagnostic item `sym::deref_method` where possible pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; pub const DIR_BUILDER: [&str; 3] = ["std", "fs", "DirBuilder"]; pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"]; @@ -55,11 +53,9 @@ pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect" pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"]; pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"]; pub const HASH: [&str; 3] = ["core", "hash", "Hash"]; -pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"]; pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"]; pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"]; pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"]; -pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"]; #[cfg(feature = "internal-lints")] pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; #[cfg(feature = "internal-lints")] @@ -67,8 +63,6 @@ pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const INDEX: [&str; 3] = ["core", "ops", "Index"]; pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"]; pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"]; -pub const INTO: [&str; 3] = ["core", "convert", "Into"]; -pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"]; pub const IO_READ: [&str; 3] = ["std", "io", "Read"]; pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"]; pub const IPADDR_V4: [&str; 5] = ["std", "net", "ip", "IpAddr", "V4"]; @@ -79,7 +73,6 @@ pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"]; #[cfg(feature = "internal-lints")] pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; pub const LIBC_STRLEN: [&str; 2] = ["libc", "strlen"]; -pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"]; #[cfg(any(feature = "internal-lints", feature = "metadata-collector-lint"))] pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"]; @@ -93,6 +86,7 @@ pub const MEM_SIZE_OF_VAL: [&str; 3] = ["core", "mem", "size_of_val"]; pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"]; pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"]; pub const OPS_MODULE: [&str; 2] = ["core", "ops"]; +/// Preferably use the diagnostic item `sym::option_type` where possible pub const OPTION: [&str; 3] = ["core", "option", "Option"]; pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"]; pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"]; @@ -116,8 +110,6 @@ pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"]; pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"]; pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"]; pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"]; -pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"]; -pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"]; pub const PTR_SLICE_FROM_RAW_PARTS: [&str; 3] = ["core", "ptr", "slice_from_raw_parts"]; pub const PTR_SLICE_FROM_RAW_PARTS_MUT: [&str; 3] = ["core", "ptr", "slice_from_raw_parts_mut"]; pub const PTR_SWAP_NONOVERLAPPING: [&str; 3] = ["core", "ptr", "swap_nonoverlapping"]; @@ -141,6 +133,7 @@ pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"]; pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"]; pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"]; pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"]; +/// Preferably use the diagnostic item `sym::result_type` where possible pub const RESULT: [&str; 3] = ["core", "result", "Result"]; pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"]; pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"]; @@ -176,16 +169,11 @@ pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"]; pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"]; pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"]; -pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"]; pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"]; -pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"]; -pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"]; pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"]; pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"]; -pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"]; pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"]; pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"]; pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"]; pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"]; pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; -pub const WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"]; diff --git a/src/tools/clippy/doc/adding_lints.md b/src/tools/clippy/doc/adding_lints.md index 5a06afedbf4..f2260c3d1a2 100644 --- a/src/tools/clippy/doc/adding_lints.md +++ b/src/tools/clippy/doc/adding_lints.md @@ -11,6 +11,7 @@ because that's clearly a non-descriptive name. - [Setup](#setup) - [Getting Started](#getting-started) - [Testing](#testing) + - [Cargo lints](#cargo-lints) - [Rustfix tests](#rustfix-tests) - [Edition 2018 tests](#edition-2018-tests) - [Testing manually](#testing-manually) @@ -179,14 +180,11 @@ the auto-generated lint declaration to have a real description, something like t ```rust declare_clippy_lint! { - /// **What it does:** + /// ### What it does /// - /// **Why is this bad?** - /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? /// + /// ### Example /// ```rust /// // example code /// ``` @@ -487,13 +485,13 @@ Please document your lint with a doc comment akin to the following: ```rust 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,ignore /// // Bad diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain index 3a2005e7872..bff657bc110 100644 --- a/src/tools/clippy/rust-toolchain +++ b/src/tools/clippy/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-07-19" +channel = "nightly-2021-07-29" components = ["llvm-tools-preview", "rustc-dev", "rust-src"] diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs index 6bd4123ddeb..7589f42a7b4 100644 --- a/src/tools/clippy/src/main.rs +++ b/src/tools/clippy/src/main.rs @@ -14,6 +14,8 @@ Usage: cargo clippy [options] [--] [...] Common options: + --no-deps Run Clippy only on the given crate, without linting the dependencies + --fix Automatically apply lint suggestions. This flag implies `--no-deps` -h, --help Print this message -V, --version Print version info and exit @@ -71,6 +73,7 @@ impl ClippyCmd { { let mut cargo_subcommand = "check"; let mut args = vec![]; + let mut clippy_args: Vec = vec![]; for arg in old_args.by_ref() { match arg.as_str() { @@ -78,6 +81,10 @@ impl ClippyCmd { cargo_subcommand = "fix"; continue; }, + "--no-deps" => { + clippy_args.push("--no-deps".into()); + continue; + }, "--" => break, _ => {}, } @@ -85,7 +92,7 @@ impl ClippyCmd { args.push(arg); } - let mut clippy_args: Vec = old_args.collect(); + clippy_args.append(&mut (old_args.collect())); if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { clippy_args.push("--no-deps".into()); } diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index caa19e39ccd..0a82377a10e 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -1,5 +1,6 @@ #![feature(test)] // compiletest_rs requires this attribute #![feature(once_cell)] +#![feature(try_blocks)] use compiletest_rs as compiletest; use compiletest_rs::common::Mode as TestMode; @@ -34,50 +35,60 @@ fn clippy_driver_path() -> PathBuf { // as what we manually pass to `cargo` invocation fn third_party_crates() -> String { use std::collections::HashMap; - static CRATES: &[&str] = &["serde", "serde_derive", "regex", "clippy_lints", "syn", "quote"]; + static CRATES: &[&str] = &[ + "clippy_lints", + "clippy_utils", + "if_chain", + "quote", + "regex", + "serde", + "serde_derive", + "syn", + ]; let dep_dir = cargo::TARGET_LIB.join("deps"); - let mut crates: HashMap<&str, PathBuf> = HashMap::with_capacity(CRATES.len()); - for entry in fs::read_dir(dep_dir).unwrap() { - let path = match entry { - Ok(entry) => entry.path(), - Err(_) => continue, - }; - if let Some(name) = path.file_name().and_then(OsStr::to_str) { - for dep in CRATES { - if name.starts_with(&format!("lib{}-", dep)) - && name.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rlib")) == Some(true) - { - if let Some(old) = crates.insert(dep, path.clone()) { - // Check which action should be done in order to remove compiled deps. - // If pre-installed version of compiler is used, `cargo clean` will do. - // Otherwise (for bootstrapped compiler), the dependencies directory - // must be removed manually. - let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { - "remove the stageN-tools directory" - } else { - "run `cargo clean`" - }; - - panic!( - "\n---------------------------------------------------\n\n \ - Found multiple rlibs for crate `{}`: `{:?}` and `{:?}`.\n \ - Probably, you need to {} before running tests again.\n \ - \nFor details on that error see https://github.com/rust-lang/rust-clippy/issues/7343 \ - \n---------------------------------------------------\n", - dep, old, path, suggested_action - ); - } - break; - } - } + let mut crates: HashMap<&str, Vec> = HashMap::with_capacity(CRATES.len()); + let mut flags = String::new(); + for entry in fs::read_dir(dep_dir).unwrap().flatten() { + let path = entry.path(); + if let Some(name) = try { + let name = path.file_name()?.to_str()?; + let (name, _) = name.strip_suffix(".rlib")?.strip_prefix("lib")?.split_once('-')?; + CRATES.iter().copied().find(|&c| c == name)? + } { + flags += &format!(" --extern {}={}", name, path.display()); + crates.entry(name).or_default().push(path.clone()); } } + crates.retain(|_, paths| paths.len() > 1); + if !crates.is_empty() { + let crate_names = crates.keys().map(|s| format!("`{}`", s)).collect::>().join(", "); + // add backslashes for an easy copy-paste `rm` command + let paths = crates + .into_values() + .flatten() + .map(|p| strip_current_dir(&p).display().to_string()) + .collect::>() + .join(" \\\n"); + // Check which action should be done in order to remove compiled deps. + // If pre-installed version of compiler is used, `cargo clean` will do. + // Otherwise (for bootstrapped compiler), the dependencies directory + // must be removed manually. + let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { + "removing the stageN-tools directory" + } else { + "running `cargo clean`" + }; - let v: Vec<_> = crates - .into_iter() - .map(|(dep, path)| format!("--extern {}={}", dep, path.display())) - .collect(); - v.join(" ") + panic!( + "\n----------------------------------------------------------------------\n\ + ERROR: Found multiple rlibs for crates: {}\n\ + Try {} or remove the following files:\n\n{}\n\n\ + For details on this error see https://github.com/rust-lang/rust-clippy/issues/7343\n\ + ----------------------------------------------------------------------\n", + crate_names, suggested_action, paths + ); + } + flags } fn default_config() -> compiletest::Config { @@ -304,3 +315,12 @@ impl Drop for VarGuard { } } } + +fn strip_current_dir(path: &Path) -> &Path { + if let Ok(curr) = env::current_dir() { + if let Ok(stripped) = path.strip_prefix(curr) { + return stripped; + } + } + path +} diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index 7de130c7dbe..4ede20c5258 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -76,8 +76,8 @@ fn test_no_deps_ignores_path_deps_in_workspaces() { .env("CARGO_INCREMENTAL", "0") .arg("clippy") .args(&["-p", "subcrate"]) - .arg("--") .arg("--no-deps") + .arg("--") .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir .args(&["--cfg", r#"feature="primary_package_test""#]) .output() @@ -183,7 +183,7 @@ fn run_metadata_collection_lint() { use std::time::SystemTime; // Setup for validation - let metadata_output_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("util/gh-pages/metadata_collection.json"); + let metadata_output_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("util/gh-pages/lints.json"); let start_time = SystemTime::now(); // Run collection as is diff --git a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs index 063f0c6460c..be7b7a9af19 100644 --- a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs +++ b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs @@ -27,7 +27,6 @@ impl<'tcx> LateLintPass<'tcx> for Pass { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) { let ty = cx.typeck_results().expr_ty(expr); - let _ = match_type(cx, ty, &paths::VEC); // FIXME: Doesn't lint external paths let _ = match_type(cx, ty, &OPTION); let _ = match_type(cx, ty, &["core", "result", "Result"]); diff --git a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr index 71472960565..f5d92fc615c 100644 --- a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr +++ b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr @@ -1,5 +1,5 @@ error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item - --> $DIR/match_type_on_diag_item.rs:31:17 + --> $DIR/match_type_on_diag_item.rs:30:17 | LL | let _ = match_type(cx, ty, &OPTION); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::option_type)` @@ -12,13 +12,13 @@ LL | #![deny(clippy::internal)] = note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]` error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item - --> $DIR/match_type_on_diag_item.rs:32:17 + --> $DIR/match_type_on_diag_item.rs:31:17 | LL | let _ = match_type(cx, ty, &["core", "result", "Result"]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::result_type)` error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item - --> $DIR/match_type_on_diag_item.rs:35:17 + --> $DIR/match_type_on_diag_item.rs:34:17 | LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)` diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml index 2eff854c22c..dac4446703b 100644 --- a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml +++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml @@ -6,4 +6,6 @@ disallowed-types = [ "std::thread::Thread", "std::time::Instant", "std::io::Read", + "std::primitive::usize", + "bool" ] diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs index 567afb5aec1..0871a3073ab 100644 --- a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs +++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs @@ -13,13 +13,15 @@ fn bad_return_type() -> fn() -> Sneaky { todo!() } -fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) { - todo!() -} +fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} -fn trait_obj(_: &dyn std::io::Read) { - todo!() -} +fn trait_obj(_: &dyn std::io::Read) {} + +fn full_and_single_path_prim(_: usize, _: bool) {} + +fn const_generics() {} + +struct GenArg([u8; U]); static BAD: foo::atomic::AtomicPtr<()> = foo::atomic::AtomicPtr::new(std::ptr::null_mut()); @@ -32,4 +34,5 @@ fn main() { let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default(); let _ = syn::Ident::new("", todo!()); let _ = HashMap; + let _: usize = 64_usize; } diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr index 4e6fd91fba1..90ce7db2cc4 100644 --- a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr +++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr @@ -21,68 +21,98 @@ LL | fn bad_return_type() -> fn() -> Sneaky { error: `std::time::Instant` is not allowed according to config --> $DIR/conf_disallowed_type.rs:16:28 | -LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) { +LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} | ^^^^^^ error: `std::sync::atomic::AtomicU32` is not allowed according to config --> $DIR/conf_disallowed_type.rs:16:39 | -LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) { +LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} | ^^^^^^^^^^^^^^^^^^^^^^ error: `std::io::Read` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:20:22 + --> $DIR/conf_disallowed_type.rs:18:22 | -LL | fn trait_obj(_: &dyn std::io::Read) { +LL | fn trait_obj(_: &dyn std::io::Read) {} | ^^^^^^^^^^^^^ +error: `usize` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:20:33 + | +LL | fn full_and_single_path_prim(_: usize, _: bool) {} + | ^^^^^ + +error: `bool` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:20:43 + | +LL | fn full_and_single_path_prim(_: usize, _: bool) {} + | ^^^^ + +error: `usize` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:22:28 + | +LL | fn const_generics() {} + | ^^^^^ + +error: `usize` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:24:24 + | +LL | struct GenArg([u8; U]); + | ^^^^^ + error: `std::collections::HashMap` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:28:48 + --> $DIR/conf_disallowed_type.rs:30:48 | LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `std::collections::HashMap` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:28:12 + --> $DIR/conf_disallowed_type.rs:30:12 | LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `std::time::Instant` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:29:13 + --> $DIR/conf_disallowed_type.rs:31:13 | LL | let _ = Sneaky::now(); | ^^^^^^ error: `std::sync::atomic::AtomicU32` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:30:13 + --> $DIR/conf_disallowed_type.rs:32:13 | LL | let _ = foo::atomic::AtomicU32::new(0); | ^^^^^^^^^^^^^^^^^^^^^^ error: `std::sync::atomic::AtomicU32` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:31:17 + --> $DIR/conf_disallowed_type.rs:33:17 | LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `std::sync::atomic::AtomicU32` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:31:48 + --> $DIR/conf_disallowed_type.rs:33:48 | LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1); | ^^^^^^^^^^^^^^^^^^^^^^ error: `syn::TypePath` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:32:43 + --> $DIR/conf_disallowed_type.rs:34:43 | LL | let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default(); | ^^^^^^^^^^^^^ -error: `proc_macro2::Ident` is not allowed according to config - --> $DIR/conf_disallowed_type.rs:33:13 +error: `syn::Ident` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:35:13 | LL | let _ = syn::Ident::new("", todo!()); | ^^^^^^^^^^ -error: aborting due to 14 previous errors +error: `usize` is not allowed according to config + --> $DIR/conf_disallowed_type.rs:37:12 + | +LL | let _: usize = 64_usize; + | ^^^^^ + +error: aborting due to 19 previous errors diff --git a/src/tools/clippy/tests/ui/author/blocks.rs b/src/tools/clippy/tests/ui/author/blocks.rs index a8068436b70..c8465cd59aa 100644 --- a/src/tools/clippy/tests/ui/author/blocks.rs +++ b/src/tools/clippy/tests/ui/author/blocks.rs @@ -1,16 +1,15 @@ -#![feature(stmt_expr_attributes)] #![allow(redundant_semicolons, clippy::no_effect)] #[rustfmt::skip] fn main() { #[clippy::author] { - ;;;; - } -} - -#[clippy::author] -fn foo() { - let x = 42i32; - -x; + let x = 42i32; + -x; + }; + #[clippy::author] + { + let expr = String::new(); + drop(expr) + }; } diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout index c8ef75e48fc..854bc28083a 100644 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ b/src/tools/clippy/tests/ui/author/blocks.stdout @@ -1,12 +1,39 @@ if_chain! { if let ExprKind::Block(ref block) = expr.kind; - if let Some(trailing_expr) = &block.expr; - if block.stmts.len() == 0; + if block.stmts.len() == 2; + if let StmtKind::Local(ref local) = block.stmts[0].kind; + if let Some(ref init) = local.init; + if let ExprKind::Lit(ref lit) = init.kind; + if let LitKind::Int(42, _) = lit.node; + if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; + if name.as_str() == "x"; + if let StmtKind::Semi(ref e, _) = block.stmts[1].kind + if let ExprKind::Unary(UnOp::Neg, ref inner) = e.kind; + if let ExprKind::Path(ref path) = inner.kind; + if match_qpath(path, &["x"]); + if block.expr.is_none(); then { // report your lint here } } if_chain! { + if let ExprKind::Block(ref block) = expr.kind; + if block.stmts.len() == 1; + if let StmtKind::Local(ref local) = block.stmts[0].kind; + if let Some(ref init) = local.init; + if let ExprKind::Call(ref func, ref args) = init.kind; + if let ExprKind::Path(ref path) = func.kind; + if match_qpath(path, &["String", "new"]); + if args.len() == 0; + if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; + if name.as_str() == "expr"; + if let Some(trailing_expr) = &block.expr; + if let ExprKind::Call(ref func1, ref args1) = trailing_expr.kind; + if let ExprKind::Path(ref path1) = func1.kind; + if match_qpath(path1, &["drop"]); + if args1.len() == 1; + if let ExprKind::Path(ref path2) = args1[0].kind; + if match_qpath(path2, &["expr"]); then { // report your lint here } diff --git a/src/tools/clippy/tests/ui/author/for_loop.stdout b/src/tools/clippy/tests/ui/author/for_loop.stdout index 3bf7607c62f..f1b4d4e096e 100644 --- a/src/tools/clippy/tests/ui/author/for_loop.stdout +++ b/src/tools/clippy/tests/ui/author/for_loop.stdout @@ -11,7 +11,6 @@ if_chain! { // unimplemented: field checks if arms.len() == 1; if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind; - if let Some(trailing_expr) = &body.expr; if body.stmts.len() == 4; if let StmtKind::Local(ref local) = body.stmts[0].kind; if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.kind; @@ -48,7 +47,6 @@ if_chain! { if name1.as_str() == "y"; if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind if let ExprKind::Block(ref block) = e1.kind; - if let Some(trailing_expr1) = &block.expr; if block.stmts.len() == 1; if let StmtKind::Local(ref local2) = block.stmts[0].kind; if let Some(ref init1) = local2.init; @@ -56,6 +54,8 @@ if_chain! { if match_qpath(path9, &["y"]); if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.kind; if name2.as_str() == "z"; + if block.expr.is_none(); + if body.expr.is_none(); if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pat.kind; if name3.as_str() == "iter"; then { diff --git a/src/tools/clippy/tests/ui/author/if.stdout b/src/tools/clippy/tests/ui/author/if.stdout index cac64a3f40b..502b38545b8 100644 --- a/src/tools/clippy/tests/ui/author/if.stdout +++ b/src/tools/clippy/tests/ui/author/if.stdout @@ -3,7 +3,6 @@ if_chain! { if let Some(ref init) = local.init; if let ExprKind::If(ref cond, ref then, Some(ref else_)) = init.kind; if let ExprKind::Block(ref block) = else_.kind; - if let Some(trailing_expr) = &block.expr; if block.stmts.len() == 1; if let StmtKind::Semi(ref e, _) = block.stmts[0].kind if let ExprKind::Binary(ref op, ref left, ref right) = e.kind; @@ -12,10 +11,10 @@ if_chain! { if let LitKind::Int(2, _) = lit.node; if let ExprKind::Lit(ref lit1) = right.kind; if let LitKind::Int(2, _) = lit1.node; + if block.expr.is_none(); if let ExprKind::Lit(ref lit2) = cond.kind; if let LitKind::Bool(true) = lit2.node; if let ExprKind::Block(ref block1) = then.kind; - if let Some(trailing_expr1) = &block1.expr; if block1.stmts.len() == 1; if let StmtKind::Semi(ref e1, _) = block1.stmts[0].kind if let ExprKind::Binary(ref op1, ref left1, ref right1) = e1.kind; @@ -24,6 +23,7 @@ if_chain! { if let LitKind::Int(1, _) = lit3.node; if let ExprKind::Lit(ref lit4) = right1.kind; if let LitKind::Int(1, _) = lit4.node; + if block1.expr.is_none(); if let PatKind::Wild = local.pat.kind; then { // report your lint here diff --git a/src/tools/clippy/tests/ui/author/matches.stdout b/src/tools/clippy/tests/ui/author/matches.stdout index 2e8f8227dca..68cc2b214eb 100644 --- a/src/tools/clippy/tests/ui/author/matches.stdout +++ b/src/tools/clippy/tests/ui/author/matches.stdout @@ -11,7 +11,6 @@ if_chain! { if let ExprKind::Lit(ref lit2) = lit_expr.kind; if let LitKind::Int(16, _) = lit2.node; if let ExprKind::Block(ref block) = arms[1].body.kind; - if let Some(trailing_expr) = &block.expr; if block.stmts.len() == 1; if let StmtKind::Local(ref local1) = block.stmts[0].kind; if let Some(ref init1) = local1.init; @@ -19,6 +18,9 @@ if_chain! { if let LitKind::Int(3, _) = lit3.node; if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind; if name.as_str() == "x"; + if let Some(trailing_expr) = &block.expr; + if let ExprKind::Path(ref path) = trailing_expr.kind; + if match_qpath(path, &["x"]); if let PatKind::Lit(ref lit_expr1) = arms[1].pat.kind if let ExprKind::Lit(ref lit4) = lit_expr1.kind; if let LitKind::Int(17, _) = lit4.node; diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.fixed b/src/tools/clippy/tests/ui/extend_with_drain.fixed similarity index 96% rename from src/tools/clippy/tests/ui/append_instead_of_extend.fixed rename to src/tools/clippy/tests/ui/extend_with_drain.fixed index 283358333cd..00170e649e2 100644 --- a/src/tools/clippy/tests/ui/append_instead_of_extend.fixed +++ b/src/tools/clippy/tests/ui/extend_with_drain.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::append_instead_of_extend)] +#![warn(clippy::extend_with_drain)] use std::collections::BinaryHeap; fn main() { //gets linted diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.rs b/src/tools/clippy/tests/ui/extend_with_drain.rs similarity index 96% rename from src/tools/clippy/tests/ui/append_instead_of_extend.rs rename to src/tools/clippy/tests/ui/extend_with_drain.rs index abde5cdac5c..d76458c3289 100644 --- a/src/tools/clippy/tests/ui/append_instead_of_extend.rs +++ b/src/tools/clippy/tests/ui/extend_with_drain.rs @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::append_instead_of_extend)] +#![warn(clippy::extend_with_drain)] use std::collections::BinaryHeap; fn main() { //gets linted diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.stderr b/src/tools/clippy/tests/ui/extend_with_drain.stderr similarity index 77% rename from src/tools/clippy/tests/ui/append_instead_of_extend.stderr rename to src/tools/clippy/tests/ui/extend_with_drain.stderr index 9d309d981de..57f344716a1 100644 --- a/src/tools/clippy/tests/ui/append_instead_of_extend.stderr +++ b/src/tools/clippy/tests/ui/extend_with_drain.stderr @@ -1,19 +1,19 @@ error: use of `extend` instead of `append` for adding the full range of a second vector - --> $DIR/append_instead_of_extend.rs:9:5 + --> $DIR/extend_with_drain.rs:9:5 | LL | vec2.extend(vec1.drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec2.append(&mut vec1)` | - = note: `-D clippy::append-instead-of-extend` implied by `-D warnings` + = note: `-D clippy::extend-with-drain` implied by `-D warnings` error: use of `extend` instead of `append` for adding the full range of a second vector - --> $DIR/append_instead_of_extend.rs:14:5 + --> $DIR/extend_with_drain.rs:14:5 | LL | vec4.extend(vec3.drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec4.append(&mut vec3)` error: use of `extend` instead of `append` for adding the full range of a second vector - --> $DIR/append_instead_of_extend.rs:18:5 + --> $DIR/extend_with_drain.rs:18:5 | LL | vec11.extend(return_vector().drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec11.append(&mut return_vector())` diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed index 5917ffc3e12..639eac8b8b3 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed @@ -7,7 +7,7 @@ clippy::no_effect, clippy::if_same_then_else, clippy::needless_return, - clippy::self_named_constructor + clippy::self_named_constructors )] use std::cell::Cell; diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.rs b/src/tools/clippy/tests/ui/needless_bool/fixable.rs index d26dcb9fcc3..a3ce086a1c9 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.rs +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.rs @@ -7,7 +7,7 @@ clippy::no_effect, clippy::if_same_then_else, clippy::needless_return, - clippy::self_named_constructor + clippy::self_named_constructors )] use std::cell::Cell; diff --git a/src/tools/clippy/tests/ui/needless_continue.rs b/src/tools/clippy/tests/ui/needless_continue.rs index 5da95647f2c..83ee27f4887 100644 --- a/src/tools/clippy/tests/ui/needless_continue.rs +++ b/src/tools/clippy/tests/ui/needless_continue.rs @@ -51,6 +51,34 @@ fn main() { } } +fn simple_loop() { + loop { + continue; // should lint here + } +} + +fn simple_loop2() { + loop { + println!("bleh"); + continue; // should lint here + } +} + +#[rustfmt::skip] +fn simple_loop3() { + loop { + continue // should lint here + } +} + +#[rustfmt::skip] +fn simple_loop4() { + loop { + println!("bleh"); + continue // should lint here + } +} + mod issue_2329 { fn condition() -> bool { unimplemented!() diff --git a/src/tools/clippy/tests/ui/needless_continue.stderr b/src/tools/clippy/tests/ui/needless_continue.stderr index 8d6a37df960..22b86f25e8f 100644 --- a/src/tools/clippy/tests/ui/needless_continue.stderr +++ b/src/tools/clippy/tests/ui/needless_continue.stderr @@ -54,8 +54,40 @@ LL | | } println!("Jabber"); } +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:56:9 + | +LL | continue; // should lint here + | ^^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:63:9 + | +LL | continue; // should lint here + | ^^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:70:9 + | +LL | continue // should lint here + | ^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:78:9 + | +LL | continue // should lint here + | ^^^^^^^^ + | + = help: consider dropping the `continue` expression + error: this `else` block is redundant - --> $DIR/needless_continue.rs:100:24 + --> $DIR/needless_continue.rs:128:24 | LL | } else { | ________________________^ @@ -78,7 +110,7 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> $DIR/needless_continue.rs:106:17 + --> $DIR/needless_continue.rs:134:17 | LL | / if condition() { LL | | continue; // should lint here @@ -95,5 +127,5 @@ LL | | } println!("bar-5"); } -error: aborting due to 4 previous errors +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs index 58094646b50..4b2e7444dcf 100644 --- a/src/tools/clippy/tests/ui/new_without_default.rs +++ b/src/tools/clippy/tests/ui/new_without_default.rs @@ -173,4 +173,16 @@ impl BarGenerics { } } +pub mod issue7220 { + pub struct Foo { + _bar: *mut T, + } + + impl Foo { + pub fn new() -> Self { + todo!() + } + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr index 56c5fe1c618..7c964000807 100644 --- a/src/tools/clippy/tests/ui/new_without_default.stderr +++ b/src/tools/clippy/tests/ui/new_without_default.stderr @@ -7,7 +7,7 @@ LL | | } | |_____^ | = note: `-D clippy::new-without-default` implied by `-D warnings` -help: try this +help: try adding this | LL | impl Default for Foo { LL | fn default() -> Self { @@ -24,7 +24,7 @@ LL | | Bar LL | | } | |_____^ | -help: try this +help: try adding this | LL | impl Default for Bar { LL | fn default() -> Self { @@ -41,7 +41,7 @@ LL | | unimplemented!() LL | | } | |_____^ | -help: try this +help: try adding this | LL | impl<'c> Default for LtKo<'c> { LL | fn default() -> Self { @@ -58,7 +58,7 @@ LL | | NewNotEqualToDerive { foo: 1 } LL | | } | |_____^ | -help: try this +help: try adding this | LL | impl Default for NewNotEqualToDerive { LL | fn default() -> Self { @@ -75,7 +75,7 @@ LL | | Self(Default::default()) LL | | } | |_____^ | -help: try this +help: try adding this | LL | impl Default for FooGenerics { LL | fn default() -> Self { @@ -92,7 +92,7 @@ LL | | Self(Default::default()) LL | | } | |_____^ | -help: try this +help: try adding this | LL | impl Default for BarGenerics { LL | fn default() -> Self { @@ -101,5 +101,23 @@ LL | } LL | } | -error: aborting due to 6 previous errors +error: you should consider adding a `Default` implementation for `Foo` + --> $DIR/new_without_default.rs:182:9 + | +LL | / pub fn new() -> Self { +LL | | todo!() +LL | | } + | |_________^ + | +help: try adding this + | +LL | impl Default for Foo { +LL | fn default() -> Self { +LL | Self::new() +LL | } +LL | } +LL | + ... + +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/self_named_constructor.rs b/src/tools/clippy/tests/ui/self_named_constructors.rs similarity index 96% rename from src/tools/clippy/tests/ui/self_named_constructor.rs rename to src/tools/clippy/tests/ui/self_named_constructors.rs index 7658b86a8d6..356f701c985 100644 --- a/src/tools/clippy/tests/ui/self_named_constructor.rs +++ b/src/tools/clippy/tests/ui/self_named_constructors.rs @@ -1,4 +1,4 @@ -#![warn(clippy::self_named_constructor)] +#![warn(clippy::self_named_constructors)] struct ShouldSpawn; struct ShouldNotSpawn; diff --git a/src/tools/clippy/tests/ui/self_named_constructor.stderr b/src/tools/clippy/tests/ui/self_named_constructors.stderr similarity index 65% rename from src/tools/clippy/tests/ui/self_named_constructor.stderr rename to src/tools/clippy/tests/ui/self_named_constructors.stderr index 1e2c34ac2f7..ba989f06dc8 100644 --- a/src/tools/clippy/tests/ui/self_named_constructor.stderr +++ b/src/tools/clippy/tests/ui/self_named_constructors.stderr @@ -1,12 +1,12 @@ error: constructor `should_spawn` has the same name as the type - --> $DIR/self_named_constructor.rs:7:5 + --> $DIR/self_named_constructors.rs:7:5 | LL | / pub fn should_spawn() -> ShouldSpawn { LL | | ShouldSpawn LL | | } | |_____^ | - = note: `-D clippy::self-named-constructor` implied by `-D warnings` + = note: `-D clippy::self-named-constructors` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/similar_names.stderr b/src/tools/clippy/tests/ui/similar_names.stderr index a7eb2be0778..b24accd962a 100644 --- a/src/tools/clippy/tests/ui/similar_names.stderr +++ b/src/tools/clippy/tests/ui/similar_names.stderr @@ -10,11 +10,6 @@ note: existing binding defined here | LL | let apple: i32; | ^^^^^ -help: separate the discriminating character by an underscore like: `b_pple` - --> $DIR/similar_names.rs:15:9 - | -LL | let bpple: i32; - | ^^^^^ error: binding's name is too similar to existing binding --> $DIR/similar_names.rs:17:9 @@ -27,11 +22,6 @@ note: existing binding defined here | LL | let apple: i32; | ^^^^^ -help: separate the discriminating character by an underscore like: `c_pple` - --> $DIR/similar_names.rs:17:9 - | -LL | let cpple: i32; - | ^^^^^ error: binding's name is too similar to existing binding --> $DIR/similar_names.rs:41:9 @@ -44,11 +34,6 @@ note: existing binding defined here | LL | let blubx: i32; | ^^^^^ -help: separate the discriminating character by an underscore like: `blub_y` - --> $DIR/similar_names.rs:41:9 - | -LL | let bluby: i32; - | ^^^^^ error: binding's name is too similar to existing binding --> $DIR/similar_names.rs:45:9 @@ -85,11 +70,6 @@ note: existing binding defined here | LL | let parser: i32; | ^^^^^^ -help: separate the discriminating character by an underscore like: `parse_e` - --> $DIR/similar_names.rs:67:9 - | -LL | let parsee: i32; - | ^^^^^^ error: binding's name is too similar to existing binding --> $DIR/similar_names.rs:85:16 diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs index df0fdaccb34..535683729f6 100644 --- a/src/tools/clippy/tests/ui/unit_arg.rs +++ b/src/tools/clippy/tests/ui/unit_arg.rs @@ -7,7 +7,7 @@ clippy::unnecessary_wraps, clippy::or_fun_call, clippy::needless_question_mark, - clippy::self_named_constructor + clippy::self_named_constructors )] use std::fmt::Debug; diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed index 23fc7632511..dcf818f8076 100644 --- a/src/tools/clippy/tests/ui/use_self.fixed +++ b/src/tools/clippy/tests/ui/use_self.fixed @@ -8,7 +8,7 @@ clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into, - clippy::self_named_constructor + clippy::self_named_constructors )] #[macro_use] diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs index bb46a339923..9da6fef7a38 100644 --- a/src/tools/clippy/tests/ui/use_self.rs +++ b/src/tools/clippy/tests/ui/use_self.rs @@ -8,7 +8,7 @@ clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into, - clippy::self_named_constructor + clippy::self_named_constructors )] #[macro_use] diff --git a/src/tools/clippy/util/export.py b/src/tools/clippy/util/export.py deleted file mode 100755 index 1248e6b6a26..00000000000 --- a/src/tools/clippy/util/export.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python - -# Build the gh-pages - -from collections import OrderedDict -import re -import sys -import json - -from lintlib import parse_all, log - -lint_subheadline = re.compile(r'''^\*\*([\w\s]+?)[:?.!]?\*\*(.*)''') -rust_code_block = re.compile(r'''```rust.+?```''', flags=re.DOTALL) - -CONF_TEMPLATE = """\ -This lint has the following configuration variables: - -* `%s: %s`: %s (defaults to `%s`).""" - - -def parse_code_block(match): - lines = [] - - for line in match.group(0).split('\n'): - # fix syntax highlighting for headers like ```rust,ignore - if line.startswith('```rust'): - lines.append('```rust') - elif not line.startswith('# '): - lines.append(line) - - return '\n'.join(lines) - - -def parse_lint_def(lint): - lint_dict = {} - lint_dict['id'] = lint.name - lint_dict['group'] = lint.group - lint_dict['level'] = lint.level - lint_dict['docs'] = OrderedDict() - - last_section = None - - for line in lint.doc: - match = re.match(lint_subheadline, line) - if match: - last_section = match.groups()[0] - text = match.groups()[1] - else: - text = line - - if not last_section: - log.warning("Skipping comment line as it was not preceded by a heading") - log.debug("in lint `%s`, line `%s`", lint.name, line) - - if last_section not in lint_dict['docs']: - lint_dict['docs'][last_section] = "" - - lint_dict['docs'][last_section] += text + "\n" - - for section in lint_dict['docs']: - lint_dict['docs'][section] = re.sub(rust_code_block, parse_code_block, lint_dict['docs'][section].strip()) - - return lint_dict - - -def main(): - lintlist, configs = parse_all() - lints = {} - for lint in lintlist: - lints[lint.name] = parse_lint_def(lint) - if lint.name in configs: - lints[lint.name]['docs']['Configuration'] = \ - CONF_TEMPLATE % configs[lint.name] - - outfile = sys.argv[1] if len(sys.argv) > 1 else "util/gh-pages/lints.json" - with open(outfile, "w") as fp: - lints = list(lints.values()) - lints.sort(key=lambda x: x['id']) - json.dump(lints, fp, indent=2) - log.info("wrote JSON for great justice") - - -if __name__ == "__main__": - main() diff --git a/src/tools/clippy/util/gh-pages/index.html b/src/tools/clippy/util/gh-pages/index.html index 0174d3ffcbc..48421150a54 100644 --- a/src/tools/clippy/util/gh-pages/index.html +++ b/src/tools/clippy/util/gh-pages/index.html @@ -1,10 +1,17 @@ + - ALL the Clippy Lints + Clippy Lints @@ -22,15 +29,95 @@ .panel-heading { cursor: pointer; } - .panel-title { display: flex; } + .panel-title { display: flex; flex-wrap: wrap;} .panel-title .label { display: inline-block; } - .panel-title-name { flex: 1; } + .panel-title-name { flex: 1; min-width: 400px;} .panel-title-name span { vertical-align: bottom; } .panel .panel-title-name .anchor { display: none; } .panel:hover .panel-title-name .anchor { display: inline;} + .label { + padding-top: 0.3em; + padding-bottom: 0.3em; + } + + .label-lint-group { + min-width: 8em; + } + .label-lint-level { + min-width: 4em; + } + + .label-lint-level-allow { + background-color: #5cb85c; + } + .label-lint-level-warn { + background-color: #f0ad4e; + } + .label-lint-level-deny { + background-color: #d9534f; + } + .label-lint-level-none { + background-color: #777777; + opacity: 0.5; + } + + .label-group-deprecated { + opacity: 0.5; + } + + .label-doc-folding { + color: #000; + background-color: #fff; + border: 1px solid var(--theme-popup-border); + } + .label-doc-folding:hover { + background-color: #e6e6e6; + } + + .lint-doc-md > h3 { + border-top: 1px solid var(--theme-popup-border); + padding: 10px 15px; + margin: 0 -15px; + font-size: 18px; + } + .lint-doc-md > h3:first-child { + border-top: none; + padding-top: 0px; + } + + @media (max-width:749px) { + .lint-additional-info-container { + display: flex; + flex-flow: column; + } + .lint-additional-info-item + .lint-additional-info-item { + border-top: 1px solid var(--theme-popup-border); + } + } + @media (min-width:750px) { + .lint-additional-info-container { + display: flex; + flex-flow: row; + } + .lint-additional-info-item + .lint-additional-info-item { + border-left: 1px solid var(--theme-popup-border); + } + } + + .lint-additional-info-item { + display: inline-flex; + min-width: 200px; + flex-grow: 1; + padding: 9px 5px 5px 15px; + } + + .label-applicability { + background-color: #777777; + margin: auto 5px; + }