提交 a985d8e6 编写于 作者: B bors

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

Update Clippy

r? `@Manishearth`
......@@ -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",
......
......@@ -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"
......
......@@ -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: |
......
......@@ -2423,7 +2423,6 @@ Released 2018-09-13
<!-- begin autogenerated links to lint list -->
[`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
......
[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"
......
......@@ -169,14 +169,11 @@ fn get_lint_file_contents(
{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
/// ```
......
......@@ -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()
......
[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"
......
......@@ -11,24 +11,26 @@
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<isize> = Vec::new();
/// if vec.len() <= 0 {}
......
......@@ -7,21 +7,21 @@
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;
......
......@@ -6,7 +6,8 @@
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 @@
/// 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! {
/// **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;
......
......@@ -5,7 +5,8 @@
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 @@
/// 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;
/// ...
......
......@@ -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 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
}
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)]
......
......@@ -8,14 +8,17 @@
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)
......
......@@ -12,15 +12,18 @@
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! {
/// **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;
......
......@@ -7,15 +7,14 @@
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() {}
///
......
......@@ -8,16 +8,16 @@
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};
///
......
......@@ -41,10 +41,12 @@
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 @@
/// 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! {
/// **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 @@
/// `#[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! {
/// **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! {
/// **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! {
/// **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! {
/// **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! {
/// **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)]
......
......@@ -8,10 +8,12 @@
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 @@
/// 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! {
/// **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;
///
......
......@@ -10,7 +10,8 @@
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 `_ <bit_op> m
/// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
......@@ -26,7 +27,8 @@
/// |`<` 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 @@
/// 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! {
/// **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 @@
/// |`>` / `<=`|`|` / `^`|`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! {
/// **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 { }
......
......@@ -5,15 +5,15 @@
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;
/// ```
......
......@@ -13,14 +13,14 @@
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 } { /* ... */ }
......
......@@ -6,14 +6,13 @@
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);
......
......@@ -14,16 +14,19 @@
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! {
/// **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 { ... }
/// ```
......
......@@ -12,18 +12,20 @@
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
......
......@@ -9,15 +9,15 @@
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]
......
......@@ -8,17 +8,14 @@
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")
......
......@@ -20,7 +20,8 @@
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 @@
/// 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! {
/// **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! {
/// **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! {
/// **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! {
/// **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! {
/// **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.
///
/// **Known problems:** None.
/// ### Why is this bad?
/// It's just unnecessary.
///
/// **Example:**
/// ### Example
/// ```rust
/// let _ = 2i32 as i32;
/// let _ = 0.5 as f32;
......@@ -168,17 +168,20 @@
}
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! {
/// **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 @@
///
/// 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! {
/// **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! {
/// **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! {
/// **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! {
/// **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;
......
......@@ -13,13 +13,13 @@
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 _ =
......
......@@ -14,15 +14,19 @@
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"
......
......@@ -22,15 +22,15 @@
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! {
/// **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 {
......
......@@ -9,18 +9,17 @@
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<Result<u64, String>>) {
/// let n = match opt {
......
......@@ -6,16 +6,19 @@
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() {}
......
......@@ -16,13 +16,13 @@
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! {
/// **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! {
/// **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.
///
/// **Known problems:** Hopefully none.
/// ### Why is this bad?
/// This is probably a copy & paste error.
///
/// **Example:**
/// ### Example
/// ```ignore
/// let foo = if … {
/// 42
......@@ -115,17 +115,19 @@
}
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");
......
......@@ -8,15 +8,15 @@
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);
......
......@@ -8,13 +8,13 @@
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");
......
......@@ -8,14 +8,14 @@
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)
......
......@@ -13,14 +13,14 @@
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! {
/// **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)]
......
......@@ -18,7 +18,8 @@
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 @@
///
/// 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;
......
......@@ -12,27 +12,33 @@
}
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! {
/// **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! {
/// **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! {
/// **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! {
/// **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! {
/// **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! {
/// **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"
......
......@@ -11,12 +11,14 @@
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");
......
......@@ -15,10 +15,12 @@
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 @@
/// k1 == k2 ⇒ hash(k1) == hash(k2)
/// ```
///
/// **Known problems:** None.
///
/// **Example:**
/// ### Example
/// ```ignore
/// #[derive(Hash)]
/// struct Foo;
......@@ -44,10 +44,12 @@
}
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 @@
/// 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! {
/// **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! {
/// **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;
///
......
......@@ -8,15 +8,14 @@
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
......
......@@ -6,7 +6,8 @@
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 @@
/// [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 @@
///
/// [`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"]
......
......@@ -2,27 +2,24 @@
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 @@
#[derive(Clone, Debug)]
pub struct DisallowedType {
disallowed: FxHashSet<Vec<Symbol>>,
def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
def_ids: FxHashSet<DefId>,
prim_tys: FxHashSet<PrimTy>,
}
impl DisallowedType {
......@@ -53,6 +51,23 @@ pub fn new(disallowed: &FxHashSet<String>) -> Self {
.map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
.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::<Vec<_>>();
if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
{
self.def_ids.insert((id, path.clone()));
match clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>()) {
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::<Vec<_>>().join("::");
fn emit(cx: &LateContext<'_>, name: &str, span: Span) {
span_lint(
cx,
DISALLOWED_TYPE,
......
......@@ -30,15 +30,18 @@
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 @@
/// `[`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! {
/// **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! {
/// **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! {
/// **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! {
/// **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
/// ///
......
......@@ -10,14 +10,14 @@
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;
......
......@@ -4,14 +4,14 @@
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 {
......
......@@ -8,17 +8,17 @@
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! {
/// **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! {
/// **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! {
/// **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 @@
/// 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
......
......@@ -12,15 +12,15 @@
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);
......
......@@ -7,14 +7,14 @@
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() {}
......
......@@ -6,13 +6,15 @@
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 @@
/// 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 {}
......
......@@ -16,12 +16,15 @@
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 @@
/// };
/// ```
///
/// **Example:**
/// ### Example
/// ```rust
/// # use std::collections::HashMap;
/// # let mut map = HashMap::new();
......
......@@ -11,15 +11,15 @@
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)]
......
......@@ -10,15 +10,15 @@
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! {
/// **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.
///
/// **Known problems:** None.
/// ### Why is this bad?
/// It requires the user to type the module name twice.
///
/// **Example:**
/// ### Example
/// ```rust
/// mod cake {
/// struct BlackForestCake;
......@@ -65,10 +65,12 @@
}
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 @@
/// 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;
......
......@@ -9,18 +9,21 @@
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! {
/// **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
......
......@@ -6,15 +6,15 @@
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;
......
......@@ -19,16 +19,16 @@ pub struct BoxedLocal {
}
declare_clippy_lint! {
/// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would
/// ### What it does
/// Checks for usage of `Box<T>` where an unboxed `T` would
/// work fine.
///
/// **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
......
......@@ -14,19 +14,22 @@
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! {
/// **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());
/// ```
......
......@@ -9,17 +9,20 @@
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! {
/// **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 }
......
......@@ -8,19 +8,19 @@
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! {
/// **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) { ... }
......
......@@ -8,16 +8,15 @@
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! {
/// **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,
......
......@@ -6,15 +6,15 @@
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)
/// ```
......
......@@ -9,14 +9,14 @@
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";
......
......@@ -10,13 +10,13 @@
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);
///
......
......@@ -11,30 +11,32 @@
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()`"
......
......@@ -10,15 +10,14 @@
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! {
/// **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
......
......@@ -18,16 +18,15 @@
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! {
/// **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;
///
......
......@@ -13,18 +13,18 @@
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
......
......@@ -9,15 +9,15 @@
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! {
/// **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.
///
/// **Known problems:** None.
/// ### Why is this bad?
/// This is either a typo in the binary operator or confusing.
///
/// **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! {
/// **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! {
/// **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.
///
/// **Known problems:** None.
/// ### Why is this bad?
/// This could lead to unexpected results.
///
/// **Example:**
/// ### Example
/// ```rust,ignore
/// let a = &[
/// -1, -2, -3 // <= no comma here
......
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
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(
......
......@@ -10,20 +10,22 @@
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::<primitive>()`
/// (and in most cases, the turbofish can be removed), which reduces code length
/// and complexity.
///
/// **Known problems:**
/// ### Known problems
///
/// This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly
/// in some cases, which is correct but adds unnecessary complexity to the code.
///
/// **Example:**
///
/// ### Example
/// ```ignore
/// let input: &str = get_input();
/// let num = u16::from_str_radix(input, 10)?;
......
......@@ -11,15 +11,15 @@
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! {
/// **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! {
/// **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 @@
/// 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! {
/// **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! {
/// **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! {
/// **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 @@
/// 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 { t }
......@@ -163,20 +167,23 @@
}
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<u8, ()> { Err(()) }
/// ```
......
......@@ -12,12 +12,14 @@
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 @@
/// 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]>) {}
/// ```
......
......@@ -14,10 +14,12 @@
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 @@
/// 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];
......
......@@ -11,14 +11,14 @@
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;
......
......@@ -9,16 +9,15 @@
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();
......
......@@ -10,14 +10,14 @@
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() {
......
......@@ -8,14 +8,14 @@
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<usize> = vec![];
/// # fn a() {}
......
......@@ -10,14 +10,13 @@
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() {
......
......@@ -5,7 +5,7 @@
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 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 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
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 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
),
);
}
} 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());
......
......@@ -13,17 +13,17 @@
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
......
......@@ -8,14 +8,13 @@
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;
......
......@@ -10,11 +10,13 @@
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 @@
///
/// inconsistent order can be confusing and decreases readability and consistency.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ### Example
/// ```rust
/// struct Foo {
/// x: i32,
......
......@@ -10,14 +10,17 @@
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! {
/// **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];
......
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! {
/// **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 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
];
/// 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]);
}
}
......
......@@ -10,13 +10,13 @@
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 {
......
......@@ -8,14 +8,16 @@
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! {
/// **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`.
/// ### 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.
///
/// **Known problems:** None
/// ### 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`.
///
/// ** Example:**
/// ### Known problems
/// None
///
/// ### Example
/// ```rust
/// // Bad
/// use std::fmt;
......
......@@ -10,14 +10,14 @@
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]
......
......@@ -8,13 +8,13 @@
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;
......
......@@ -5,15 +5,15 @@
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;
......
......@@ -14,18 +14,20 @@
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;
......
......@@ -7,15 +7,15 @@
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() {
......
......@@ -11,15 +11,15 @@
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];
......
......@@ -10,20 +10,22 @@
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 {
......
......@@ -10,13 +10,13 @@
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];
/// ```
......
......@@ -18,17 +18,17 @@
};
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! {
/// **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! {
/// **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 == "" {
......
......@@ -9,14 +9,14 @@
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;
///
......
......@@ -9,15 +9,15 @@
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// **What it does:** Checks for `let _ = <expr>`
/// ### What it does
/// Checks for `let _ = <expr>`
/// 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<u32, u32> {
/// Ok(0)
......@@ -33,17 +33,17 @@
}
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! {
/// **What it does:** Checks for `let _ = <expr>`
/// ### What it does
/// Checks for `let _ = <expr>`
/// 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
......
......@@ -73,14 +73,13 @@
/// 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 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]
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册