mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 07:04:18 +00:00
Merge commit '0cce3f643bfcbb92d5a1bb71858c9cbaff749d6b' into clippyup
This commit is contained in:
parent
5331fea875
commit
2b20f49841
283 changed files with 3436 additions and 3113 deletions
9
.github/deploy.sh
vendored
9
.github/deploy.sh
vendored
|
@ -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"
|
||||
|
||||
|
|
17
.github/workflows/deploy.yml
vendored
17
.github/workflows/deploy.yml
vendored
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.55"
|
||||
version = "0.1.56"
|
||||
authors = ["The Rust Clippy Developers"]
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
|
|
|
@ -169,14 +169,11 @@ use rustc_session::{{declare_lint_pass, declare_tool_lint}};
|
|||
{pass_import}
|
||||
|
||||
declare_clippy_lint! {{
|
||||
/// **What it does:**
|
||||
/// ### What it does
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // example code where clippy issues a warning
|
||||
/// ```
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "clippy_lints"
|
||||
# begin automatic update
|
||||
version = "0.1.55"
|
||||
version = "0.1.56"
|
||||
# end automatic update
|
||||
authors = ["The Rust Clippy Developers"]
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
|
|
|
@ -11,24 +11,26 @@ use clippy_utils::ty::is_isize_or_usize;
|
|||
use clippy_utils::{clip, int_bits, unsext};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for comparisons where one side of the relation is
|
||||
/// ### What it does
|
||||
/// Checks for comparisons where one side of the relation is
|
||||
/// either the minimum or maximum value for its type and warns if it involves a
|
||||
/// case that is always true or always false. Only integer and boolean types are
|
||||
/// checked.
|
||||
///
|
||||
/// **Why is this bad?** An expression like `min <= x` may misleadingly imply
|
||||
/// ### Why is this bad?
|
||||
/// An expression like `min <= x` may misleadingly imply
|
||||
/// that it is possible for `x` to be less than the minimum. Expressions like
|
||||
/// `max < x` are probably mistakes.
|
||||
///
|
||||
/// **Known problems:** For `usize` the size of the current compile target will
|
||||
/// ### Known problems
|
||||
/// For `usize` the size of the current compile target will
|
||||
/// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
|
||||
/// a comparison to detect target pointer width will trigger this lint. One can
|
||||
/// use `mem::sizeof` and compare its value or conditional compilation
|
||||
/// attributes
|
||||
/// like `#[cfg(target_pointer_width = "64")] ..` instead.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let vec: Vec<isize> = Vec::new();
|
||||
/// if vec.len() <= 0 {}
|
||||
|
|
|
@ -7,21 +7,21 @@ use rustc_span::symbol;
|
|||
use std::f64::consts as f64;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for floating point literals that approximate
|
||||
/// ### What it does
|
||||
/// Checks for floating point literals that approximate
|
||||
/// constants which are defined in
|
||||
/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
|
||||
/// or
|
||||
/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
|
||||
/// respectively, suggesting to use the predefined constant.
|
||||
///
|
||||
/// **Why is this bad?** Usually, the definition in the standard library is more
|
||||
/// ### Why is this bad?
|
||||
/// Usually, the definition in the standard library is more
|
||||
/// precise than what people come up with. If you find that your definition is
|
||||
/// actually more precise, please [file a Rust
|
||||
/// issue](https://github.com/rust-lang/rust/issues).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = 3.14;
|
||||
/// let y = 1_f64 / x;
|
||||
|
|
|
@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for integer arithmetic operations which could overflow or panic.
|
||||
/// ### What it does
|
||||
/// Checks for integer arithmetic operations which could overflow or panic.
|
||||
///
|
||||
/// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
|
||||
/// of overflowing according to the [Rust
|
||||
|
@ -14,13 +15,12 @@ declare_clippy_lint! {
|
|||
/// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
|
||||
/// attempted.
|
||||
///
|
||||
/// **Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in
|
||||
/// ### Why is this bad?
|
||||
/// Integer overflow will trigger a panic in debug builds or will wrap in
|
||||
/// release mode. Division by zero will cause a panic in either mode. In some applications one
|
||||
/// wants explicitly checked, wrapping or saturating arithmetic.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let a = 0;
|
||||
/// a + 1;
|
||||
|
@ -31,14 +31,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for float arithmetic.
|
||||
/// ### What it does
|
||||
/// Checks for float arithmetic.
|
||||
///
|
||||
/// **Why is this bad?** For some embedded systems or kernel development, it
|
||||
/// ### Why is this bad?
|
||||
/// For some embedded systems or kernel development, it
|
||||
/// can be useful to rule out floating-point numbers.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let a = 0.0;
|
||||
/// a + 1.0;
|
||||
|
|
|
@ -5,7 +5,8 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `as` conversions.
|
||||
/// ### What it does
|
||||
/// Checks for usage of `as` conversions.
|
||||
///
|
||||
/// Note that this lint is specialized in linting *every single* use of `as`
|
||||
/// regardless of whether good alternatives exist or not.
|
||||
|
@ -15,14 +16,13 @@ declare_clippy_lint! {
|
|||
/// There is a good explanation the reason why this lint should work in this way and how it is useful
|
||||
/// [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).
|
||||
///
|
||||
/// **Why is this bad?** `as` conversions will perform many kinds of
|
||||
/// ### Why is this bad?
|
||||
/// `as` conversions will perform many kinds of
|
||||
/// conversions, including silently lossy conversions and dangerous coercions.
|
||||
/// There are cases when it makes sense to use `as`, so the lint is
|
||||
/// Allow by default.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// let a: u32;
|
||||
/// ...
|
||||
|
|
|
@ -53,14 +53,14 @@ fn check_expr_asm_syntax(lint: &'static Lint, cx: &EarlyContext<'_>, expr: &Expr
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of Intel x86 assembly syntax.
|
||||
/// ### What it does
|
||||
/// Checks for usage of Intel x86 assembly syntax.
|
||||
///
|
||||
/// **Why is this bad?** The lint has been enabled to indicate a preference
|
||||
/// ### Why is this bad?
|
||||
/// The lint has been enabled to indicate a preference
|
||||
/// for AT&T x86 assembly syntax.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(asm)]
|
||||
|
@ -89,14 +89,14 @@ impl EarlyLintPass for InlineAsmX86IntelSyntax {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of AT&T x86 assembly syntax.
|
||||
/// ### What it does
|
||||
/// Checks for usage of AT&T x86 assembly syntax.
|
||||
///
|
||||
/// **Why is this bad?** The lint has been enabled to indicate a preference
|
||||
/// ### Why is this bad?
|
||||
/// The lint has been enabled to indicate a preference
|
||||
/// for Intel x86 assembly syntax.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(asm)]
|
||||
|
|
|
@ -8,14 +8,17 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
|
||||
/// ### What it does
|
||||
/// Checks for `assert!(true)` and `assert!(false)` calls.
|
||||
///
|
||||
/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
|
||||
/// ### Why is this bad?
|
||||
/// Will be optimized out by the compiler or should probably be replaced by a
|
||||
/// `panic!()` or `unreachable!()`
|
||||
///
|
||||
/// **Known problems:** None
|
||||
/// ### Known problems
|
||||
/// None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// assert!(false)
|
||||
/// assert!(true)
|
||||
|
|
|
@ -12,15 +12,18 @@ use rustc_middle::hir::map::Map;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
/// ### What it does
|
||||
/// Checks for `a = a op b` or `a = b commutative_op a`
|
||||
/// patterns.
|
||||
///
|
||||
/// **Why is this bad?** These can be written as the shorter `a op= b`.
|
||||
/// ### Why is this bad?
|
||||
/// These can be written as the shorter `a op= b`.
|
||||
///
|
||||
/// **Known problems:** While forbidden by the spec, `OpAssign` traits may have
|
||||
/// ### Known problems
|
||||
/// While forbidden by the spec, `OpAssign` traits may have
|
||||
/// implementations that differ from the regular `Op` impl.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// let b = 0;
|
||||
|
@ -37,17 +40,20 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns.
|
||||
/// ### What it does
|
||||
/// Checks for `a op= a op b` or `a op= b op a` patterns.
|
||||
///
|
||||
/// **Why is this bad?** Most likely these are bugs where one meant to write `a
|
||||
/// ### Why is this bad?
|
||||
/// Most likely these are bugs where one meant to write `a
|
||||
/// op= b`.
|
||||
///
|
||||
/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have
|
||||
/// ### Known problems
|
||||
/// Clippy cannot know for sure if `a op= a op b` should have
|
||||
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
|
||||
/// If `a op= a op b` is really the correct behaviour it should be
|
||||
/// written as `a = a op a op b` as it's less confusing.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// let b = 2;
|
||||
|
|
|
@ -7,15 +7,14 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for async blocks that yield values of types
|
||||
/// ### What it does
|
||||
/// Checks for async blocks that yield values of types
|
||||
/// that can themselves be awaited.
|
||||
///
|
||||
/// **Why is this bad?** An await is likely missing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// An await is likely missing.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// async fn foo() {}
|
||||
///
|
||||
|
|
|
@ -8,16 +8,16 @@ use rustc_middle::ty;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of invalid atomic
|
||||
/// ### What it does
|
||||
/// Checks for usage of invalid atomic
|
||||
/// ordering in atomic loads/stores/exchanges/updates and
|
||||
/// memory fences.
|
||||
///
|
||||
/// **Why is this bad?** Using an invalid atomic ordering
|
||||
/// ### Why is this bad?
|
||||
/// Using an invalid atomic ordering
|
||||
/// will cause a panic at run-time.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,no_run
|
||||
/// # use std::sync::atomic::{self, AtomicU8, Ordering};
|
||||
///
|
||||
|
|
|
@ -41,10 +41,12 @@ static UNIX_SYSTEMS: &[&str] = &[
|
|||
static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
||||
/// ### What it does
|
||||
/// Checks for items annotated with `#[inline(always)]`,
|
||||
/// unless the annotated function is empty or simply panics.
|
||||
///
|
||||
/// **Why is this bad?** While there are valid uses of this annotation (and once
|
||||
/// ### Why is this bad?
|
||||
/// While there are valid uses of this annotation (and once
|
||||
/// you know when to use it, by all means `allow` this lint), it's a common
|
||||
/// newbie-mistake to pepper one's code with it.
|
||||
///
|
||||
|
@ -52,11 +54,12 @@ declare_clippy_lint! {
|
|||
/// measure if that additional function call really affects your runtime profile
|
||||
/// sufficiently to make up for the increase in compile time.
|
||||
///
|
||||
/// **Known problems:** False positives, big time. This lint is meant to be
|
||||
/// ### Known problems
|
||||
/// False positives, big time. This lint is meant to be
|
||||
/// deactivated by everyone doing serious performance work. This means having
|
||||
/// done the measurement.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// #[inline(always)]
|
||||
/// fn not_quite_hot_code(..) { ... }
|
||||
|
@ -67,7 +70,8 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `extern crate` and `use` items annotated with
|
||||
/// ### What it does
|
||||
/// Checks for `extern crate` and `use` items annotated with
|
||||
/// lint attributes.
|
||||
///
|
||||
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
|
||||
|
@ -75,12 +79,11 @@ declare_clippy_lint! {
|
|||
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
|
||||
/// `extern crate` items with a `#[macro_use]` attribute.
|
||||
///
|
||||
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
|
||||
/// ### Why is this bad?
|
||||
/// Lint attributes have no effect on crate imports. Most
|
||||
/// likely a `!` was forgotten.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// // Bad
|
||||
/// #[deny(dead_code)]
|
||||
|
@ -101,15 +104,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[deprecated]` annotations with a `since`
|
||||
/// ### What it does
|
||||
/// Checks for `#[deprecated]` annotations with a `since`
|
||||
/// field that is not a valid semantic version.
|
||||
///
|
||||
/// **Why is this bad?** For checking the version of the deprecation, it must be
|
||||
/// ### Why is this bad?
|
||||
/// For checking the version of the deprecation, it must be
|
||||
/// a valid semver. Failing that, the contained information is useless.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// #[deprecated(since = "forever")]
|
||||
/// fn something_else() { /* ... */ }
|
||||
|
@ -120,20 +123,22 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for empty lines after outer attributes
|
||||
/// ### What it does
|
||||
/// Checks for empty lines after outer attributes
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
/// Most likely the attribute was meant to be an inner attribute using a '!'.
|
||||
/// If it was meant to be an outer attribute, then the following item
|
||||
/// should not be separated by empty lines.
|
||||
///
|
||||
/// **Known problems:** Can cause false positives.
|
||||
/// ### Known problems
|
||||
/// Can cause false positives.
|
||||
///
|
||||
/// From the clippy side it's difficult to detect empty lines between an attributes and the
|
||||
/// following item because empty lines and comments are not part of the AST. The parsing
|
||||
/// currently works for basic cases but is not perfect.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Good (as inner attribute)
|
||||
/// #![allow(dead_code)]
|
||||
|
@ -155,14 +160,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
|
||||
/// ### What it does
|
||||
/// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
|
||||
///
|
||||
/// **Why is this bad?** Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
|
||||
/// ### Why is this bad?
|
||||
/// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
|
||||
/// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #![deny(clippy::restriction)]
|
||||
|
@ -178,18 +183,20 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
|
||||
/// ### What it does
|
||||
/// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
|
||||
/// with `#[rustfmt::skip]`.
|
||||
///
|
||||
/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
|
||||
/// ### Why is this bad?
|
||||
/// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
|
||||
/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
|
||||
///
|
||||
/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get
|
||||
/// ### Known problems
|
||||
/// This lint doesn't detect crate level inner attributes, because they get
|
||||
/// processed before the PreExpansionPass lints get executed. See
|
||||
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
|
@ -207,15 +214,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for cfg attributes having operating systems used in target family position.
|
||||
/// ### What it does
|
||||
/// Checks for cfg attributes having operating systems used in target family position.
|
||||
///
|
||||
/// **Why is this bad?** The configuration option will not be recognised and the related item will not be included
|
||||
/// ### Why is this bad?
|
||||
/// The configuration option will not be recognised and the related item will not be included
|
||||
/// by the conditional compilation engine.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #[cfg(linux)]
|
||||
|
|
|
@ -8,10 +8,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to await while holding a
|
||||
/// ### What it does
|
||||
/// Checks for calls to await while holding a
|
||||
/// non-async-aware MutexGuard.
|
||||
///
|
||||
/// **Why is this bad?** The Mutex types found in std::sync and parking_lot
|
||||
/// ### Why is this bad?
|
||||
/// The Mutex types found in std::sync and parking_lot
|
||||
/// are not designed to operate in an async context across await points.
|
||||
///
|
||||
/// There are two potential solutions. One is to use an asynx-aware Mutex
|
||||
|
@ -19,10 +21,10 @@ declare_clippy_lint! {
|
|||
/// other solution is to ensure the mutex is unlocked before calling await,
|
||||
/// either by introducing a scope or an explicit call to Drop::drop.
|
||||
///
|
||||
/// **Known problems:** Will report false positive for explicitly dropped guards ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Known problems
|
||||
/// Will report false positive for explicitly dropped guards ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)).
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// use std::sync::Mutex;
|
||||
///
|
||||
|
@ -51,17 +53,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to await while holding a
|
||||
/// ### What it does
|
||||
/// Checks for calls to await while holding a
|
||||
/// `RefCell` `Ref` or `RefMut`.
|
||||
///
|
||||
/// **Why is this bad?** `RefCell` refs only check for exclusive mutable access
|
||||
/// ### Why is this bad?
|
||||
/// `RefCell` refs only check for exclusive mutable access
|
||||
/// at runtime. Holding onto a `RefCell` ref across an `await` suspension point
|
||||
/// risks panics from a mutable ref shared while other refs are outstanding.
|
||||
///
|
||||
/// **Known problems:** Will report false positive for explicitly dropped refs ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Known problems
|
||||
/// Will report false positive for explicitly dropped refs ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)).
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// use std::cell::RefCell;
|
||||
///
|
||||
|
|
|
@ -10,7 +10,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for incompatible bit masks in comparisons.
|
||||
/// ### What it does
|
||||
/// Checks for incompatible bit masks in comparisons.
|
||||
///
|
||||
/// The formula for detecting if an expression of the type `_ <bit_op> m
|
||||
/// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
|
||||
|
@ -26,7 +27,8 @@ declare_clippy_lint! {
|
|||
/// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |
|
||||
/// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |
|
||||
///
|
||||
/// **Why is this bad?** If the bits that the comparison cares about are always
|
||||
/// ### Why is this bad?
|
||||
/// If the bits that the comparison cares about are always
|
||||
/// set to zero or one by the bit mask, the comparison is constant `true` or
|
||||
/// `false` (depending on mask, compared value, and operators).
|
||||
///
|
||||
|
@ -34,9 +36,7 @@ declare_clippy_lint! {
|
|||
/// this intentionally is to win an underhanded Rust contest or create a
|
||||
/// test-case for this lint.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// if (x & 1 == 2) { }
|
||||
|
@ -47,7 +47,8 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for bit masks in comparisons which can be removed
|
||||
/// ### What it does
|
||||
/// Checks for bit masks in comparisons which can be removed
|
||||
/// without changing the outcome. The basic structure can be seen in the
|
||||
/// following table:
|
||||
///
|
||||
|
@ -56,16 +57,18 @@ declare_clippy_lint! {
|
|||
/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|
|
||||
/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|
|
||||
///
|
||||
/// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
|
||||
/// ### Why is this bad?
|
||||
/// Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
|
||||
/// but still a bit misleading, because the bit mask is ineffective.
|
||||
///
|
||||
/// **Known problems:** False negatives: This lint will only match instances
|
||||
/// ### Known problems
|
||||
/// False negatives: This lint will only match instances
|
||||
/// where we have figured out the math (which is for a power-of-two compared
|
||||
/// value). This means things like `x | 1 >= 7` (which would be better written
|
||||
/// as `x >= 6`) will not be reported (but bit masks like this are fairly
|
||||
/// uncommon).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// if (x | 1 > 3) { }
|
||||
|
@ -76,15 +79,18 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for bit masks that can be replaced by a call
|
||||
/// ### What it does
|
||||
/// Checks for bit masks that can be replaced by a call
|
||||
/// to `trailing_zeros`
|
||||
///
|
||||
/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15
|
||||
/// ### Why is this bad?
|
||||
/// `x.trailing_zeros() > 4` is much clearer than `x & 15
|
||||
/// == 0`
|
||||
///
|
||||
/// **Known problems:** llvm generates better code for `x & 15 == 0` on x86
|
||||
/// ### Known problems
|
||||
/// llvm generates better code for `x & 15 == 0` on x86
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// if x & 0b1111 == 0 { }
|
||||
|
|
|
@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of blacklisted names for variables, such
|
||||
/// ### What it does
|
||||
/// Checks for usage of blacklisted names for variables, such
|
||||
/// as `foo`.
|
||||
///
|
||||
/// **Why is this bad?** These names are usually placeholder names and should be
|
||||
/// ### Why is this bad?
|
||||
/// These names are usually placeholder names and should be
|
||||
/// avoided.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let foo = 3.14;
|
||||
/// ```
|
||||
|
|
|
@ -13,14 +13,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `if` conditions that use blocks containing an
|
||||
/// ### What it does
|
||||
/// Checks for `if` conditions that use blocks containing an
|
||||
/// expression, statements or conditions that use closures with blocks.
|
||||
///
|
||||
/// **Why is this bad?** Style, using blocks in the condition makes it hard to read.
|
||||
/// ### Why is this bad?
|
||||
/// Style, using blocks in the condition makes it hard to read.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// if { true } { /* ... */ }
|
||||
|
|
|
@ -6,14 +6,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint warns about boolean comparisons in assert-like macros.
|
||||
/// ### What it does
|
||||
/// This lint warns about boolean comparisons in assert-like macros.
|
||||
///
|
||||
/// **Why is this bad?** It is shorter to use the equivalent.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// It is shorter to use the equivalent.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// assert_eq!("a".is_empty(), false);
|
||||
|
|
|
@ -14,16 +14,19 @@ use rustc_span::source_map::Span;
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for boolean expressions that can be written more
|
||||
/// ### What it does
|
||||
/// Checks for boolean expressions that can be written more
|
||||
/// concisely.
|
||||
///
|
||||
/// **Why is this bad?** Readability of boolean expressions suffers from
|
||||
/// ### Why is this bad?
|
||||
/// Readability of boolean expressions suffers from
|
||||
/// unnecessary duplication.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior of `||` and
|
||||
/// ### Known problems
|
||||
/// Ignores short circuiting behavior of `||` and
|
||||
/// `&&`. Ignores `|`, `&` and `^`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// if a && true // should be: if a
|
||||
/// if !(a == b) // should be: if a != b
|
||||
|
@ -34,14 +37,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for boolean expressions that contain terminals that
|
||||
/// ### What it does
|
||||
/// Checks for boolean expressions that contain terminals that
|
||||
/// can be eliminated.
|
||||
///
|
||||
/// **Why is this bad?** This is most likely a logic bug.
|
||||
/// ### Why is this bad?
|
||||
/// This is most likely a logic bug.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior.
|
||||
/// ### Known problems
|
||||
/// Ignores short circuiting behavior.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// if a && b || a { ... }
|
||||
/// ```
|
||||
|
|
|
@ -12,18 +12,20 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for naive byte counts
|
||||
/// ### What it does
|
||||
/// Checks for naive byte counts
|
||||
///
|
||||
/// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount)
|
||||
/// ### Why is this bad?
|
||||
/// The [`bytecount`](https://crates.io/crates/bytecount)
|
||||
/// crate has methods to count your bytes faster, especially for large slices.
|
||||
///
|
||||
/// **Known problems:** If you have predominantly small slices, the
|
||||
/// ### Known problems
|
||||
/// If you have predominantly small slices, the
|
||||
/// `bytecount::count(..)` method may actually be slower. However, if you can
|
||||
/// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
|
||||
/// faster in those cases.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let vec = vec![1_u8];
|
||||
/// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead
|
||||
|
|
|
@ -9,15 +9,15 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::source_map::DUMMY_SP;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks to see if all common metadata is defined in
|
||||
/// ### What it does
|
||||
/// Checks to see if all common metadata is defined in
|
||||
/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
|
||||
///
|
||||
/// **Why is this bad?** It will be more difficult for users to discover the
|
||||
/// ### Why is this bad?
|
||||
/// It will be more difficult for users to discover the
|
||||
/// purpose of the crate, and key information related to it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```toml
|
||||
/// # This `Cargo.toml` is missing a description field:
|
||||
/// [package]
|
||||
|
|
|
@ -8,17 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::{source_map::Spanned, symbol::sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
/// ### What it does
|
||||
/// Checks for calls to `ends_with` with possible file extensions
|
||||
/// and suggests to use a case-insensitive approach instead.
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
/// `ends_with` is case-sensitive and may not detect files with a valid extension.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn is_rust_file(filename: &str) -> bool {
|
||||
/// filename.ends_with(".rs")
|
||||
|
|
|
@ -20,7 +20,8 @@ use rustc_semver::RustcVersion;
|
|||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts from any numerical to a float type where
|
||||
/// ### What it does
|
||||
/// Checks for casts from any numerical to a float type where
|
||||
/// the receiving type cannot store all values from the original type without
|
||||
/// rounding errors. This possible rounding is to be expected, so this lint is
|
||||
/// `Allow` by default.
|
||||
|
@ -28,13 +29,12 @@ declare_clippy_lint! {
|
|||
/// Basically, this warns on casting any integer with 32 or more bits to `f32`
|
||||
/// or any 64-bit integer to `f64`.
|
||||
///
|
||||
/// **Why is this bad?** It's not bad at all. But in some applications it can be
|
||||
/// ### Why is this bad?
|
||||
/// It's not bad at all. But in some applications it can be
|
||||
/// helpful to know where precision loss can take place. This lint can help find
|
||||
/// those places in the code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = u64::MAX;
|
||||
/// x as f64;
|
||||
|
@ -45,17 +45,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts from a signed to an unsigned numerical
|
||||
/// ### What it does
|
||||
/// Checks for casts from a signed to an unsigned numerical
|
||||
/// type. In this case, negative values wrap around to large positive values,
|
||||
/// which can be quite surprising in practice. However, as the cast works as
|
||||
/// defined, this lint is `Allow` by default.
|
||||
///
|
||||
/// **Why is this bad?** Possibly surprising results. You can activate this lint
|
||||
/// ### Why is this bad?
|
||||
/// Possibly surprising results. You can activate this lint
|
||||
/// as a one-time check to see where numerical wrapping can arise.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let y: i8 = -1;
|
||||
/// y as u128; // will return 18446744073709551615
|
||||
|
@ -66,17 +66,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts between numerical types that may
|
||||
/// ### What it does
|
||||
/// Checks for casts between numerical types that may
|
||||
/// truncate large values. This is expected behavior, so the cast is `Allow` by
|
||||
/// default.
|
||||
///
|
||||
/// **Why is this bad?** In some problem domains, it is good practice to avoid
|
||||
/// ### Why is this bad?
|
||||
/// In some problem domains, it is good practice to avoid
|
||||
/// truncation. This lint can be activated to help assess where additional
|
||||
/// checks could be beneficial.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn as_u8(x: u64) -> u8 {
|
||||
/// x as u8
|
||||
|
@ -88,20 +88,20 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts from an unsigned type to a signed type of
|
||||
/// ### What it does
|
||||
/// Checks for casts from an unsigned type to a signed type of
|
||||
/// the same size. Performing such a cast is a 'no-op' for the compiler,
|
||||
/// i.e., nothing is changed at the bit level, and the binary representation of
|
||||
/// the value is reinterpreted. This can cause wrapping if the value is too big
|
||||
/// for the target signed type. However, the cast works as defined, so this lint
|
||||
/// is `Allow` by default.
|
||||
///
|
||||
/// **Why is this bad?** While such a cast is not bad in itself, the results can
|
||||
/// ### Why is this bad?
|
||||
/// While such a cast is not bad in itself, the results can
|
||||
/// be surprising when this is not the intended behavior, as demonstrated by the
|
||||
/// example below.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// u32::MAX as i32; // will yield a value of `-1`
|
||||
/// ```
|
||||
|
@ -111,19 +111,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts between numerical types that may
|
||||
/// ### What it does
|
||||
/// Checks for casts between numerical types that may
|
||||
/// be replaced by safe conversion functions.
|
||||
///
|
||||
/// **Why is this bad?** Rust's `as` keyword will perform many kinds of
|
||||
/// ### Why is this bad?
|
||||
/// Rust's `as` keyword will perform many kinds of
|
||||
/// conversions, including silently lossy conversions. Conversion functions such
|
||||
/// as `i32::from` will only perform lossless conversions. Using the conversion
|
||||
/// functions prevents conversions from turning into silent lossy conversions if
|
||||
/// the types of the input expressions ever change, and make it easier for
|
||||
/// people reading the code to know that the conversion is lossless.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn as_u64(x: u8) -> u64 {
|
||||
/// x as u64
|
||||
|
@ -143,14 +143,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts to the same type, casts of int literals to integer types
|
||||
/// ### What it does
|
||||
/// Checks for casts to the same type, casts of int literals to integer types
|
||||
/// and casts of float literals to float types.
|
||||
///
|
||||
/// **Why is this bad?** It's just unnecessary.
|
||||
/// ### Why is this bad?
|
||||
/// It's just unnecessary.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let _ = 2i32 as i32;
|
||||
/// let _ = 0.5 as f32;
|
||||
|
@ -168,17 +168,20 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts, using `as` or `pointer::cast`,
|
||||
/// ### What it does
|
||||
/// Checks for casts, using `as` or `pointer::cast`,
|
||||
/// from a less-strictly-aligned pointer to a more-strictly-aligned pointer
|
||||
///
|
||||
/// **Why is this bad?** Dereferencing the resulting pointer may be undefined
|
||||
/// ### Why is this bad?
|
||||
/// Dereferencing the resulting pointer may be undefined
|
||||
/// behavior.
|
||||
///
|
||||
/// **Known problems:** Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
|
||||
/// ### Known problems
|
||||
/// Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
|
||||
/// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like
|
||||
/// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let _ = (&1u8 as *const u8) as *const u16;
|
||||
/// let _ = (&mut 1u8 as *mut u8) as *mut u16;
|
||||
|
@ -192,9 +195,10 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts of function pointers to something other than usize
|
||||
/// ### What it does
|
||||
/// Checks for casts of function pointers to something other than usize
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
/// Casting a function pointer to anything other than usize/isize is not portable across
|
||||
/// architectures, because you end up losing bits if the target type is too small or end up with a
|
||||
/// bunch of extra bits that waste space and add more instructions to the final binary than
|
||||
|
@ -202,8 +206,7 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// Casting to isize also doesn't make sense since there are no signed addresses.
|
||||
///
|
||||
/// **Example**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// fn fun() -> i32 { 1 }
|
||||
|
@ -219,16 +222,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to
|
||||
/// ### What it does
|
||||
/// Checks for casts of a function pointer to a numeric type not wide enough to
|
||||
/// store address.
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
/// Such a cast discards some bits of the function's address. If this is intended, it would be more
|
||||
/// clearly expressed by casting to usize first, then casting the usize to the intended type (with
|
||||
/// a comment) to perform the truncation.
|
||||
///
|
||||
/// **Example**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// fn fn1() -> i16 {
|
||||
|
@ -249,15 +252,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code.
|
||||
/// ### What it does
|
||||
/// Checks for casts of `&T` to `&mut T` anywhere in the code.
|
||||
///
|
||||
/// **Why is this bad?** It’s basically guaranteed to be undefined behaviour.
|
||||
/// ### Why is this bad?
|
||||
/// It’s basically guaranteed to be undefined behaviour.
|
||||
/// `UnsafeCell` is the only way to obtain aliasable data that is considered
|
||||
/// mutable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// fn x(r: &i32) {
|
||||
/// unsafe {
|
||||
|
@ -283,18 +286,18 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions where a character literal is cast
|
||||
/// ### What it does
|
||||
/// Checks for expressions where a character literal is cast
|
||||
/// to `u8` and suggests using a byte literal instead.
|
||||
///
|
||||
/// **Why is this bad?** In general, casting values to smaller types is
|
||||
/// ### Why is this bad?
|
||||
/// In general, casting values to smaller types is
|
||||
/// error-prone and should be avoided where possible. In the particular case of
|
||||
/// converting a character literal to u8, it is easy to avoid by just using a
|
||||
/// byte literal instead. As an added bonus, `b'a'` is even slightly shorter
|
||||
/// than `'a' as u8`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// 'x' as u8
|
||||
/// ```
|
||||
|
@ -310,18 +313,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
/// ### What it does
|
||||
/// Checks for `as` casts between raw pointers without changing its mutability,
|
||||
/// namely `*const T` to `*const U` and `*mut T` to `*mut U`.
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
/// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
|
||||
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let ptr: *const u32 = &42_u32;
|
||||
/// let mut_ptr: *mut u32 = &mut 42_u32;
|
||||
|
|
|
@ -13,13 +13,13 @@ use rustc_semver::RustcVersion;
|
|||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for explicit bounds checking when casting.
|
||||
/// ### What it does
|
||||
/// Checks for explicit bounds checking when casting.
|
||||
///
|
||||
/// **Why is this bad?** Reduces the readability of statements & is error prone.
|
||||
/// ### Why is this bad?
|
||||
/// Reduces the readability of statements & is error prone.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let foo: u32 = 5;
|
||||
/// # let _ =
|
||||
|
|
|
@ -14,15 +14,19 @@ use rustc_span::source_map::Span;
|
|||
use rustc_span::{sym, BytePos};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for methods with high cognitive complexity.
|
||||
/// ### What it does
|
||||
/// Checks for methods with high cognitive complexity.
|
||||
///
|
||||
/// **Why is this bad?** Methods of high cognitive complexity tend to be hard to
|
||||
/// ### Why is this bad?
|
||||
/// Methods of high cognitive complexity tend to be hard to
|
||||
/// both read and maintain. Also LLVM will tend to optimize small methods better.
|
||||
///
|
||||
/// **Known problems:** Sometimes it's hard to find a way to reduce the
|
||||
/// ### Known problems
|
||||
/// Sometimes it's hard to find a way to reduce the
|
||||
/// complexity.
|
||||
///
|
||||
/// **Example:** No. You'll see it when you get the warning.
|
||||
/// ### Example
|
||||
/// No. You'll see it when you get the warning.
|
||||
pub COGNITIVE_COMPLEXITY,
|
||||
nursery,
|
||||
"functions that should be split up into multiple functions"
|
||||
|
|
|
@ -22,15 +22,15 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for nested `if` statements which can be collapsed
|
||||
/// ### What it does
|
||||
/// Checks for nested `if` statements which can be collapsed
|
||||
/// by `&&`-combining their conditions.
|
||||
///
|
||||
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which
|
||||
/// ### Why is this bad?
|
||||
/// Each `if`-statement adds one level of nesting, which
|
||||
/// makes code look more complex than it really is.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// if x {
|
||||
/// if y {
|
||||
|
@ -53,15 +53,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for collapsible `else { if ... }` expressions
|
||||
/// ### What it does
|
||||
/// Checks for collapsible `else { if ... }` expressions
|
||||
/// that can be collapsed to `else if ...`.
|
||||
///
|
||||
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which
|
||||
/// ### Why is this bad?
|
||||
/// Each `if`-statement adds one level of nesting, which
|
||||
/// makes code look more complex than it really is.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
///
|
||||
/// if x {
|
||||
|
|
|
@ -9,18 +9,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::{MultiSpan, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
|
||||
/// ### What it does
|
||||
/// Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
|
||||
/// without adding any branches.
|
||||
///
|
||||
/// Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
|
||||
/// cases where merging would most likely make the code more readable.
|
||||
///
|
||||
/// **Why is this bad?** It is unnecessarily verbose and complex.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// It is unnecessarily verbose and complex.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn func(opt: Option<Result<u64, String>>) {
|
||||
/// let n = match opt {
|
||||
|
|
|
@ -6,16 +6,19 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks comparison chains written with `if` that can be
|
||||
/// ### What it does
|
||||
/// Checks comparison chains written with `if` that can be
|
||||
/// rewritten with `match` and `cmp`.
|
||||
///
|
||||
/// **Why is this bad?** `if` is not guaranteed to be exhaustive and conditionals can get
|
||||
/// ### Why is this bad?
|
||||
/// `if` is not guaranteed to be exhaustive and conditionals can get
|
||||
/// repetitive
|
||||
///
|
||||
/// **Known problems:** The match statement may be slower due to the compiler
|
||||
/// ### Known problems
|
||||
/// The match statement may be slower due to the compiler
|
||||
/// not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// # fn a() {}
|
||||
/// # fn b() {}
|
||||
|
|
|
@ -16,13 +16,13 @@ use rustc_span::{source_map::Span, symbol::Symbol, BytePos};
|
|||
use std::borrow::Cow;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for consecutive `if`s with the same condition.
|
||||
/// ### What it does
|
||||
/// Checks for consecutive `if`s with the same condition.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
/// ### Why is this bad?
|
||||
/// This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// if a == b {
|
||||
/// …
|
||||
|
@ -47,15 +47,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for consecutive `if`s with the same function call.
|
||||
/// ### What it does
|
||||
/// Checks for consecutive `if`s with the same function call.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
/// ### Why is this bad?
|
||||
/// This is probably a copy & paste error.
|
||||
/// Despite the fact that function can have side effects and `if` works as
|
||||
/// intended, such an approach is implicit and can be considered a "code smell".
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// if foo() == bar {
|
||||
/// …
|
||||
|
@ -94,14 +94,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `if/else` with the same body as the *then* part
|
||||
/// ### What it does
|
||||
/// Checks for `if/else` with the same body as the *then* part
|
||||
/// and the *else* part.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
/// ### Why is this bad?
|
||||
/// This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// let foo = if … {
|
||||
/// 42
|
||||
|
@ -115,17 +115,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks if the `if` and `else` block contain shared code that can be
|
||||
/// ### What it does
|
||||
/// Checks if the `if` and `else` block contain shared code that can be
|
||||
/// moved out of the blocks.
|
||||
///
|
||||
/// **Why is this bad?** Duplicate code is less maintainable.
|
||||
/// ### Why is this bad?
|
||||
/// Duplicate code is less maintainable.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// ### Known problems
|
||||
/// * The lint doesn't check if the moved expressions modify values that are beeing used in
|
||||
/// the if condition. The suggestion can in that case modify the behavior of the program.
|
||||
/// See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// let foo = if … {
|
||||
/// println!("Hello World");
|
||||
|
|
|
@ -8,15 +8,15 @@ use rustc_span::sym;
|
|||
use if_chain::if_chain;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for types that implement `Copy` as well as
|
||||
/// ### What it does
|
||||
/// Checks for types that implement `Copy` as well as
|
||||
/// `Iterator`.
|
||||
///
|
||||
/// **Why is this bad?** Implicit copies can be confusing when working with
|
||||
/// ### Why is this bad?
|
||||
/// Implicit copies can be confusing when working with
|
||||
/// iterator combinators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// struct Countdown(u8);
|
||||
|
|
|
@ -8,13 +8,13 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
|
||||
/// ### What it does
|
||||
/// Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
|
||||
///
|
||||
/// **Why is this bad?** Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
|
||||
/// ### Why is this bad?
|
||||
/// Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// std::fs::create_dir("foo");
|
||||
|
|
|
@ -8,14 +8,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of dbg!() macro.
|
||||
/// ### What it does
|
||||
/// Checks for usage of dbg!() macro.
|
||||
///
|
||||
/// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It
|
||||
/// ### Why is this bad?
|
||||
/// `dbg!` macro is intended as a debugging tool. It
|
||||
/// should not be in version control.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// dbg!(true)
|
||||
|
|
|
@ -13,14 +13,14 @@ use rustc_span::symbol::{Ident, Symbol};
|
|||
use rustc_span::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for literal calls to `Default::default()`.
|
||||
/// ### What it does
|
||||
/// Checks for literal calls to `Default::default()`.
|
||||
///
|
||||
/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is
|
||||
/// ### Why is this bad?
|
||||
/// It's more clear to the reader to use the name of the type whose default is
|
||||
/// being gotten than the generic `Default`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let s: String = Default::default();
|
||||
|
@ -34,14 +34,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for immediate reassignment of fields initialized
|
||||
/// ### What it does
|
||||
/// Checks for immediate reassignment of fields initialized
|
||||
/// with Default::default().
|
||||
///
|
||||
/// **Why is this bad?**It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
|
||||
/// ### Why is this bad?
|
||||
///It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
|
||||
///
|
||||
/// **Known problems:** Assignments to patterns that are of tuple type are not linted.
|
||||
/// ### Known problems
|
||||
/// Assignments to patterns that are of tuple type are not linted.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```
|
||||
/// # #[derive(Default)]
|
||||
|
|
|
@ -18,7 +18,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use std::iter;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
|
||||
/// ### What it does
|
||||
/// Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
|
||||
/// inference.
|
||||
///
|
||||
/// Default numeric fallback means that if numeric types have not yet been bound to concrete
|
||||
|
@ -27,12 +28,14 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
|
||||
///
|
||||
/// **Why is this bad?** For those who are very careful about types, default numeric fallback
|
||||
/// ### Why is this bad?
|
||||
/// For those who are very careful about types, default numeric fallback
|
||||
/// can be a pitfall that cause unexpected runtime behavior.
|
||||
///
|
||||
/// **Known problems:** This lint can only be allowed at the function level or above.
|
||||
/// ### Known problems
|
||||
/// This lint can only be allowed at the function level or above.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let i = 10;
|
||||
/// let f = 1.23;
|
||||
|
|
|
@ -12,27 +12,33 @@ macro_rules! declare_deprecated_lint {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This used to check for `assert!(a == b)` and recommend
|
||||
/// ### Deprecation reason
|
||||
/// This used to check for `assert!(a == b)` and recommend
|
||||
/// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.
|
||||
pub SHOULD_ASSERT_EQ,
|
||||
"`assert!()` will be more flexible with RFC 2011"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This used to check for `Vec::extend`, which was slower than
|
||||
/// ### Deprecation reason
|
||||
/// This used to check for `Vec::extend`, which was slower than
|
||||
/// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true.
|
||||
pub EXTEND_FROM_SLICE,
|
||||
"`.extend_from_slice(_)` is a faster way to extend a Vec by a slice"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** `Range::step_by(0)` used to be linted since it's
|
||||
/// ### Deprecation reason
|
||||
/// `Range::step_by(0)` used to be linted since it's
|
||||
/// an infinite iterator, which is better expressed by `iter::repeat`,
|
||||
/// but the method has been removed for `Iterator::step_by` which panics
|
||||
/// if given a zero
|
||||
|
@ -41,27 +47,33 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This used to check for `Vec::as_slice`, which was unstable with good
|
||||
/// ### Deprecation reason
|
||||
/// This used to check for `Vec::as_slice`, which was unstable with good
|
||||
/// stable alternatives. `Vec::as_slice` has now been stabilized.
|
||||
pub UNSTABLE_AS_SLICE,
|
||||
"`Vec::as_slice` has been stabilized in 1.7"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This used to check for `Vec::as_mut_slice`, which was unstable with good
|
||||
/// ### Deprecation reason
|
||||
/// This used to check for `Vec::as_mut_slice`, which was unstable with good
|
||||
/// stable alternatives. `Vec::as_mut_slice` has now been stabilized.
|
||||
pub UNSTABLE_AS_MUT_SLICE,
|
||||
"`Vec::as_mut_slice` has been stabilized in 1.7"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint should never have applied to non-pointer types, as transmuting
|
||||
/// ### Deprecation reason
|
||||
/// This lint should never have applied to non-pointer types, as transmuting
|
||||
/// between non-pointer types of differing alignment is well-defined behavior (it's semantically
|
||||
/// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
|
||||
/// cast_ptr_alignment and transmute_ptr_to_ptr.
|
||||
|
@ -70,9 +82,11 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint is too subjective, not having a good reason for being in clippy.
|
||||
/// ### Deprecation reason
|
||||
/// This lint is too subjective, not having a good reason for being in clippy.
|
||||
/// Additionally, compound assignment operators may be overloaded separately from their non-assigning
|
||||
/// counterparts, so this lint may suggest a change in behavior or the code may not compile.
|
||||
pub ASSIGN_OPS,
|
||||
|
@ -80,9 +94,11 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** The original rule will only lint for `if let`. After
|
||||
/// ### Deprecation reason
|
||||
/// The original rule will only lint for `if let`. After
|
||||
/// making it support to lint `match`, naming as `if let` is not suitable for it.
|
||||
/// So, this lint is deprecated.
|
||||
pub IF_LET_REDUNDANT_PATTERN_MATCHING,
|
||||
|
@ -90,9 +106,11 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint used to suggest replacing `let mut vec =
|
||||
/// ### Deprecation reason
|
||||
/// This lint used to suggest replacing `let mut vec =
|
||||
/// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The
|
||||
/// replacement has very different performance characteristics so the lint is
|
||||
/// deprecated.
|
||||
|
@ -101,51 +119,63 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint has been superseded by #[must_use] in rustc.
|
||||
/// ### Deprecation reason
|
||||
/// This lint has been superseded by #[must_use] in rustc.
|
||||
pub UNUSED_COLLECT,
|
||||
"`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** Associated-constants are now preferred.
|
||||
/// ### Deprecation reason
|
||||
/// Associated-constants are now preferred.
|
||||
pub REPLACE_CONSTS,
|
||||
"associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** The regex! macro does not exist anymore.
|
||||
/// ### Deprecation reason
|
||||
/// The regex! macro does not exist anymore.
|
||||
pub REGEX_MACRO,
|
||||
"the regex! macro has been removed from the regex crate in 2018"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint has been replaced by `manual_find_map`, a
|
||||
/// ### Deprecation reason
|
||||
/// This lint has been replaced by `manual_find_map`, a
|
||||
/// more specific lint.
|
||||
pub FIND_MAP,
|
||||
"this lint has been replaced by `manual_find_map`, a more specific lint"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint has been replaced by `manual_filter_map`, a
|
||||
/// ### Deprecation reason
|
||||
/// This lint has been replaced by `manual_filter_map`, a
|
||||
/// more specific lint.
|
||||
pub FILTER_MAP,
|
||||
"this lint has been replaced by `manual_filter_map`, a more specific lint"
|
||||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** The `avoid_breaking_exported_api` config option was added, which
|
||||
/// ### Deprecation reason
|
||||
/// The `avoid_breaking_exported_api` config option was added, which
|
||||
/// enables the `enum_variant_names` lint for public items.
|
||||
/// ```
|
||||
pub PUB_ENUM_VARIANT_NAMES,
|
||||
|
@ -153,9 +183,11 @@ declare_deprecated_lint! {
|
|||
}
|
||||
|
||||
declare_deprecated_lint! {
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
/// ### What it does
|
||||
/// Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** The `avoid_breaking_exported_api` config option was added, which
|
||||
/// ### Deprecation reason
|
||||
/// The `avoid_breaking_exported_api` config option was added, which
|
||||
/// enables the `wrong_self_conversion` lint for public items.
|
||||
pub WRONG_PUB_SELF_CONVENTION,
|
||||
"set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items"
|
||||
|
|
|
@ -11,12 +11,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::{symbol::sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for explicit `deref()` or `deref_mut()` method calls.
|
||||
/// ### What it does
|
||||
/// Checks for explicit `deref()` or `deref_mut()` method calls.
|
||||
///
|
||||
/// **Why is this bad?** Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
|
||||
/// ### Why is this bad?
|
||||
/// Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
|
||||
/// when not part of a method chain.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// use std::ops::Deref;
|
||||
/// let a: &mut String = &mut String::from("foo");
|
||||
|
|
|
@ -15,10 +15,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq`
|
||||
/// ### What it does
|
||||
/// Checks for deriving `Hash` but implementing `PartialEq`
|
||||
/// explicitly or vice versa.
|
||||
///
|
||||
/// **Why is this bad?** The implementation of these traits must agree (for
|
||||
/// ### Why is this bad?
|
||||
/// The implementation of these traits must agree (for
|
||||
/// example for use with `HashMap`) so it’s probably a bad idea to use a
|
||||
/// default-generated `Hash` implementation with an explicitly defined
|
||||
/// `PartialEq`. In particular, the following must hold for any type:
|
||||
|
@ -27,9 +29,7 @@ declare_clippy_lint! {
|
|||
/// k1 == k2 ⇒ hash(k1) == hash(k2)
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// #[derive(Hash)]
|
||||
/// struct Foo;
|
||||
|
@ -44,10 +44,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for deriving `Ord` but implementing `PartialOrd`
|
||||
/// ### What it does
|
||||
/// Checks for deriving `Ord` but implementing `PartialOrd`
|
||||
/// explicitly or vice versa.
|
||||
///
|
||||
/// **Why is this bad?** The implementation of these traits must agree (for
|
||||
/// ### Why is this bad?
|
||||
/// The implementation of these traits must agree (for
|
||||
/// example for use with `sort`) so it’s probably a bad idea to use a
|
||||
/// default-generated `Ord` implementation with an explicitly defined
|
||||
/// `PartialOrd`. In particular, the following must hold for any type
|
||||
|
@ -57,10 +59,7 @@ declare_clippy_lint! {
|
|||
/// k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// #[derive(Ord, PartialEq, Eq)]
|
||||
/// struct Foo;
|
||||
|
@ -95,18 +94,21 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for explicit `Clone` implementations for `Copy`
|
||||
/// ### What it does
|
||||
/// Checks for explicit `Clone` implementations for `Copy`
|
||||
/// types.
|
||||
///
|
||||
/// **Why is this bad?** To avoid surprising behaviour, these traits should
|
||||
/// ### Why is this bad?
|
||||
/// To avoid surprising behaviour, these traits should
|
||||
/// agree and the behaviour of `Copy` cannot be overridden. In almost all
|
||||
/// situations a `Copy` type should have a `Clone` implementation that does
|
||||
/// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
|
||||
/// gets you.
|
||||
///
|
||||
/// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925
|
||||
/// ### Known problems
|
||||
/// Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// #[derive(Copy)]
|
||||
/// struct Foo;
|
||||
|
@ -121,16 +123,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for deriving `serde::Deserialize` on a type that
|
||||
/// ### What it does
|
||||
/// Checks for deriving `serde::Deserialize` on a type that
|
||||
/// has methods using `unsafe`.
|
||||
///
|
||||
/// **Why is this bad?** Deriving `serde::Deserialize` will create a constructor
|
||||
/// ### Why is this bad?
|
||||
/// Deriving `serde::Deserialize` will create a constructor
|
||||
/// that may violate invariants hold by another constructor.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
|
|
|
@ -8,15 +8,14 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Denies the configured methods and functions in clippy.toml
|
||||
/// ### What it does
|
||||
/// Denies the configured methods and functions in clippy.toml
|
||||
///
|
||||
/// **Why is this bad?** Some methods are undesirable in certain contexts,
|
||||
/// ### Why is this bad?
|
||||
/// Some methods are undesirable in certain contexts,
|
||||
/// and it's beneficial to lint for them as needed.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// An example clippy.toml configuration:
|
||||
/// ```toml
|
||||
/// # clippy.toml
|
||||
|
|
|
@ -6,7 +6,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use unicode_script::{Script, UnicodeScript};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of unicode scripts other than those explicitly allowed
|
||||
/// ### What it does
|
||||
/// Checks for usage of unicode scripts other than those explicitly allowed
|
||||
/// by the lint config.
|
||||
///
|
||||
/// This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
|
||||
|
@ -19,7 +20,8 @@ declare_clippy_lint! {
|
|||
/// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
|
||||
/// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
|
||||
///
|
||||
/// **Why is this bad?** It may be not desired to have many different scripts for
|
||||
/// ### Why is this bad?
|
||||
/// It may be not desired to have many different scripts for
|
||||
/// identifiers in the codebase.
|
||||
///
|
||||
/// Note that if you only want to allow plain English, you might want to use
|
||||
|
@ -27,9 +29,7 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Assuming that `clippy.toml` contains the following line:
|
||||
/// // allowed-locales = ["Latin", "Cyrillic"]
|
||||
|
|
|
@ -2,27 +2,24 @@ use clippy_utils::diagnostics::span_lint;
|
|||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::{
|
||||
def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind,
|
||||
def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, PrimTy, TraitBoundModifier, Ty, TyKind, UseKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Denies the configured types in clippy.toml.
|
||||
/// ### What it does
|
||||
/// Denies the configured types in clippy.toml.
|
||||
///
|
||||
/// **Why is this bad?** Some types are undesirable in certain contexts.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// N.B. There is no way to ban primitive types.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Some types are undesirable in certain contexts.
|
||||
///
|
||||
/// ### Example:
|
||||
/// An example clippy.toml configuration:
|
||||
/// ```toml
|
||||
/// # clippy.toml
|
||||
/// disallowed-methods = ["std::collections::BTreeMap"]
|
||||
/// disallowed-types = ["std::collections::BTreeMap"]
|
||||
/// ```
|
||||
///
|
||||
/// ```rust,ignore
|
||||
|
@ -42,7 +39,8 @@ declare_clippy_lint! {
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct DisallowedType {
|
||||
disallowed: FxHashSet<Vec<Symbol>>,
|
||||
def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
|
||||
def_ids: FxHashSet<DefId>,
|
||||
prim_tys: FxHashSet<PrimTy>,
|
||||
}
|
||||
|
||||
impl DisallowedType {
|
||||
|
@ -53,6 +51,23 @@ impl DisallowedType {
|
|||
.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 std::thread;
|
|||
use url::Url;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the presence of `_`, `::` or camel-case words
|
||||
/// ### What it does
|
||||
/// Checks for the presence of `_`, `::` or camel-case words
|
||||
/// outside ticks in documentation.
|
||||
///
|
||||
/// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and
|
||||
/// ### Why is this bad?
|
||||
/// *Rustdoc* supports markdown formatting, `_`, `::` and
|
||||
/// camel-case probably indicates some code which should be included between
|
||||
/// ticks. `_` can also be used for emphasis in markdown, this lint tries to
|
||||
/// consider that.
|
||||
///
|
||||
/// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks
|
||||
/// ### Known problems
|
||||
/// Lots of bad docs won’t be fixed, what the lint checks
|
||||
/// for is limited, and there are still false positives. HTML elements and their
|
||||
/// content are not linted.
|
||||
///
|
||||
|
@ -47,7 +50,7 @@ declare_clippy_lint! {
|
|||
/// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
|
||||
/// would fail.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// /// Do something with the foo_bar parameter. See also
|
||||
/// /// that::other::module::foo.
|
||||
|
@ -68,15 +71,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the doc comments of publicly visible
|
||||
/// ### What it does
|
||||
/// Checks for the doc comments of publicly visible
|
||||
/// unsafe functions and warns if there is no `# Safety` section.
|
||||
///
|
||||
/// **Why is this bad?** Unsafe functions should document their safety
|
||||
/// ### Why is this bad?
|
||||
/// Unsafe functions should document their safety
|
||||
/// preconditions, so that users can be sure they are using them safely.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
///# type Universe = ();
|
||||
/// /// This function should really be documented
|
||||
|
@ -102,16 +105,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks the doc comments of publicly visible functions that
|
||||
/// ### What it does
|
||||
/// Checks the doc comments of publicly visible functions that
|
||||
/// return a `Result` type and warns if there is no `# Errors` section.
|
||||
///
|
||||
/// **Why is this bad?** Documenting the type of errors that can be returned from a
|
||||
/// ### Why is this bad?
|
||||
/// Documenting the type of errors that can be returned from a
|
||||
/// function can help callers write code to handle the errors appropriately.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
///
|
||||
/// ### Examples
|
||||
/// Since the following function returns a `Result` it has an `# Errors` section in
|
||||
/// its doc comment:
|
||||
///
|
||||
|
@ -131,16 +133,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks the doc comments of publicly visible functions that
|
||||
/// ### What it does
|
||||
/// Checks the doc comments of publicly visible functions that
|
||||
/// may panic and warns if there is no `# Panics` section.
|
||||
///
|
||||
/// **Why is this bad?** Documenting the scenarios in which panicking occurs
|
||||
/// ### Why is this bad?
|
||||
/// Documenting the scenarios in which panicking occurs
|
||||
/// can help callers who do not want to panic to avoid those situations.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
///
|
||||
/// ### Examples
|
||||
/// Since the following function may panic it has a `# Panics` section in
|
||||
/// its doc comment:
|
||||
///
|
||||
|
@ -162,14 +163,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `fn main() { .. }` in doctests
|
||||
/// ### What it does
|
||||
/// Checks for `fn main() { .. }` in doctests
|
||||
///
|
||||
/// **Why is this bad?** The test can be shorter (and likely more readable)
|
||||
/// ### Why is this bad?
|
||||
/// The test can be shorter (and likely more readable)
|
||||
/// if the `fn main()` is left implicit.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ``````rust
|
||||
/// /// An example of a doctest with a `main()` function
|
||||
/// ///
|
||||
|
|
|
@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for double comparisons that could be simplified to a single expression.
|
||||
/// ### What it does
|
||||
/// Checks for double comparisons that could be simplified to a single expression.
|
||||
///
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
/// ### Why is this bad?
|
||||
/// Readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// # let y = 2;
|
||||
|
|
|
@ -4,14 +4,14 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for unnecessary double parentheses.
|
||||
/// ### What it does
|
||||
/// Checks for unnecessary double parentheses.
|
||||
///
|
||||
/// **Why is this bad?** This makes code harder to read and might indicate a
|
||||
/// ### Why is this bad?
|
||||
/// This makes code harder to read and might indicate a
|
||||
/// mistake.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// fn simple_double_parens() -> i32 {
|
||||
|
|
|
@ -8,17 +8,17 @@ use rustc_middle::ty;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
|
||||
/// ### What it does
|
||||
/// Checks for calls to `std::mem::drop` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `drop` on a reference will only drop the
|
||||
/// ### Why is this bad?
|
||||
/// Calling `drop` on a reference will only drop the
|
||||
/// reference itself, which is a no-op. It will not call the `drop` method (from
|
||||
/// the `Drop` trait implementation) on the underlying referenced value, which
|
||||
/// is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// let mut lock_guard = mutex.lock();
|
||||
/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
|
||||
|
@ -31,17 +31,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a reference
|
||||
/// ### What it does
|
||||
/// Checks for calls to `std::mem::forget` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `forget` on a reference will only forget the
|
||||
/// ### Why is this bad?
|
||||
/// Calling `forget` on a reference will only forget the
|
||||
/// reference itself, which is a no-op. It will not forget the underlying
|
||||
/// referenced
|
||||
/// value, which is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = Box::new(1);
|
||||
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
|
||||
|
@ -52,16 +52,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a value
|
||||
/// ### What it does
|
||||
/// Checks for calls to `std::mem::drop` with a value
|
||||
/// that derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that
|
||||
/// ### Why is this bad?
|
||||
/// Calling `std::mem::drop` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the
|
||||
|
@ -73,10 +73,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a value that
|
||||
/// ### What it does
|
||||
/// Checks for calls to `std::mem::forget` with a value that
|
||||
/// derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that
|
||||
/// ### Why is this bad?
|
||||
/// Calling `std::mem::forget` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
|
@ -86,9 +88,7 @@ declare_clippy_lint! {
|
|||
/// there
|
||||
/// is nothing for `std::mem::forget` to ignore.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the
|
||||
|
|
|
@ -12,15 +12,15 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
|||
use clippy_utils::paths;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds
|
||||
/// ### What it does
|
||||
/// Checks for calculation of subsecond microseconds or milliseconds
|
||||
/// from other `Duration` methods.
|
||||
///
|
||||
/// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or
|
||||
/// ### Why is this bad?
|
||||
/// It's more concise to call `Duration::subsec_micros()` or
|
||||
/// `Duration::subsec_millis()` than to calculate them.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # use std::time::Duration;
|
||||
/// let dur = Duration::new(5, 0);
|
||||
|
|
|
@ -7,14 +7,14 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
|
||||
/// ### What it does
|
||||
/// Checks for usage of if expressions with an `else if` branch,
|
||||
/// but without a final `else` branch.
|
||||
///
|
||||
/// **Why is this bad?** Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
|
||||
/// ### Why is this bad?
|
||||
/// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # fn a() {}
|
||||
/// # fn b() {}
|
||||
|
|
|
@ -6,13 +6,15 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `enum`s with no variants.
|
||||
/// ### What it does
|
||||
/// Checks for `enum`s with no variants.
|
||||
///
|
||||
/// As of this writing, the `never_type` is still a
|
||||
/// nightly-only experimental API. Therefore, this lint is only triggered
|
||||
/// if the `never_type` is enabled.
|
||||
///
|
||||
/// **Why is this bad?** If you want to introduce a type which
|
||||
/// ### Why is this bad?
|
||||
/// If you want to introduce a type which
|
||||
/// can't be instantiated, you should use `!` (the primitive type "never"),
|
||||
/// or a wrapper around it, because `!` has more extensive
|
||||
/// compiler support (type inference, etc...) and wrappers
|
||||
|
@ -20,10 +22,7 @@ declare_clippy_lint! {
|
|||
/// For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html)
|
||||
///
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// enum Test {}
|
||||
|
|
|
@ -16,12 +16,15 @@ use rustc_span::{Span, SyntaxContext, DUMMY_SP};
|
|||
use std::fmt::Write;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap`
|
||||
/// ### What it does
|
||||
/// Checks for uses of `contains_key` + `insert` on `HashMap`
|
||||
/// or `BTreeMap`.
|
||||
///
|
||||
/// **Why is this bad?** Using `entry` is more efficient.
|
||||
/// ### Why is this bad?
|
||||
/// Using `entry` is more efficient.
|
||||
///
|
||||
/// **Known problems:** The suggestion may have type inference errors in some cases. e.g.
|
||||
/// ### Known problems
|
||||
/// The suggestion may have type inference errors in some cases. e.g.
|
||||
/// ```rust
|
||||
/// let mut map = std::collections::HashMap::new();
|
||||
/// let _ = if !map.contains_key(&0) {
|
||||
|
@ -31,7 +34,7 @@ declare_clippy_lint! {
|
|||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # use std::collections::HashMap;
|
||||
/// # let mut map = HashMap::new();
|
||||
|
|
|
@ -11,15 +11,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use std::convert::TryFrom;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for C-like enumerations that are
|
||||
/// ### What it does
|
||||
/// Checks for C-like enumerations that are
|
||||
/// `repr(isize/usize)` and have values that don't fit into an `i32`.
|
||||
///
|
||||
/// **Why is this bad?** This will truncate the variant value on 32 bit
|
||||
/// ### Why is this bad?
|
||||
/// This will truncate the variant value on 32 bit
|
||||
/// architectures, but works fine on 64 bit.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # #[cfg(target_pointer_width = "64")]
|
||||
/// #[repr(usize)]
|
||||
|
|
|
@ -10,15 +10,15 @@ use rustc_span::source_map::Span;
|
|||
use rustc_span::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects enumeration variants that are prefixed or suffixed
|
||||
/// ### What it does
|
||||
/// Detects enumeration variants that are prefixed or suffixed
|
||||
/// by the same characters.
|
||||
///
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant,
|
||||
/// ### Why is this bad?
|
||||
/// Enumeration variant names should specify their variant,
|
||||
/// not repeat the enumeration name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
|
@ -40,14 +40,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects type names that are prefixed or suffixed by the
|
||||
/// ### What it does
|
||||
/// Detects type names that are prefixed or suffixed by the
|
||||
/// containing module's name.
|
||||
///
|
||||
/// **Why is this bad?** It requires the user to type the module name twice.
|
||||
/// ### Why is this bad?
|
||||
/// It requires the user to type the module name twice.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// mod cake {
|
||||
/// struct BlackForestCake;
|
||||
|
@ -65,10 +65,12 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for modules that have the same name as their
|
||||
/// ### What it does
|
||||
/// Checks for modules that have the same name as their
|
||||
/// parent module
|
||||
///
|
||||
/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and
|
||||
/// ### Why is this bad?
|
||||
/// A typical beginner mistake is to have `mod foo;` and
|
||||
/// again `mod foo { ..
|
||||
/// }` in `foo.rs`.
|
||||
/// The expectation is that items inside the inner `mod foo { .. }` are then
|
||||
|
@ -78,9 +80,7 @@ declare_clippy_lint! {
|
|||
/// If this is done on purpose, it would be better to choose a more
|
||||
/// representative module name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// // lib.rs
|
||||
/// mod foo;
|
||||
|
|
|
@ -9,18 +9,21 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for equal operands to comparison, logical and
|
||||
/// ### What it does
|
||||
/// Checks for equal operands to comparison, logical and
|
||||
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
|
||||
/// `||`, `&`, `|`, `^`, `-` and `/`).
|
||||
///
|
||||
/// **Why is this bad?** This is usually just a typo or a copy and paste error.
|
||||
/// ### Why is this bad?
|
||||
/// This is usually just a typo or a copy and paste error.
|
||||
///
|
||||
/// **Known problems:** False negatives: We had some false positives regarding
|
||||
/// ### Known problems
|
||||
/// False negatives: We had some false positives regarding
|
||||
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance
|
||||
/// of `x.pop() && x.pop()`), so we removed matching any function or method
|
||||
/// calls. We may introduce a list of known pure functions in the future.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// if x + 1 == x + 1 {}
|
||||
|
@ -37,15 +40,18 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for arguments to `==` which have their address
|
||||
/// ### What it does
|
||||
/// Checks for arguments to `==` which have their address
|
||||
/// taken to satisfy a bound
|
||||
/// and suggests to dereference the other argument instead
|
||||
///
|
||||
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
|
||||
/// ### Why is this bad?
|
||||
/// It is more idiomatic to dereference the other argument.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
/// ### Known problems
|
||||
/// None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// // Bad
|
||||
/// &x == y
|
||||
|
|
|
@ -6,15 +6,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for erasing operations, e.g., `x * 0`.
|
||||
/// ### What it does
|
||||
/// Checks for erasing operations, e.g., `x * 0`.
|
||||
///
|
||||
/// **Why is this bad?** The whole expression can be replaced by zero.
|
||||
/// ### Why is this bad?
|
||||
/// The whole expression can be replaced by zero.
|
||||
/// This is most likely not the intended outcome and should probably be
|
||||
/// corrected
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = 1;
|
||||
/// 0 / x;
|
||||
|
|
|
@ -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_middle::ty::{self, ClosureKind, Ty};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for closures which just call another function where
|
||||
/// ### What it does
|
||||
/// Checks for closures which just call another function where
|
||||
/// the function can be called directly. `unsafe` functions or calls where types
|
||||
/// get adjusted are ignored.
|
||||
///
|
||||
/// **Why is this bad?** Needlessly creating a closure adds code for no benefit
|
||||
/// ### Why is this bad?
|
||||
/// Needlessly creating a closure adds code for no benefit
|
||||
/// and gives the optimizer more work.
|
||||
///
|
||||
/// **Known problems:** If creating the closure inside the closure has a side-
|
||||
/// ### Known problems
|
||||
/// If creating the closure inside the closure has a side-
|
||||
/// effect then moving the closure creation out will change when that side-
|
||||
/// effect runs.
|
||||
/// See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// xs.map(|x| foo(x))
|
||||
|
@ -42,17 +45,20 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for closures which only invoke a method on the closure
|
||||
/// ### What it does
|
||||
/// Checks for closures which only invoke a method on the closure
|
||||
/// argument and can be replaced by referencing the method directly.
|
||||
///
|
||||
/// **Why is this bad?** It's unnecessary to create the closure.
|
||||
/// ### Why is this bad?
|
||||
/// It's unnecessary to create the closure.
|
||||
///
|
||||
/// **Known problems:** [#3071](https://github.com/rust-lang/rust-clippy/issues/3071),
|
||||
/// ### Known problems
|
||||
/// [#3071](https://github.com/rust-lang/rust-clippy/issues/3071),
|
||||
/// [#3942](https://github.com/rust-lang/rust-clippy/issues/3942),
|
||||
/// [#4002](https://github.com/rust-lang/rust-clippy/issues/4002)
|
||||
///
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// Some('a').map(|s| s.to_uppercase());
|
||||
/// ```
|
||||
|
|
|
@ -9,17 +9,20 @@ use rustc_middle::ty;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for a read and a write to the same variable where
|
||||
/// ### What it does
|
||||
/// Checks for a read and a write to the same variable where
|
||||
/// whether the read occurs before or after the write depends on the evaluation
|
||||
/// order of sub-expressions.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// ### Why is this bad?
|
||||
/// It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Code which intentionally depends on the evaluation
|
||||
/// ### Known problems
|
||||
/// Code which intentionally depends on the evaluation
|
||||
/// order, or which is correct for any evaluation order.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let mut x = 0;
|
||||
///
|
||||
|
@ -43,16 +46,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for diverging calls that are not match arms or
|
||||
/// ### What it does
|
||||
/// Checks for diverging calls that are not match arms or
|
||||
/// statements.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// ### Why is this bad?
|
||||
/// It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Someone might want to use `some_bool || panic!()` as a
|
||||
/// ### Known problems
|
||||
/// Someone might want to use `some_bool || panic!()` as a
|
||||
/// shorthand.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,no_run
|
||||
/// # fn b() -> bool { true }
|
||||
/// # fn c() -> bool { true }
|
||||
|
|
|
@ -8,19 +8,19 @@ use rustc_span::{sym, Span};
|
|||
use std::convert::TryInto;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for excessive
|
||||
/// ### What it does
|
||||
/// Checks for excessive
|
||||
/// use of bools in structs.
|
||||
///
|
||||
/// **Why is this bad?** Excessive bools in a struct
|
||||
/// ### Why is this bad?
|
||||
/// Excessive bools in a struct
|
||||
/// is often a sign that it's used as a state machine,
|
||||
/// which is much better implemented as an enum.
|
||||
/// If it's not the case, excessive bools usually benefit
|
||||
/// from refactoring into two-variant enums for better
|
||||
/// readability and API.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// struct S {
|
||||
|
@ -44,19 +44,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for excessive use of
|
||||
/// ### What it does
|
||||
/// Checks for excessive use of
|
||||
/// bools in function definitions.
|
||||
///
|
||||
/// **Why is this bad?** Calls to such functions
|
||||
/// ### Why is this bad?
|
||||
/// Calls to such functions
|
||||
/// are confusing and error prone, because it's
|
||||
/// hard to remember argument order and you have
|
||||
/// no type system support to back you up. Using
|
||||
/// two-variant enums instead of bools often makes
|
||||
/// API easier to use.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust,ignore
|
||||
/// fn f(is_round: bool, is_hot: bool) { ... }
|
||||
|
|
|
@ -8,16 +8,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
|
||||
/// ### What it does
|
||||
/// Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
|
||||
///
|
||||
/// **Why is this bad?** Exhaustive enums are typically fine, but a project which does
|
||||
/// ### Why is this bad?
|
||||
/// Exhaustive enums are typically fine, but a project which does
|
||||
/// not wish to make a stability commitment around exported enums may wish to
|
||||
/// disable them by default.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// enum Foo {
|
||||
/// Bar,
|
||||
|
@ -38,16 +37,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
|
||||
/// ### What it does
|
||||
/// Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
|
||||
///
|
||||
/// **Why is this bad?** Exhaustive structs are typically fine, but a project which does
|
||||
/// ### Why is this bad?
|
||||
/// Exhaustive structs are typically fine, but a project which does
|
||||
/// not wish to make a stability commitment around exported structs may wish to
|
||||
/// disable them by default.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// struct Foo {
|
||||
/// bar: u8,
|
||||
|
|
|
@ -6,15 +6,15 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** `exit()` terminates the program and doesn't provide a
|
||||
/// ### What it does
|
||||
/// `exit()` terminates the program and doesn't provide a
|
||||
/// stack trace.
|
||||
///
|
||||
/// **Why is this bad?** Ideally a program is terminated by finishing
|
||||
/// ### Why is this bad?
|
||||
/// Ideally a program is terminated by finishing
|
||||
/// the main function.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// std::process::exit(0)
|
||||
/// ```
|
||||
|
|
|
@ -9,14 +9,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be
|
||||
/// ### What it does
|
||||
/// Checks for usage of `write!()` / `writeln()!` which can be
|
||||
/// replaced with `(e)print!()` / `(e)println!()`
|
||||
///
|
||||
/// **Why is this bad?** Using `(e)println! is clearer and more concise
|
||||
/// ### Why is this bad?
|
||||
/// Using `(e)println! is clearer and more concise
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # use std::io::Write;
|
||||
/// # let bar = "furchtbar";
|
||||
|
|
|
@ -10,13 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::{sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
|
||||
/// ### What it does
|
||||
/// Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
|
||||
///
|
||||
/// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure.
|
||||
/// ### Why is this bad?
|
||||
/// `TryFrom` should be used if there's a possibility of failure.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// struct Foo(i32);
|
||||
///
|
||||
|
|
|
@ -11,30 +11,32 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Spanned;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for statements of the form `(a - b) < f32::EPSILON` or
|
||||
/// `(a - b) < f64::EPSILON`. Notes the missing `.abs()`.
|
||||
///
|
||||
/// **Why is this bad?** The code without `.abs()` is more likely to have a bug.
|
||||
///
|
||||
/// **Known problems:** If the user can ensure that b is larger than a, the `.abs()` is
|
||||
/// technically unneccessary. However, it will make the code more robust and doesn't have any
|
||||
/// large performance implications. If the abs call was deliberately left out for performance
|
||||
/// reasons, it is probably better to state this explicitly in the code, which then can be done
|
||||
/// with an allow.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
|
||||
/// (a - b) < f32::EPSILON
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
|
||||
/// (a - b).abs() < f32::EPSILON
|
||||
/// }
|
||||
/// ```
|
||||
/// ### What it does
|
||||
/// Checks for statements of the form `(a - b) < f32::EPSILON` or
|
||||
/// `(a - b) < f64::EPSILON`. Notes the missing `.abs()`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The code without `.abs()` is more likely to have a bug.
|
||||
///
|
||||
/// ### Known problems
|
||||
/// If the user can ensure that b is larger than a, the `.abs()` is
|
||||
/// technically unneccessary. However, it will make the code more robust and doesn't have any
|
||||
/// large performance implications. If the abs call was deliberately left out for performance
|
||||
/// reasons, it is probably better to state this explicitly in the code, which then can be done
|
||||
/// with an allow.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
|
||||
/// (a - b) < f32::EPSILON
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// pub fn is_roughly_equal(a: f32, b: f32) -> bool {
|
||||
/// (a - b).abs() < f32::EPSILON
|
||||
/// }
|
||||
/// ```
|
||||
pub FLOAT_EQUALITY_WITHOUT_ABS,
|
||||
suspicious,
|
||||
"float equality check without `.abs()`"
|
||||
|
|
|
@ -10,15 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use std::fmt;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for float literals with a precision greater
|
||||
/// ### What it does
|
||||
/// Checks for float literals with a precision greater
|
||||
/// than that supported by the underlying type.
|
||||
///
|
||||
/// **Why is this bad?** Rust will truncate the literal silently.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Rust will truncate the literal silently.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let v: f32 = 0.123_456_789_9;
|
||||
|
@ -34,16 +33,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for whole number float literals that
|
||||
/// ### What it does
|
||||
/// Checks for whole number float literals that
|
||||
/// cannot be represented as the underlying type without loss.
|
||||
///
|
||||
/// **Why is this bad?** Rust will silently lose precision during
|
||||
/// ### Why is this bad?
|
||||
/// Rust will silently lose precision during
|
||||
/// conversion to a float.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let _: f32 = 16_777_217.0; // 16_777_216.0
|
||||
|
|
|
@ -18,16 +18,15 @@ use std::f64::consts as f64_consts;
|
|||
use sugg::Sugg;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Looks for floating-point expressions that
|
||||
/// ### What it does
|
||||
/// Looks for floating-point expressions that
|
||||
/// can be expressed using built-in methods to improve accuracy
|
||||
/// at the cost of performance.
|
||||
///
|
||||
/// **Why is this bad?** Negatively impacts accuracy.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Negatively impacts accuracy.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let a = 3f32;
|
||||
/// let _ = a.powf(1.0 / 3.0);
|
||||
|
@ -49,16 +48,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Looks for floating-point expressions that
|
||||
/// ### What it does
|
||||
/// Looks for floating-point expressions that
|
||||
/// can be expressed using built-in methods to improve both
|
||||
/// accuracy and performance.
|
||||
///
|
||||
/// **Why is this bad?** Negatively impacts accuracy and performance.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Negatively impacts accuracy and performance.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// use std::f32::consts::E;
|
||||
///
|
||||
|
|
|
@ -13,18 +13,18 @@ use rustc_span::symbol::kw;
|
|||
use rustc_span::{sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the use of `format!("string literal with no
|
||||
/// ### What it does
|
||||
/// Checks for the use of `format!("string literal with no
|
||||
/// argument")` and `format!("{}", foo)` where `foo` is a string.
|
||||
///
|
||||
/// **Why is this bad?** There is no point of doing that. `format!("foo")` can
|
||||
/// ### Why is this bad?
|
||||
/// There is no point of doing that. `format!("foo")` can
|
||||
/// be replaced by `"foo".to_owned()` if you really need a `String`. The even
|
||||
/// worse `&format!("foo")` is often encountered in the wild. `format!("{}",
|
||||
/// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
|
||||
/// if `foo: &str`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
///
|
||||
/// // Bad
|
||||
|
|
|
@ -9,15 +9,15 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-`
|
||||
/// ### What it does
|
||||
/// Checks for use of the non-existent `=*`, `=!` and `=-`
|
||||
/// operators.
|
||||
///
|
||||
/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or
|
||||
/// ### Why is this bad?
|
||||
/// This is either a typo of `*=`, `!=` or `-=` or
|
||||
/// confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
|
||||
/// ```
|
||||
|
@ -27,15 +27,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks the formatting of a unary operator on the right hand side
|
||||
/// ### What it does
|
||||
/// Checks the formatting of a unary operator on the right hand side
|
||||
/// of a binary operator. It lints if there is no space between the binary and unary operators,
|
||||
/// but there is a space between the unary and its operand.
|
||||
///
|
||||
/// **Why is this bad?** This is either a typo in the binary operator or confusing.
|
||||
/// ### Why is this bad?
|
||||
/// This is either a typo in the binary operator or confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// if foo <- 30 { // this should be `foo < -30` but looks like a different operator
|
||||
/// }
|
||||
|
@ -49,15 +49,15 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for formatting of `else`. It lints if the `else`
|
||||
/// ### What it does
|
||||
/// Checks for formatting of `else`. It lints if the `else`
|
||||
/// is followed immediately by a newline or the `else` seems to be missing.
|
||||
///
|
||||
/// **Why is this bad?** This is probably some refactoring remnant, even if the
|
||||
/// ### Why is this bad?
|
||||
/// This is probably some refactoring remnant, even if the
|
||||
/// code is correct, it might look confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// if foo {
|
||||
/// } { // looks like an `else` is missing here
|
||||
|
@ -85,14 +85,14 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for possible missing comma in an array. It lints if
|
||||
/// ### What it does
|
||||
/// Checks for possible missing comma in an array. It lints if
|
||||
/// an array element is a binary operator expression and it lies on two lines.
|
||||
///
|
||||
/// **Why is this bad?** This could lead to unexpected results.
|
||||
/// ### Why is this bad?
|
||||
/// This could lead to unexpected results.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// let a = &[
|
||||
/// -1, -2, -3 // <= no comma here
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::paths::INTO;
|
||||
use clippy_utils::{match_def_path, meets_msrv, msrvs};
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
|
||||
/// ### What it does
|
||||
/// Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
|
||||
///
|
||||
/// **Why is this bad?** According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// struct StringWrapper(String);
|
||||
///
|
||||
|
@ -62,7 +61,7 @@ impl LateLintPass<'_> for FromOverInto {
|
|||
if_chain! {
|
||||
if let hir::ItemKind::Impl{ .. } = &item.kind;
|
||||
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
|
||||
if match_def_path(cx, impl_trait_ref.def_id, &INTO);
|
||||
if cx.tcx.is_diagnostic_item(sym::into_trait, impl_trait_ref.def_id);
|
||||
|
||||
then {
|
||||
span_lint_and_help(
|
||||
|
|
|
@ -10,20 +10,22 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::symbol::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
/// ### What it does
|
||||
///
|
||||
/// Checks for function invocations of the form `primitive::from_str_radix(s, 10)`
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// This specific common use case can be rewritten as `s.parse::<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_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_span::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions with too many parameters.
|
||||
/// ### What it does
|
||||
/// Checks for functions with too many parameters.
|
||||
///
|
||||
/// **Why is this bad?** Functions with lots of parameters are considered bad
|
||||
/// ### Why is this bad?
|
||||
/// Functions with lots of parameters are considered bad
|
||||
/// style and reduce readability (“what does the 5th parameter mean?”). Consider
|
||||
/// grouping some parameters into a new type.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # struct Color;
|
||||
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
|
||||
|
@ -32,16 +32,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions with a large amount of lines.
|
||||
/// ### What it does
|
||||
/// Checks for functions with a large amount of lines.
|
||||
///
|
||||
/// **Why is this bad?** Functions with a lot of lines are harder to understand
|
||||
/// ### Why is this bad?
|
||||
/// Functions with a lot of lines are harder to understand
|
||||
/// due to having to look at a larger amount of code to understand what the
|
||||
/// function is doing. Consider splitting the body of the function into
|
||||
/// multiple functions.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn im_too_long() {
|
||||
/// println!("");
|
||||
|
@ -55,15 +55,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public functions that dereference raw pointer
|
||||
/// ### What it does
|
||||
/// Checks for public functions that dereference raw pointer
|
||||
/// arguments but are not marked `unsafe`.
|
||||
///
|
||||
/// **Why is this bad?** The function should probably be marked `unsafe`, since
|
||||
/// ### Why is this bad?
|
||||
/// The function should probably be marked `unsafe`, since
|
||||
/// for an arbitrary raw pointer, there is no way of telling for sure if it is
|
||||
/// valid.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// ### Known problems
|
||||
/// * It does not check functions recursively so if the pointer is passed to a
|
||||
/// private non-`unsafe` function which does the dereferencing, the lint won't
|
||||
/// trigger.
|
||||
|
@ -71,7 +72,7 @@ declare_clippy_lint! {
|
|||
/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
|
||||
/// `some_argument.get_raw_ptr()`).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// pub fn foo(x: *const u8) {
|
||||
|
@ -89,17 +90,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for a [`#[must_use]`] attribute on
|
||||
/// ### What it does
|
||||
/// Checks for a [`#[must_use]`] attribute on
|
||||
/// unit-returning functions and methods.
|
||||
///
|
||||
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
|
||||
///
|
||||
/// **Why is this bad?** Unit values are useless. The attribute is likely
|
||||
/// ### Why is this bad?
|
||||
/// Unit values are useless. The attribute is likely
|
||||
/// a remnant of a refactoring that removed the return type.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// #[must_use]
|
||||
/// fn useless() { }
|
||||
|
@ -110,19 +111,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for a [`#[must_use]`] attribute without
|
||||
/// ### What it does
|
||||
/// Checks for a [`#[must_use]`] attribute without
|
||||
/// further information on functions and methods that return a type already
|
||||
/// marked as `#[must_use]`.
|
||||
///
|
||||
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
|
||||
///
|
||||
/// **Why is this bad?** The attribute isn't needed. Not using the result
|
||||
/// ### Why is this bad?
|
||||
/// The attribute isn't needed. Not using the result
|
||||
/// will already be reported. Alternatively, one can add some text to the
|
||||
/// attribute to improve the lint message.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// #[must_use]
|
||||
/// fn double_must_use() -> Result<(), ()> {
|
||||
|
@ -135,16 +136,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public functions that have no
|
||||
/// ### What it does
|
||||
/// Checks for public functions that have no
|
||||
/// [`#[must_use]`] attribute, but return something not already marked
|
||||
/// must-use, have no mutable arg and mutate no statics.
|
||||
///
|
||||
/// [`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
|
||||
///
|
||||
/// **Why is this bad?** Not bad at all, this lint just shows places where
|
||||
/// ### Why is this bad?
|
||||
/// Not bad at all, this lint just shows places where
|
||||
/// you could add the attribute.
|
||||
///
|
||||
/// **Known problems:** The lint only checks the arguments for mutable
|
||||
/// ### Known problems
|
||||
/// The lint only checks the arguments for mutable
|
||||
/// types without looking if they are actually changed. On the other hand,
|
||||
/// it also ignores a broad range of potentially interesting side effects,
|
||||
/// because we cannot decide whether the programmer intends the function to
|
||||
|
@ -152,7 +156,7 @@ declare_clippy_lint! {
|
|||
/// positives. At least we don't lint if the result type is unit or already
|
||||
/// `#[must_use]`.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// // this could be annotated with `#[must_use]`.
|
||||
/// fn id<T>(t: T) -> T { t }
|
||||
|
@ -163,20 +167,23 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public functions that return a `Result`
|
||||
/// ### What it does
|
||||
/// Checks for public functions that return a `Result`
|
||||
/// with an `Err` type of `()`. It suggests using a custom type that
|
||||
/// implements `std::error::Error`.
|
||||
///
|
||||
/// **Why is this bad?** Unit does not implement `Error` and carries no
|
||||
/// ### Why is this bad?
|
||||
/// Unit does not implement `Error` and carries no
|
||||
/// further information about what went wrong.
|
||||
///
|
||||
/// **Known problems:** Of course, this lint assumes that `Result` is used
|
||||
/// ### Known problems
|
||||
/// Of course, this lint assumes that `Result` is used
|
||||
/// for a fallible operation (which is after all the intended use). However
|
||||
/// code may opt to (mis)use it as a basic two-variant-enum. In that case,
|
||||
/// the suggestion is misguided, and the code should use a custom enum
|
||||
/// instead.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// pub fn read_u8() -> Result<u8, ()> { Err(()) }
|
||||
/// ```
|
||||
|
|
|
@ -12,12 +12,14 @@ use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
|
|||
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint requires Future implementations returned from
|
||||
/// ### What it does
|
||||
/// This lint requires Future implementations returned from
|
||||
/// functions and methods to implement the `Send` marker trait. It is mostly
|
||||
/// used by library authors (public and internal) that target an audience where
|
||||
/// multithreaded executors are likely to be used for running these Futures.
|
||||
///
|
||||
/// **Why is this bad?** A Future implementation captures some state that it
|
||||
/// ### Why is this bad?
|
||||
/// A Future implementation captures some state that it
|
||||
/// needs to eventually produce its final value. When targeting a multithreaded
|
||||
/// executor (which is the norm on non-embedded devices) this means that this
|
||||
/// state may need to be transported to other threads, in other words the
|
||||
|
@ -31,10 +33,7 @@ declare_clippy_lint! {
|
|||
/// modifying the library where the offending Future implementation is
|
||||
/// produced.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
|
||||
/// ```
|
||||
|
|
|
@ -14,10 +14,12 @@ use rustc_span::source_map::Spanned;
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for using `x.get(x.len() - 1)` instead of
|
||||
/// ### What it does
|
||||
/// Checks for using `x.get(x.len() - 1)` instead of
|
||||
/// `x.last()`.
|
||||
///
|
||||
/// **Why is this bad?** Using `x.last()` is easier to read and has the same
|
||||
/// ### Why is this bad?
|
||||
/// Using `x.last()` is easier to read and has the same
|
||||
/// result.
|
||||
///
|
||||
/// Note that using `x[x.len() - 1]` is semantically different from
|
||||
|
@ -27,10 +29,7 @@ declare_clippy_lint! {
|
|||
/// There is another lint (get_unwrap) that covers the case of using
|
||||
/// `x.get(index).unwrap()` instead of `x[index]`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let x = vec![2, 3, 5];
|
||||
|
|
|
@ -11,14 +11,14 @@ use clippy_utils::diagnostics::span_lint;
|
|||
use clippy_utils::{clip, unsext};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for identity operations, e.g., `x + 0`.
|
||||
/// ### What it does
|
||||
/// Checks for identity operations, e.g., `x + 0`.
|
||||
///
|
||||
/// **Why is this bad?** This code can be removed without changing the
|
||||
/// ### Why is this bad?
|
||||
/// This code can be removed without changing the
|
||||
/// meaning. So it just obscures what's going on. Delete it mercilessly.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// x / 1 + 0 * 1 - 0 | 0;
|
||||
|
|
|
@ -9,16 +9,15 @@ use rustc_middle::hir::map::Map;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `Mutex::lock` calls in `if let` expression
|
||||
/// ### What it does
|
||||
/// Checks for `Mutex::lock` calls in `if let` expression
|
||||
/// with lock calls in any of the else blocks.
|
||||
///
|
||||
/// **Why is this bad?** The Mutex lock remains held for the whole
|
||||
/// ### Why is this bad?
|
||||
/// The Mutex lock remains held for the whole
|
||||
/// `if let ... else` block and deadlocks.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// if let Ok(thing) = mutex.lock() {
|
||||
/// do_thing();
|
||||
|
|
|
@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:*** Checks for unnecessary `ok()` in if let.
|
||||
/// ### What it does
|
||||
///* Checks for unnecessary `ok()` in if let.
|
||||
///
|
||||
/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match
|
||||
/// ### Why is this bad?
|
||||
/// Calling `ok()` in if let is unnecessary, instead match
|
||||
/// on `Ok(pat)`
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// for i in iter {
|
||||
/// if let Some(value) = i.parse().ok() {
|
||||
|
|
|
@ -8,14 +8,14 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an
|
||||
/// ### What it does
|
||||
/// Checks for usage of `!` or `!=` in an if condition with an
|
||||
/// else branch.
|
||||
///
|
||||
/// **Why is this bad?** Negations reduce the readability of statements.
|
||||
/// ### Why is this bad?
|
||||
/// Negations reduce the readability of statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let v: Vec<usize> = vec![];
|
||||
/// # fn a() {}
|
||||
|
|
|
@ -10,14 +10,13 @@ use rustc_semver::RustcVersion;
|
|||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for if-else that could be written to `bool::then`.
|
||||
/// ### What it does
|
||||
/// Checks for if-else that could be written to `bool::then`.
|
||||
///
|
||||
/// **Why is this bad?** Looks a little redundant. Using `bool::then` helps it have less lines of code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Looks a little redundant. Using `bool::then` helps it have less lines of code.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let v = vec![0];
|
||||
/// let a = if v.is_empty() {
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::collections::BTreeMap;
|
|||
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, walk_inf, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::map::Map;
|
||||
|
@ -19,24 +19,26 @@ use rustc_typeck::hir_ty_to_ty;
|
|||
use if_chain::if_chain;
|
||||
|
||||
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
|
||||
use clippy_utils::paths;
|
||||
use clippy_utils::differing_macro_contexts;
|
||||
use clippy_utils::source::{snippet, snippet_opt};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{differing_macro_contexts, match_def_path};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public `impl` or `fn` missing generalization
|
||||
/// ### What it does
|
||||
/// Checks for public `impl` or `fn` missing generalization
|
||||
/// over different hashers and implicitly defaulting to the default hashing
|
||||
/// algorithm (`SipHash`).
|
||||
///
|
||||
/// **Why is this bad?** `HashMap` or `HashSet` with custom hashers cannot be
|
||||
/// ### Why is this bad?
|
||||
/// `HashMap` or `HashSet` with custom hashers cannot be
|
||||
/// used with them.
|
||||
///
|
||||
/// **Known problems:** Suggestions for replacing constructors can contain
|
||||
/// ### Known problems
|
||||
/// Suggestions for replacing constructors can contain
|
||||
/// false-positives. Also applying suggestions can require modification of other
|
||||
/// pieces of code, possibly including external crates.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # use std::collections::HashMap;
|
||||
/// # use std::hash::{Hash, BuildHasher};
|
||||
|
@ -347,7 +349,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
|
|||
return;
|
||||
}
|
||||
|
||||
if match_def_path(self.cx, ty_did, &paths::HASHMAP) {
|
||||
if self.cx.tcx.is_diagnostic_item(sym::hashmap_type, ty_did) {
|
||||
if method.ident.name == sym::new {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashMap::default()".to_string());
|
||||
|
@ -360,7 +362,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
|
|||
),
|
||||
);
|
||||
}
|
||||
} else if match_def_path(self.cx, ty_did, &paths::HASHSET) {
|
||||
} else if self.cx.tcx.is_diagnostic_item(sym::hashset_type, ty_did) {
|
||||
if method.ident.name == sym::new {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashSet::default()".to_string());
|
||||
|
|
|
@ -13,17 +13,17 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::{Span, SyntaxContext};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for missing return statements at the end of a block.
|
||||
/// ### What it does
|
||||
/// Checks for missing return statements at the end of a block.
|
||||
///
|
||||
/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
|
||||
/// ### Why is this bad?
|
||||
/// Actually omitting the return keyword is idiomatic Rust code. Programmers
|
||||
/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
|
||||
/// the last returning statement because the only difference is a missing `;`. Especially in bigger
|
||||
/// code with multiple return paths having a `return` keyword makes it easier to find the
|
||||
/// corresponding statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) -> usize {
|
||||
/// x
|
||||
|
|
|
@ -8,14 +8,13 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for implicit saturating subtraction.
|
||||
/// ### What it does
|
||||
/// Checks for implicit saturating subtraction.
|
||||
///
|
||||
/// **Why is this bad?** Simplicity and readability. Instead we can easily use an builtin function.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Why is this bad?
|
||||
/// Simplicity and readability. Instead we can easily use an builtin function.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let end: u32 = 10;
|
||||
/// let start: u32 = 5;
|
||||
|
|
|
@ -10,11 +10,13 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for struct constructors where all fields are shorthand and
|
||||
/// ### What it does
|
||||
/// Checks for struct constructors where all fields are shorthand and
|
||||
/// the order of the field init shorthand in the constructor is inconsistent
|
||||
/// with the order in the struct definition.
|
||||
///
|
||||
/// **Why is this bad?** Since the order of fields in a constructor doesn't affect the
|
||||
/// ### Why is this bad?
|
||||
/// Since the order of fields in a constructor doesn't affect the
|
||||
/// resulted instance as the below example indicates,
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -32,10 +34,7 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// inconsistent order can be confusing and decreases readability and consistency.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// struct Foo {
|
||||
/// x: i32,
|
||||
|
|
|
@ -10,14 +10,17 @@ use rustc_middle::ty;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for out of bounds array indexing with a constant
|
||||
/// ### What it does
|
||||
/// Checks for out of bounds array indexing with a constant
|
||||
/// index.
|
||||
///
|
||||
/// **Why is this bad?** This will always panic at runtime.
|
||||
/// ### Why is this bad?
|
||||
/// This will always panic at runtime.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
/// ### Known problems
|
||||
/// Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// # #![allow(const_err)]
|
||||
/// let x = [1, 2, 3, 4];
|
||||
|
@ -36,16 +39,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cases, this lint
|
||||
/// ### What it does
|
||||
/// Checks for usage of indexing or slicing. Arrays are special cases, this lint
|
||||
/// does report on arrays if we can tell that slicing operations are in bounds and does not
|
||||
/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
|
||||
///
|
||||
/// **Why is this bad?** Indexing and slicing can panic at runtime and there are
|
||||
/// ### Why is this bad?
|
||||
/// Indexing and slicing can panic at runtime and there are
|
||||
/// safe alternatives.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
/// ### Known problems
|
||||
/// Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,no_run
|
||||
/// // Vector
|
||||
/// let x = vec![0; 5];
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::{implements_trait, match_type};
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths};
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
/// ### What it does
|
||||
/// Checks for iteration that is guaranteed to be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// ### Why is this bad?
|
||||
/// While there may be places where this is acceptable
|
||||
/// (e.g., in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// use std::iter;
|
||||
///
|
||||
|
@ -25,15 +26,18 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that may be infinite.
|
||||
/// ### What it does
|
||||
/// Checks for iteration that may be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// ### Why is this bad?
|
||||
/// While there may be places where this is acceptable
|
||||
/// (e.g., in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** The code may have a condition to stop iteration, but
|
||||
/// ### Known problems
|
||||
/// The code may have a condition to stop iteration, but
|
||||
/// this lint is not clever enough to analyze it.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let infinite_iter = 0..;
|
||||
/// [0..].iter().zip(infinite_iter.take_while(|x| *x > 5));
|
||||
|
@ -202,15 +206,15 @@ const COMPLETING_METHODS: [(&str, usize); 12] = [
|
|||
];
|
||||
|
||||
/// the paths of types that are known to be infinitely allocating
|
||||
const INFINITE_COLLECTORS: [&[&str]; 8] = [
|
||||
&paths::BINARY_HEAP,
|
||||
&paths::BTREEMAP,
|
||||
&paths::BTREESET,
|
||||
&paths::HASHMAP,
|
||||
&paths::HASHSET,
|
||||
&paths::LINKED_LIST,
|
||||
&paths::VEC,
|
||||
&paths::VEC_DEQUE,
|
||||
const INFINITE_COLLECTORS: &[Symbol] = &[
|
||||
sym::BinaryHeap,
|
||||
sym::BTreeMap,
|
||||
sym::BTreeSet,
|
||||
sym::hashmap_type,
|
||||
sym::hashset_type,
|
||||
sym::LinkedList,
|
||||
sym::vec_type,
|
||||
sym::vecdeque_type,
|
||||
];
|
||||
|
||||
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||
|
@ -235,7 +239,10 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
|||
}
|
||||
} else if method.ident.name == sym!(collect) {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) {
|
||||
if INFINITE_COLLECTORS
|
||||
.iter()
|
||||
.any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item))
|
||||
{
|
||||
return is_infinite(cx, &args[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ use rustc_span::Span;
|
|||
use std::collections::hash_map::Entry;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for multiple inherent implementations of a struct
|
||||
/// ### What it does
|
||||
/// Checks for multiple inherent implementations of a struct
|
||||
///
|
||||
/// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate.
|
||||
/// ### Why is this bad?
|
||||
/// Splitting the implementation of a type makes the code harder to navigate.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
|
|
|
@ -8,14 +8,16 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.
|
||||
/// ### What it does
|
||||
/// Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.
|
||||
///
|
||||
/// **Why is this bad?** This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.
|
||||
/// ### Why is this bad?
|
||||
/// This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// ** Example:**
|
||||
/// ### Known problems
|
||||
/// None
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// pub struct A;
|
||||
|
@ -45,14 +47,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait.
|
||||
/// ### What it does
|
||||
/// Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait.
|
||||
///
|
||||
/// **Why is this bad?** This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.
|
||||
/// ### Why is this bad?
|
||||
/// This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// ** Example:**
|
||||
/// ### Known problems
|
||||
/// None
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// use std::fmt;
|
||||
|
|
|
@ -10,14 +10,14 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_span::{sym, Symbol};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[inline]` on trait methods without bodies
|
||||
/// ### What it does
|
||||
/// Checks for `#[inline]` on trait methods without bodies
|
||||
///
|
||||
/// **Why is this bad?** Only implementations of trait methods may be inlined.
|
||||
/// ### Why is this bad?
|
||||
/// Only implementations of trait methods may be inlined.
|
||||
/// The inline attribute is ignored for trait methods without bodies.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// trait Animal {
|
||||
/// #[inline]
|
||||
|
|
|
@ -8,13 +8,13 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
|
||||
/// ### What it does
|
||||
/// Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
|
||||
///
|
||||
/// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`.
|
||||
/// ### Why is this bad?
|
||||
/// Readability -- better to use `> y` instead of `>= y + 1`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # let x = 1;
|
||||
/// # let y = 1;
|
||||
|
|
|
@ -5,15 +5,15 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for division of integers
|
||||
/// ### What it does
|
||||
/// Checks for division of integers
|
||||
///
|
||||
/// **Why is this bad?** When outside of some very specific algorithms,
|
||||
/// ### Why is this bad?
|
||||
/// When outside of some very specific algorithms,
|
||||
/// integer division is very often a mistake because it discards the
|
||||
/// remainder.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let x = 3 / 2;
|
||||
|
|
|
@ -14,18 +14,20 @@ use clippy_utils::source::snippet;
|
|||
use clippy_utils::{comparisons, sext};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for comparisons where the relation is always either
|
||||
/// ### What it does
|
||||
/// Checks for comparisons where the relation is always either
|
||||
/// true or false, but where one side has been upcast so that the comparison is
|
||||
/// necessary. Only integer types are checked.
|
||||
///
|
||||
/// **Why is this bad?** An expression like `let x : u8 = ...; (x as u32) > 300`
|
||||
/// ### Why is this bad?
|
||||
/// An expression like `let x : u8 = ...; (x as u32) > 300`
|
||||
/// will mistakenly imply that it is possible for `x` to be outside the range of
|
||||
/// `u8`.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// ### Known problems
|
||||
/// https://github.com/rust-lang/rust-clippy/issues/886
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x: u8 = 1;
|
||||
/// (x as u32) > 300;
|
||||
|
|
|
@ -7,15 +7,15 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items declared after some statement in a block.
|
||||
/// ### What it does
|
||||
/// Checks for items declared after some statement in a block.
|
||||
///
|
||||
/// **Why is this bad?** Items live for the entire scope they are declared
|
||||
/// ### Why is this bad?
|
||||
/// Items live for the entire scope they are declared
|
||||
/// in. But statements are processed in order. This might cause confusion as
|
||||
/// it's hard to figure out which item is meant in a statement.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// fn foo() {
|
||||
|
|
|
@ -11,15 +11,15 @@ use rustc_span::{BytePos, Pos, Span};
|
|||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for large `const` arrays that should
|
||||
/// ### What it does
|
||||
/// Checks for large `const` arrays that should
|
||||
/// be defined as `static` instead.
|
||||
///
|
||||
/// **Why is this bad?** Performance: const variables are inlined upon use.
|
||||
/// ### Why is this bad?
|
||||
/// Performance: const variables are inlined upon use.
|
||||
/// Static items result in only one instance and has a fixed location in memory.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// pub const a = [0u32; 1_000_000];
|
||||
|
|
|
@ -10,20 +10,22 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use rustc_target::abi::LayoutOf;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for large size differences between variants on
|
||||
/// ### What it does
|
||||
/// Checks for large size differences between variants on
|
||||
/// `enum`s.
|
||||
///
|
||||
/// **Why is this bad?** Enum size is bounded by the largest variant. Having a
|
||||
/// ### Why is this bad?
|
||||
/// Enum size is bounded by the largest variant. Having a
|
||||
/// large variant can penalize the memory layout of that enum.
|
||||
///
|
||||
/// **Known problems:** This lint obviously cannot take the distribution of
|
||||
/// ### Known problems
|
||||
/// This lint obviously cannot take the distribution of
|
||||
/// variants in your running program into account. It is possible that the
|
||||
/// smaller variants make up less than 1% of all instances, in which case
|
||||
/// the overhead is negligible and the boxing is counter-productive. Always
|
||||
/// measure the change this lint suggests.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// enum Test {
|
||||
|
|
|
@ -10,13 +10,13 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|||
use crate::rustc_target::abi::LayoutOf;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for local arrays that may be too large.
|
||||
/// ### What it does
|
||||
/// Checks for local arrays that may be too large.
|
||||
///
|
||||
/// **Why is this bad?** Large local arrays may cause stack overflow.
|
||||
/// ### Why is this bad?
|
||||
/// Large local arrays may cause stack overflow.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// let a = [0u32; 1_000_000];
|
||||
/// ```
|
||||
|
|
|
@ -18,17 +18,17 @@ use rustc_span::{
|
|||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||
/// ### What it does
|
||||
/// Checks for getting the length of something via `.len()`
|
||||
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||
///
|
||||
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster
|
||||
/// ### Why is this bad?
|
||||
/// Some structures can answer `.is_empty()` much faster
|
||||
/// than calculating their length. So it is good to get into the habit of using
|
||||
/// `.is_empty()`, and having it is cheap.
|
||||
/// Besides, it makes the intent clearer than a manual comparison in some contexts.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// if x.len() == 0 {
|
||||
/// ..
|
||||
|
@ -52,18 +52,18 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items that implement `.len()` but not
|
||||
/// ### What it does
|
||||
/// Checks for items that implement `.len()` but not
|
||||
/// `.is_empty()`.
|
||||
///
|
||||
/// **Why is this bad?** It is good custom to have both methods, because for
|
||||
/// ### Why is this bad?
|
||||
/// It is good custom to have both methods, because for
|
||||
/// some data structures, asking about the length will be a costly operation,
|
||||
/// whereas `.is_empty()` can usually answer in constant time. Also it used to
|
||||
/// lead to false positives on the [`len_zero`](#len_zero) lint – currently that
|
||||
/// lint will ignore such entities.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```ignore
|
||||
/// impl X {
|
||||
/// pub fn len(&self) -> usize {
|
||||
|
@ -77,17 +77,17 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for comparing to an empty slice such as `""` or `[]`,
|
||||
/// ### What it does
|
||||
/// Checks for comparing to an empty slice such as `""` or `[]`,
|
||||
/// and suggests using `.is_empty()` where applicable.
|
||||
///
|
||||
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster
|
||||
/// ### Why is this bad?
|
||||
/// Some structures can answer `.is_empty()` much faster
|
||||
/// than checking for equality. So it is good to get into the habit of using
|
||||
/// `.is_empty()`, and having it is cheap.
|
||||
/// Besides, it makes the intent clearer than a manual comparison in some contexts.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// if s == "" {
|
||||
|
|
|
@ -9,14 +9,14 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for variable declarations immediately followed by a
|
||||
/// ### What it does
|
||||
/// Checks for variable declarations immediately followed by a
|
||||
/// conditional affectation.
|
||||
///
|
||||
/// **Why is this bad?** This is not idiomatic Rust.
|
||||
/// ### Why is this bad?
|
||||
/// This is not idiomatic Rust.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// let foo;
|
||||
///
|
||||
|
|
|
@ -9,15 +9,15 @@ use rustc_middle::ty::subst::GenericArgKind;
|
|||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `let _ = <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! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `let _ = sync_lock`
|
||||
/// ### What it does
|
||||
/// Checks for `let _ = sync_lock`
|
||||
///
|
||||
/// **Why is this bad?** This statement immediately drops the lock instead of
|
||||
/// ### Why is this bad?
|
||||
/// This statement immediately drops the lock instead of
|
||||
/// extending its lifetime to the end of the scope, which is often not intended.
|
||||
/// To extend lock lifetime to the end of the scope, use an underscore-prefixed
|
||||
/// name instead (i.e. _lock). If you want to explicitly drop the lock,
|
||||
/// `std::mem::drop` conveys your intention better and is less error-prone.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
///
|
||||
/// Bad:
|
||||
/// ```rust,ignore
|
||||
|
@ -60,19 +60,19 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `let _ = <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 rustc_session::Session;
|
|||
/// use clippy_lints::declare_clippy_lint;
|
||||
///
|
||||
/// declare_clippy_lint! {
|
||||
/// /// **What it does:** Checks for ... (describe what the lint matches).
|
||||
/// /// ### What it does
|
||||
/// /// Checks for ... (describe what the lint matches).
|
||||
/// ///
|
||||
/// /// **Why is this bad?** Supply the reason for linting the code.
|
||||
/// ///
|
||||
/// /// **Known problems:** None. (Or describe where it could go wrong.)
|
||||
/// ///
|
||||
/// /// **Example:**
|
||||
/// /// ### Why is this bad?
|
||||
/// /// Supply the reason for linting the code.
|
||||
/// ///
|
||||
/// /// ### Example
|
||||
/// /// ```rust
|
||||
/// /// // Bad
|
||||
/// /// Insert a short example of code that triggers the lint
|
||||
|
@ -330,7 +329,7 @@ mod regex;
|
|||
mod repeat_once;
|
||||
mod returns;
|
||||
mod self_assignment;
|
||||
mod self_named_constructor;
|
||||
mod self_named_constructors;
|
||||
mod semicolon_if_nothing_returned;
|
||||
mod serde_api;
|
||||
mod shadow;
|
||||
|
@ -741,7 +740,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
|
||||
mem_replace::MEM_REPLACE_WITH_DEFAULT,
|
||||
mem_replace::MEM_REPLACE_WITH_UNINIT,
|
||||
methods::APPEND_INSTEAD_OF_EXTEND,
|
||||
methods::BIND_INSTEAD_OF_MAP,
|
||||
methods::BYTES_NTH,
|
||||
methods::CHARS_LAST_CMP,
|
||||
|
@ -752,6 +750,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
methods::CLONE_ON_REF_PTR,
|
||||
methods::EXPECT_FUN_CALL,
|
||||
methods::EXPECT_USED,
|
||||
methods::EXTEND_WITH_DRAIN,
|
||||
methods::FILETYPE_IS_FILE,
|
||||
methods::FILTER_MAP_IDENTITY,
|
||||
methods::FILTER_MAP_NEXT,
|
||||
|
@ -901,7 +900,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
returns::LET_AND_RETURN,
|
||||
returns::NEEDLESS_RETURN,
|
||||
self_assignment::SELF_ASSIGNMENT,
|
||||
self_named_constructor::SELF_NAMED_CONSTRUCTOR,
|
||||
self_named_constructors::SELF_NAMED_CONSTRUCTORS,
|
||||
semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
|
||||
serde_api::SERDE_API_MISUSE,
|
||||
shadow::SHADOW_REUSE,
|
||||
|
@ -1297,7 +1296,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
|
||||
LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
||||
LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
|
||||
LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
|
||||
LintId::of(methods::BIND_INSTEAD_OF_MAP),
|
||||
LintId::of(methods::BYTES_NTH),
|
||||
LintId::of(methods::CHARS_LAST_CMP),
|
||||
|
@ -1305,6 +1303,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(methods::CLONE_DOUBLE_REF),
|
||||
LintId::of(methods::CLONE_ON_COPY),
|
||||
LintId::of(methods::EXPECT_FUN_CALL),
|
||||
LintId::of(methods::EXTEND_WITH_DRAIN),
|
||||
LintId::of(methods::FILTER_MAP_IDENTITY),
|
||||
LintId::of(methods::FILTER_NEXT),
|
||||
LintId::of(methods::FLAT_MAP_IDENTITY),
|
||||
|
@ -1408,7 +1407,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(returns::LET_AND_RETURN),
|
||||
LintId::of(returns::NEEDLESS_RETURN),
|
||||
LintId::of(self_assignment::SELF_ASSIGNMENT),
|
||||
LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
|
||||
LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
|
||||
LintId::of(serde_api::SERDE_API_MISUSE),
|
||||
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
||||
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
|
||||
|
@ -1562,7 +1561,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
|
||||
LintId::of(returns::LET_AND_RETURN),
|
||||
LintId::of(returns::NEEDLESS_RETURN),
|
||||
LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
|
||||
LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
|
||||
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
||||
LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
|
||||
LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
|
||||
|
@ -1763,8 +1762,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
|
||||
LintId::of(loops::MANUAL_MEMCPY),
|
||||
LintId::of(loops::NEEDLESS_COLLECT),
|
||||
LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
|
||||
LintId::of(methods::EXPECT_FUN_CALL),
|
||||
LintId::of(methods::EXTEND_WITH_DRAIN),
|
||||
LintId::of(methods::ITER_NTH),
|
||||
LintId::of(methods::MANUAL_STR_REPEAT),
|
||||
LintId::of(methods::OR_FUN_CALL),
|
||||
|
@ -2105,7 +2104,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
let scripts = conf.allowed_scripts.clone();
|
||||
store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts));
|
||||
store.register_late_pass(|| box strlen_on_c_strings::StrlenOnCStrings);
|
||||
store.register_late_pass(move || box self_named_constructor::SelfNamedConstructor);
|
||||
store.register_late_pass(move || box self_named_constructors::SelfNamedConstructors);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
|
@ -18,20 +18,22 @@ use rustc_span::source_map::Span;
|
|||
use rustc_span::symbol::{kw, Symbol};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for lifetime annotations which can be removed by
|
||||
/// ### What it does
|
||||
/// Checks for lifetime annotations which can be removed by
|
||||
/// relying on lifetime elision.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// ### Why is this bad?
|
||||
/// The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// ### Known problems
|
||||
/// - We bail out if the function has a `where` clause where lifetimes
|
||||
/// are mentioned due to potenial false positives.
|
||||
/// - Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the
|
||||
/// placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad: unnecessary lifetime annotations
|
||||
/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
|
||||
|
@ -50,16 +52,16 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for lifetimes in generics that are never used
|
||||
/// ### What it does
|
||||
/// Checks for lifetimes in generics that are never used
|
||||
/// anywhere else.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// ### Why is this bad?
|
||||
/// The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad: unnecessary lifetimes
|
||||
/// fn unused_lifetime<'a>(x: u8) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue