11144 lines
683 KiB
JSON
11144 lines
683 KiB
JSON
[
|
||
{
|
||
"id": "absolute_paths",
|
||
"id_span": {
|
||
"path": "src/absolute_paths.rs",
|
||
"line": 42
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of items through absolute paths, like `std::env::current_dir`.\n\n### Why is this bad?\nMany codebases have their own style when it comes to importing, but one that is seldom used\nis using absolute paths *everywhere*. This is generally considered unidiomatic, and you\nshould add a `use` statement.\n\nThe default maximum segments (2) is pretty strict, you may want to increase this in\n`clippy.toml`.\n\nNote: One exception to this is code from macro expansion - this does not lint such cases, as\nusing absolute paths is the proper way of referencing items in one.\n\n### Example\n```rust\nlet x = std::f64::consts::PI;\n```\nUse any of the below instead, or anything else:\n```rust\nuse std::f64;\nuse std::f64::consts;\nuse std::f64::consts::PI;\nlet x = f64::consts::PI;\nlet x = consts::PI;\nlet x = PI;\nuse std::f64::consts as f64_consts;\nlet x = f64_consts::PI;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `absolute-paths-allowed-crates`: Which crates to allow absolute paths from (default: `[]`)- `absolute-paths-max-segments`: The maximum number of segments a path can have before being linted, anything above this will\n be linted. (default: `2`)",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "absurd_extreme_comparisons",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 57
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for comparisons where one side of the relation is\neither the minimum or maximum value for its type and warns if it involves a\ncase that is always true or always false. Only integer and boolean types are\nchecked.\n\n### Why is this bad?\nAn expression like `min <= x` may misleadingly imply\nthat it is possible for `x` to be less than the minimum. Expressions like\n`max < x` are probably mistakes.\n\n### Known problems\nFor `usize` the size of the current compile target will\nbe assumed (e.g., 64 bits on 64 bit systems). This means code that uses such\na comparison to detect target pointer width will trigger this lint. One can\nuse `mem::sizeof` and compare its value or conditional compilation\nattributes\nlike `#[cfg(target_pointer_width = \"64\")] ..` instead.\n\n### Example\n```rust\nlet vec: Vec<isize> = Vec::new();\nif vec.len() <= 0 {}\nif 100 > i32::MAX {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "alloc_instead_of_core",
|
||
"id_span": {
|
||
"path": "src/std_instead_of_core.rs",
|
||
"line": 85
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nFinds items imported through `alloc` when available through `core`.\n\n### Why is this bad?\n\nCrates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are\nimported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint\nis also useful for crates migrating to become `no_std` compatible.\n\n### Example\n```rust\nuse alloc::slice::from_ref;\n```\nUse instead:\n```rust\nuse core::slice::from_ref;\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "allow_attributes",
|
||
"id_span": {
|
||
"path": "src/allow_attributes.rs",
|
||
"line": 45
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of the `#[allow]` attribute and suggests replacing it with\nthe `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))\n\nThe expect attribute is still unstable and requires the `lint_reasons`\non nightly. It can be enabled by adding `#![feature(lint_reasons)]` to\nthe crate root.\n\nThis lint only warns outer attributes (`#[allow]`), as inner attributes\n(`#![allow]`) are usually used to enable or disable lints on a global scale.\n\n### Why is this bad?\n`#[expect]` attributes suppress the lint emission, but emit a warning, if\nthe expectation is unfulfilled. This can be useful to be notified when the\nlint is no longer triggered.\n\n### Example\n```rust\n#[allow(unused_mut)]\nfn foo() -> usize {\n let mut a = Vec::new();\n a.len()\n}\n```\nUse instead:\n```rust\n#![feature(lint_reasons)]\n#[expect(unused_mut)]\nfn foo() -> usize {\n let mut a = Vec::new();\n a.len()\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "allow_attributes_without_reason",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 320
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for attributes that allow lints without a reason.\n\n(This requires the `lint_reasons` feature)\n\n### Why is this bad?\nAllowing a lint should always have a reason. This reason should be documented to\nensure that others understand the reasoning\n\n### Example\n```rust\n#![feature(lint_reasons)]\n\n#![allow(clippy::some_lint)]\n```\n\nUse instead:\n```rust\n#![feature(lint_reasons)]\n\n#![allow(clippy::some_lint, reason = \"False positive rust-lang/rust-clippy#1002020\")]\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "almost_complete_range",
|
||
"id_span": {
|
||
"path": "src/almost_complete_range.rs",
|
||
"line": 28
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for ranges which almost include the entire range of letters from 'a' to 'z'\nor digits from '0' to '9', but don't because they're a half open range.\n\n### Why is this bad?\nThis (`'a'..'z'`) is almost certainly a typo meant to include all letters.\n\n### Example\n```rust\nlet _ = 'a'..'z';\n```\nUse instead:\n```rust\nlet _ = 'a'..='z';\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n### Past names\n\n* `almost_complete_letter_range`\n\n",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
},
|
||
"former_ids": [
|
||
"almost_complete_letter_range"
|
||
]
|
||
},
|
||
{
|
||
"id": "almost_swapped",
|
||
"id_span": {
|
||
"path": "src/swap.rs",
|
||
"line": 74
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `foo = bar; bar = foo` sequences.\n\n### Why is this bad?\nThis looks like a failed attempt to swap.\n\n### Example\n```rust\na = b;\nb = a;\n```\nIf swapping is intended, use `swap()` instead:\n```rust\nstd::mem::swap(&mut a, &mut b);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "approx_constant",
|
||
"id_span": {
|
||
"path": "src/approx_const.rs",
|
||
"line": 37
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for floating point literals that approximate\nconstants which are defined in\n[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)\nor\n[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),\nrespectively, suggesting to use the predefined constant.\n\n### Why is this bad?\nUsually, the definition in the standard library is more\nprecise than what people come up with. If you find that your definition is\nactually more precise, please [file a Rust\nissue](https://github.com/rust-lang/rust/issues).\n\n### Example\n```rust\nlet x = 3.14;\nlet y = 1_f64 / x;\n```\nUse instead:\n```rust\nlet x = std::f32::consts::PI;\nlet y = std::f64::consts::FRAC_1_PI;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "arc_with_non_send_sync",
|
||
"id_span": {
|
||
"path": "src/arc_with_non_send_sync.rs",
|
||
"line": 37
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does.\nThis lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.\n\n### Why is this bad?\n`Arc<T>` is a thread-safe `Rc<T>` and guarantees that updates to the reference counter\nuse atomic operations. To send an `Arc<T>` across thread boundaries and\nshare ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety),\nso either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`\n\n### Example\n```rust\n\nfn main() {\n // This is fine, as `i32` implements `Send` and `Sync`.\n let a = Arc::new(42);\n\n // `RefCell` is `!Sync`, so either the `Arc` should be replaced with an `Rc`\n // or the `RefCell` replaced with something like a `RwLock`\n let b = Arc::new(RefCell::new(42));\n}\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "arithmetic_side_effects",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 94
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks any kind of arithmetic operation of any type.\n\nOperators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust\nReference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),\nor can panic (`/`, `%`).\n\nKnown safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant\nenvironments, allowed types and non-constant operations that won't overflow are ignored.\n\n### Why is this bad?\nFor integers, overflow will trigger a panic in debug builds or wrap the result in\nrelease mode; division by zero will cause a panic in either mode. As a result, it is\ndesirable to explicitly call checked, wrapping or saturating arithmetic methods.\n\n#### Example\n```rust\n// `n` can be any number, including `i32::MAX`.\nfn foo(n: i32) -> i32 {\n n + 1\n}\n```\n\nThird-party types can also overflow or present unwanted side-effects.\n\n#### Example\n```rust\nuse rust_decimal::Decimal;\nlet _n = Decimal::MAX + Decimal::MAX;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `arithmetic-side-effects-allowed`: Suppress checking of the passed type names in all types of operations.\n\n If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.\n\n #### Example\n\n```toml\n arithmetic-side-effects-allowed = [\"SomeType\", \"AnotherType\"]\n ```\n\n #### Noteworthy\n\n A type, say `SomeType`, listed in this configuration has the same behavior of\n `[\"SomeType\" , \"*\"], [\"*\", \"SomeType\"]` in `arithmetic_side_effects_allowed_binary`. (default: `[]`)- `arithmetic-side-effects-allowed-binary`: Suppress checking of the passed type pair names in binary operations like addition or\n multiplication.\n\n Supports the \"*\" wildcard to indicate that a certain type won't trigger the lint regardless\n of the involved counterpart. For example, `[\"SomeType\", \"*\"]` or `[\"*\", \"AnotherType\"]`.\n\n Pairs are asymmetric, which means that `[\"SomeType\", \"AnotherType\"]` is not the same as\n `[\"AnotherType\", \"SomeType\"]`.\n\n #### Example\n\n```toml\n arithmetic-side-effects-allowed-binary = [[\"SomeType\" , \"f32\"], [\"AnotherType\", \"*\"]]\n ``` (default: `[]`)- `arithmetic-side-effects-allowed-unary`: Suppress checking of the passed type names in unary operations like \"negation\" (`-`).\n\n #### Example\n\n```toml\n arithmetic-side-effects-allowed-unary = [\"SomeType\", \"AnotherType\"]\n ``` (default: `[]`)\n### Past names\n\n* `integer_arithmetic`\n\n",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"integer_arithmetic"
|
||
]
|
||
},
|
||
{
|
||
"id": "as_conversions",
|
||
"id_span": {
|
||
"path": "src/as_conversions.rs",
|
||
"line": 42
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `as` conversions.\n\nNote that this lint is specialized in linting *every single* use of `as`\nregardless of whether good alternatives exist or not.\nIf you want more precise lints for `as`, please consider using these separate lints:\n`unnecessary_cast`, `cast_lossless/cast_possible_truncation/cast_possible_wrap/cast_precision_loss/cast_sign_loss`,\n`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.\nThere is a good explanation the reason why this lint should work in this way and how it is useful\n[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).\n\n### Why is this bad?\n`as` conversions will perform many kinds of\nconversions, including silently lossy conversions and dangerous coercions.\nThere are cases when it makes sense to use `as`, so the lint is\nAllow by default.\n\n### Example\n```rust\nlet a: u32;\n...\nf(a as u16);\n```\n\nUse instead:\n```rust\nf(a.try_into()?);\n\n// or\n\nf(a.try_into().expect(\"Unexpected u16 overflow in f\"));\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "as_ptr_cast_mut",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 643
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer\n\n### Why is this bad?\nSince `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior\nmutability is used, making it unlikely that having it as a mutable pointer is correct.\n\n### Example\n```rust\nlet mut vec = Vec::<u8>::with_capacity(1);\nlet ptr = vec.as_ptr() as *mut u8;\nunsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR\n```\nUse instead:\n```rust\nlet mut vec = Vec::<u8>::with_capacity(1);\nlet ptr = vec.as_mut_ptr();\nunsafe { ptr.write(4) };\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "as_underscore",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 557
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of `as _` conversion using inferred type.\n\n### Why is this bad?\nThe conversion might include lossy conversion and dangerous cast that might go\nundetected due to the type being inferred.\n\nThe lint is allowed by default as using `_` is less wordy than always specifying the type.\n\n### Example\n```rust\nfn foo(n: usize) {}\nlet n: u16 = 256;\nfoo(n as _);\n```\nUse instead:\n```rust\nfn foo(n: usize) {}\nlet n: u16 = 256;\nfoo(n as usize);\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "assertions_on_constants",
|
||
"id_span": {
|
||
"path": "src/assertions_on_constants.rs",
|
||
"line": 25
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `assert!(true)` and `assert!(false)` calls.\n\n### Why is this bad?\nWill be optimized out by the compiler or should probably be replaced by a\n`panic!()` or `unreachable!()`\n\n### Example\n```rust\nassert!(false)\nassert!(true)\nconst B: bool = false;\nassert!(B)\n```",
|
||
"version": "1.34.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "assertions_on_result_states",
|
||
"id_span": {
|
||
"path": "src/assertions_on_result_states.rs",
|
||
"line": 33
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls.\n\n### Why is this bad?\nAn assertion failure cannot output an useful message of the error.\n\n### Known problems\nThe suggested replacement decreases the readability of code and log output.\n\n### Example\n```rust\nassert!(r.is_ok());\nassert!(r.is_err());\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "assign_op_pattern",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 148
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `a = a op b` or `a = b commutative_op a`\npatterns.\n\n### Why is this bad?\nThese can be written as the shorter `a op= b`.\n\n### Known problems\nWhile forbidden by the spec, `OpAssign` traits may have\nimplementations that differ from the regular `Op` impl.\n\n### Example\n```rust\nlet mut a = 5;\nlet b = 0;\n// ...\n\na = a + b;\n```\n\nUse instead:\n```rust\nlet mut a = 5;\nlet b = 0;\n// ...\n\na += b;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "assign_ops",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 107
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint is too subjective, not having a good reason for being in clippy.\nAdditionally, compound assignment operators may be overloaded separately from their non-assigning\ncounterparts, so this lint may suggest a change in behavior or the code may not compile.",
|
||
"version": "1.30.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "assigning_clones",
|
||
"id_span": {
|
||
"path": "src/assigning_clones.rs",
|
||
"line": 49
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for code like `foo = bar.clone();`\n\n### Why is this bad?\nCustom `Clone::clone_from()` or `ToOwned::clone_into` implementations allow the objects\nto share resources and therefore avoid allocations.\n\n### Example\n```rust\nstruct Thing;\n\nimpl Clone for Thing {\n fn clone(&self) -> Self { todo!() }\n fn clone_from(&mut self, other: &Self) { todo!() }\n}\n\npub fn assign_to_ref(a: &mut Thing, b: Thing) {\n *a = b.clone();\n}\n```\nUse instead:\n```rust\nstruct Thing;\nimpl Clone for Thing {\n fn clone(&self) -> Self { todo!() }\n fn clone_from(&mut self, other: &Self) { todo!() }\n}\n\npub fn assign_to_ref(a: &mut Thing, b: Thing) {\n a.clone_from(&b);\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "async_yields_async",
|
||
"id_span": {
|
||
"path": "src/async_yields_async.rs",
|
||
"line": 39
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for async blocks that yield values of types\nthat can themselves be awaited.\n\n### Why is this bad?\nAn await is likely missing.\n\n### Example\n```rust\nasync fn foo() {}\n\nfn bar() {\n let x = async {\n foo()\n };\n}\n```\n\nUse instead:\n```rust\nasync fn foo() {}\n\nfn bar() {\n let x = async {\n foo().await\n };\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "await_holding_invalid_type",
|
||
"id_span": {
|
||
"path": "src/await_holding_invalid.rs",
|
||
"line": 164
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nAllows users to configure types which should not be held across `await`\nsuspension points.\n\n### Why is this bad?\nThere are some types which are perfectly \"safe\" to be used concurrently\nfrom a memory access perspective but will cause bugs at runtime if they\nare held in such a way.\n\n### Example\n\n```toml\nawait-holding-invalid-types = [\n # You can specify a type name\n \"CustomLockType\",\n # You can (optionally) specify a reason\n { path = \"OtherCustomLockType\", reason = \"Relies on a thread local\" }\n]\n```\n\n```rust\nstruct CustomLockType;\nstruct OtherCustomLockType;\nasync fn foo() {\n let _x = CustomLockType;\n let _y = OtherCustomLockType;\n baz().await; // Lint violation\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `await-holding-invalid-types`: (default: `[]`)",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "await_holding_lock",
|
||
"id_span": {
|
||
"path": "src/await_holding_invalid.rs",
|
||
"line": 69
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to await while holding a non-async-aware MutexGuard.\n\n### Why is this bad?\nThe Mutex types found in std::sync and parking_lot\nare not designed to operate in an async context across await points.\n\nThere are two potential solutions. One is to use an async-aware Mutex\ntype. Many asynchronous foundation crates provide such a Mutex type. The\nother solution is to ensure the mutex is unlocked before calling await,\neither by introducing a scope or an explicit call to Drop::drop.\n\n### Known problems\nWill report false positive for explicitly dropped guards\n([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is\nto wrap the `.lock()` call in a block instead of explicitly dropping the guard.\n\n### Example\n```rust\nasync fn foo(x: &Mutex<u32>) {\n let mut guard = x.lock().unwrap();\n *guard += 1;\n baz().await;\n}\n\nasync fn bar(x: &Mutex<u32>) {\n let mut guard = x.lock().unwrap();\n *guard += 1;\n drop(guard); // explicit drop\n baz().await;\n}\n```\n\nUse instead:\n```rust\nasync fn foo(x: &Mutex<u32>) {\n {\n let mut guard = x.lock().unwrap();\n *guard += 1;\n }\n baz().await;\n}\n\nasync fn bar(x: &Mutex<u32>) {\n {\n let mut guard = x.lock().unwrap();\n *guard += 1;\n } // guard dropped here at end of scope\n baz().await;\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "await_holding_refcell_ref",
|
||
"id_span": {
|
||
"path": "src/await_holding_invalid.rs",
|
||
"line": 127
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to await while holding a `RefCell` `Ref` or `RefMut`.\n\n### Why is this bad?\n`RefCell` refs only check for exclusive mutable access\nat runtime. Holding onto a `RefCell` ref across an `await` suspension point\nrisks panics from a mutable ref shared while other refs are outstanding.\n\n### Known problems\nWill report false positive for explicitly dropped refs\n([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). A workaround for this is\nto wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.\n\n### Example\n```rust\nasync fn foo(x: &RefCell<u32>) {\n let mut y = x.borrow_mut();\n *y += 1;\n baz().await;\n}\n\nasync fn bar(x: &RefCell<u32>) {\n let mut y = x.borrow_mut();\n *y += 1;\n drop(y); // explicit drop\n baz().await;\n}\n```\n\nUse instead:\n```rust\nasync fn foo(x: &RefCell<u32>) {\n {\n let mut y = x.borrow_mut();\n *y += 1;\n }\n baz().await;\n}\n\nasync fn bar(x: &RefCell<u32>) {\n {\n let mut y = x.borrow_mut();\n *y += 1;\n } // y dropped here at end of scope\n baz().await;\n}\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "bad_bit_mask",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 213
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for incompatible bit masks in comparisons.\n\nThe formula for detecting if an expression of the type `_ <bit_op> m\n<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of\n{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following\ntable:\n\n|Comparison |Bit Op|Example |is always|Formula |\n|------------|------|-------------|---------|----------------------|\n|`==` or `!=`| `&` |`x & 2 == 3` |`false` |`c & m != c` |\n|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |\n|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |\n|`==` or `!=`| `\\|` |`x \\| 1 == 0`|`false` |`c \\| m != c` |\n|`<` or `>=`| `\\|` |`x \\| 1 < 1` |`false` |`m >= c` |\n|`<=` or `>` | `\\|` |`x \\| 1 > 0` |`true` |`m > c` |\n\n### Why is this bad?\nIf the bits that the comparison cares about are always\nset to zero or one by the bit mask, the comparison is constant `true` or\n`false` (depending on mask, compared value, and operators).\n\nSo the code is actively misleading, and the only reason someone would write\nthis intentionally is to win an underhanded Rust contest or create a\ntest-case for this lint.\n\n### Example\n```rust\nif (x & 1 == 2) { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "big_endian_bytes",
|
||
"id_span": {
|
||
"path": "src/endian_bytes.rs",
|
||
"line": 63
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`.\n\n### Why is this bad?\nIt's not, but some may wish to lint usage of this method, either to suggest using the host\nendianness or little endian.\n\n### Example\n```rust\nlet _x = 2i32.to_be_bytes();\nlet _y = 2i64.to_be_bytes();\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "bind_instead_of_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 654
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or\n`_.or_else(|x| Err(y))`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.map(|x| y)` or `_.map_err(|x| y)`.\n\n### Example\n```rust\nlet _ = opt().and_then(|s| Some(s.len()));\nlet _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });\nlet _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });\n```\n\nThe correct use would be:\n\n```rust\nlet _ = opt().map(|s| s.len());\nlet _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });\nlet _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });\n```\n### Past names\n\n* `option_and_then_some`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"option_and_then_some"
|
||
]
|
||
},
|
||
{
|
||
"id": "blanket_clippy_restriction_lints",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 227
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.\n\n### Why is this bad?\nRestriction lints sometimes are in contrast with other lints or even go against idiomatic rust.\nThese lints should only be enabled on a lint-by-lint basis and with careful consideration.\n\n### Example\n```rust\n#![deny(clippy::restriction)]\n```\n\nUse instead:\n```rust\n#![deny(clippy::as_conversions)]\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "blocks_in_conditions",
|
||
"id_span": {
|
||
"path": "src/blocks_in_conditions.rs",
|
||
"line": 50
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `if` and `match` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks.\n\n### Why is this bad?\nStyle, using blocks in the condition makes it hard to read.\n\n### Examples\n```rust\nif { true } { /* ... */ }\n\nif { let x = somefunc(); x } { /* ... */ }\n\nmatch { let e = somefunc(); e } {\n // ...\n}\n```\n\nUse instead:\n```rust\nif true { /* ... */ }\n\nlet res = { let x = somefunc(); x };\nif res { /* ... */ }\n\nlet res = { let e = somefunc(); e };\nmatch res {\n // ...\n}\n```\n### Past names\n\n* `block_in_if_condition_expr`\n* `block_in_if_condition_stmt`\n* `blocks_in_if_conditions`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"block_in_if_condition_expr",
|
||
"block_in_if_condition_stmt",
|
||
"blocks_in_if_conditions"
|
||
]
|
||
},
|
||
{
|
||
"id": "bool_assert_comparison",
|
||
"id_span": {
|
||
"path": "src/bool_assert_comparison.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns about boolean comparisons in assert-like macros.\n\n### Why is this bad?\nIt is shorter to use the equivalent.\n\n### Example\n```rust\nassert_eq!(\"a\".is_empty(), false);\nassert_ne!(\"a\".is_empty(), true);\n```\n\nUse instead:\n```rust\nassert!(!\"a\".is_empty());\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "bool_comparison",
|
||
"id_span": {
|
||
"path": "src/needless_bool.rs",
|
||
"line": 77
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions of the form `x == true`,\n`x != true` and order comparisons such as `x < true` (or vice versa) and\nsuggest using the variable directly.\n\n### Why is this bad?\nUnnecessary code.\n\n### Example\n```rust\nif x == true {}\nif y == false {}\n```\nuse `x` directly:\n```rust\nif x {}\nif !y {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "bool_to_int_with_if",
|
||
"id_span": {
|
||
"path": "src/bool_to_int_with_if.rs",
|
||
"line": 43
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nInstead of using an if statement to convert a bool to an int,\nthis lint suggests using a `from()` function or an `as` coercion.\n\n### Why is this bad?\nCoercion or `from()` is another way to convert bool to a number.\nBoth methods are guaranteed to return 1 for true, and 0 for false.\n\nSee https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E\n\n### Example\n```rust\nif condition {\n 1_i64\n} else {\n 0\n};\n```\nUse instead:\n```rust\ni64::from(condition);\n```\nor\n```rust\ncondition as i64;\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "borrow_as_ptr",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 590
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of `&expr as *const T` or\n`&mut expr as *mut T`, and suggest using `ptr::addr_of` or\n`ptr::addr_of_mut` instead.\n\n### Why is this bad?\nThis would improve readability and avoid creating a reference\nthat points to an uninitialized value or unaligned place.\nRead the `ptr::addr_of` docs for more information.\n\n### Example\n```rust\nlet val = 1;\nlet p = &val as *const i32;\n\nlet mut val_mut = 1;\nlet p_mut = &mut val_mut as *mut i32;\n```\nUse instead:\n```rust\nlet val = 1;\nlet p = std::ptr::addr_of!(val);\n\nlet mut val_mut = 1;\nlet p_mut = std::ptr::addr_of_mut!(val_mut);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "borrow_deref_ref",
|
||
"id_span": {
|
||
"path": "src/borrow_deref_ref.rs",
|
||
"line": 43
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `&*(&T)`.\n\n### Why is this bad?\nDereferencing and then borrowing a reference value has no effect in most cases.\n\n### Known problems\nFalse negative on such code:\n```rust\nlet x = &12;\nlet addr_x = &x as *const _ as usize;\nlet addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.\n // But if we fix it, assert will fail.\nassert_ne!(addr_x, addr_y);\n```\n\n### Example\n```rust\nlet s = &String::new();\n\nlet a: &String = &* s;\n```\n\nUse instead:\n```rust\nlet a: &String = s;\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "borrow_interior_mutable_const",
|
||
"id_span": {
|
||
"path": "src/non_copy_const.rs",
|
||
"line": 124
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if `const` items which is interior mutable (e.g.,\ncontains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.\n\n### Why is this bad?\nConsts are copied everywhere they are referenced, i.e.,\nevery time you refer to the const a fresh instance of the `Cell` or `Mutex`\nor `AtomicXxxx` will be created, which defeats the whole purpose of using\nthese types in the first place.\n\nThe `const` value should be stored inside a `static` item.\n\n### Known problems\nWhen an enum has variants with interior mutability, use of its non\ninterior mutable variants can generate false positives. See issue\n[#3962](https://github.com/rust-lang/rust-clippy/issues/3962)\n\nTypes that have underlying or potential interior mutability trigger the lint whether\nthe interior mutable field is used or not. See issues\n[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and\n[#3825](https://github.com/rust-lang/rust-clippy/issues/3825)\n\n### Example\n```rust\nuse std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\nconst CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\n\nCONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged\nassert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct\n```\n\nUse instead:\n```rust\nuse std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\nconst CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\n\nstatic STATIC_ATOM: AtomicUsize = CONST_ATOM;\nSTATIC_ATOM.store(9, SeqCst);\nassert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "borrowed_box",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 186
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `&Box<T>` anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n\n### Why is this bad?\nA `&Box<T>` parameter requires the function caller to box `T` first before passing it to a function.\nUsing `&T` defines a concrete type for the parameter and generalizes the function, this would also\nauto-deref to `&T` at the function call site if passed a `&Box<T>`.\n\n### Example\n```rust\nfn foo(bar: &Box<T>) { ... }\n```\n\nBetter:\n\n```rust\nfn foo(bar: &T) { ... }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "box_collection",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 48
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n\n### Why is this bad?\nCollections already keeps their contents in a separate area on\nthe heap. So if you `Box` them, you just add another level of indirection\nwithout any benefit whatsoever.\n\n### Example\n```rust\nstruct X {\n values: Box<Vec<Foo>>,\n}\n```\n\nBetter:\n\n```rust\nstruct X {\n values: Vec<Foo>,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)\n### Past names\n\n* `box_vec`\n\n",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"box_vec"
|
||
]
|
||
},
|
||
{
|
||
"id": "box_default",
|
||
"id_span": {
|
||
"path": "src/box_default.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nchecks for `Box::new(Default::default())`, which can be written as\n`Box::default()`.\n\n### Why is this bad?\n`Box::default()` is equivalent and more concise.\n\n### Example\n```rust\nlet x: Box<String> = Box::new(Default::default());\n```\nUse instead:\n```rust\nlet x: Box<String> = Box::default();\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "boxed_local",
|
||
"id_span": {
|
||
"path": "src/escape.rs",
|
||
"line": 40
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `Box<T>` where an unboxed `T` would\nwork fine.\n\n### Why is this bad?\nThis is an unnecessary allocation, and bad for\nperformance. It is only necessary to allocate if you wish to move the box\ninto something.\n\n### Example\n```rust\nfn foo(x: Box<u32>) {}\n```\n\nUse instead:\n```rust\nfn foo(x: u32) {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `too-large-for-stack`: The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap (default: `200`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "branches_sharing_code",
|
||
"id_span": {
|
||
"path": "src/copies.rs",
|
||
"line": 157
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks if the `if` and `else` block contain shared code that can be\nmoved out of the blocks.\n\n### Why is this bad?\nDuplicate code is less maintainable.\n\n### Known problems\n* The lint doesn't check if the moved expressions modify values that are being used in\n the if condition. The suggestion can in that case modify the behavior of the program.\n See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)\n\n### Example\n```rust\nlet foo = if … {\n println!(\"Hello World\");\n 13\n} else {\n println!(\"Hello World\");\n 42\n};\n```\n\nUse instead:\n```rust\nprintln!(\"Hello World\");\nlet foo = if … {\n 13\n} else {\n 42\n};\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "builtin_type_shadow",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 247
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns if a generic shadows a built-in type.\n\n### Why is this bad?\nThis gives surprising type errors.\n\n### Example\n\n```rust\nimpl<u32> Foo<u32> {\n fn impl_func(&self) -> u32 {\n 42\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "bytes_count_to_len",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2567
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nIt checks for `str::bytes().count()` and suggests replacing it with\n`str::len()`.\n\n### Why is this bad?\n`str::bytes().count()` is longer and may not be as performant as using\n`str::len()`.\n\n### Example\n```rust\n\"hello\".bytes().count();\nString::from(\"hello\").bytes().count();\n```\nUse instead:\n```rust\n\"hello\".len();\nString::from(\"hello\").len();\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "bytes_nth",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2046
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `.bytes().nth()`.\n\n### Why is this bad?\n`.as_bytes().get()` is more efficient and more\nreadable.\n\n### Example\n```rust\n\"Hello\".bytes().nth(3);\n```\n\nUse instead:\n```rust\n\"Hello\".as_bytes().get(3);\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "cargo_common_metadata",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 53
|
||
},
|
||
"group": "cargo",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks to see if all common metadata is defined in\n`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata\n\n### Why is this bad?\nIt will be more difficult for users to discover the\npurpose of the crate, and key information related to it.\n\n### Example\n```toml\n# This `Cargo.toml` is missing a description field:\n[package]\nname = \"clippy\"\nversion = \"0.0.212\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"plugin\"]\ncategories = [\"development-tools\", \"development-tools::cargo-plugins\"]\n```\n\nShould include a description field like:\n\n```toml\n# This `Cargo.toml` includes all common metadata\n[package]\nname = \"clippy\"\nversion = \"0.0.212\"\ndescription = \"A bunch of helpful lints to avoid common pitfalls in Rust\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"plugin\"]\ncategories = [\"development-tools\", \"development-tools::cargo-plugins\"]\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `cargo-ignore-publish`: For internal testing only, ignores the current `publish` settings in the Cargo manifest. (default: `false`)",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "case_sensitive_file_extension_comparisons",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2595
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for calls to `ends_with` with possible file extensions\nand suggests to use a case-insensitive approach instead.\n\n### Why is this bad?\n`ends_with` is case-sensitive and may not detect files with a valid extension.\n\n### Example\n```rust\nfn is_rust_file(filename: &str) -> bool {\n filename.ends_with(\".rs\")\n}\n```\nUse instead:\n```rust\nfn is_rust_file(filename: &str) -> bool {\n let filename = std::path::Path::new(filename);\n filename.extension()\n .map_or(false, |ext| ext.eq_ignore_ascii_case(\"rs\"))\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_abs_to_unsigned",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 529
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of the `abs()` method that cast the result to unsigned.\n\n### Why is this bad?\nThe `unsigned_abs()` method avoids panic when called on the MIN value.\n\n### Example\n```rust\nlet x: i32 = -42;\nlet y: u32 = x.abs() as u32;\n```\nUse instead:\n```rust\nlet x: i32 = -42;\nlet y: u32 = x.unsigned_abs();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_enum_constructor",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 506
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for casts from an enum tuple constructor to an integer.\n\n### Why is this bad?\nThe cast is easily confused with casting a c-like enum value to an integer.\n\n### Example\n```rust\nenum E { X(i32) };\nlet _ = E::X as usize;\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_enum_truncation",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 443
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for casts from an enum type to an integral type which will definitely truncate the\nvalue.\n\n### Why is this bad?\nThe resulting integral value will not match the value of the variant it came from.\n\n### Example\n```rust\nenum E { X = 256 };\nlet _ = E::X as u8;\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_lossless",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 173
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts between numerical types that may\nbe replaced by safe conversion functions.\n\n### Why is this bad?\nRust's `as` keyword will perform many kinds of\nconversions, including silently lossy conversions. Conversion functions such\nas `i32::from` will only perform lossless conversions. Using the conversion\nfunctions prevents conversions from turning into silent lossy conversions if\nthe types of the input expressions ever change, and make it easier for\npeople reading the code to know that the conversion is lossless.\n\n### Example\n```rust\nfn as_u64(x: u8) -> u64 {\n x as u64\n}\n```\n\nUsing `::from` would look like this:\n\n```rust\nfn as_u64(x: u8) -> u64 {\n u64::from(x)\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_nan_to_int",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 665
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for a known NaN float being cast to an integer\n\n### Why is this bad?\nNaNs are cast into zero, so one could simply use this and make the\ncode more readable. The lint could also hint at a programmer error.\n\n### Example\n```rust\nlet _: (0.0_f32 / 0.0) as u64;\n```\nUse instead:\n```rust\nlet _: = 0_u64;\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_possible_truncation",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 115
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts between numerical types that may\ntruncate large values. This is expected behavior, so the cast is `Allow` by\ndefault. It suggests user either explicitly ignore the lint,\nor use `try_from()` and handle the truncation, default, or panic explicitly.\n\n### Why is this bad?\nIn some problem domains, it is good practice to avoid\ntruncation. This lint can be activated to help assess where additional\nchecks could be beneficial.\n\n### Example\n```rust\nfn as_u8(x: u64) -> u8 {\n x as u8\n}\n```\nUse instead:\n```rust\nfn as_u8(x: u64) -> u8 {\n if let Ok(x) = u8::try_from(x) {\n x\n } else {\n todo!();\n }\n}\n// Or\n#[allow(clippy::cast_possible_truncation)]\nfn as_u16(x: u64) -> u16 {\n x as u16\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_possible_wrap",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 140
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts from an unsigned type to a signed type of\nthe same size, or possibly smaller due to target dependent integers.\nPerforming such a cast is a 'no-op' for the compiler, i.e., nothing is\nchanged at the bit level, and the binary representation of the value is\nreinterpreted. This can cause wrapping if the value is too big\nfor the target signed type. However, the cast works as defined, so this lint\nis `Allow` by default.\n\n### Why is this bad?\nWhile such a cast is not bad in itself, the results can\nbe surprising when this is not the intended behavior, as demonstrated by the\nexample below.\n\n### Example\n```rust\nu32::MAX as i32; // will yield a value of `-1`\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_precision_loss",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 54
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts from any numerical to a float type where\nthe receiving type cannot store all values from the original type without\nrounding errors. This possible rounding is to be expected, so this lint is\n`Allow` by default.\n\nBasically, this warns on casting any integer with 32 or more bits to `f32`\nor any 64-bit integer to `f64`.\n\n### Why is this bad?\nIt's not bad at all. But in some applications it can be\nhelpful to know where precision loss can take place. This lint can help find\nthose places in the code.\n\n### Example\n```rust\nlet x = u64::MAX;\nx as f64;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_ptr_alignment",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 235
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts, using `as` or `pointer::cast`,\nfrom a less-strictly-aligned pointer to a more-strictly-aligned pointer\n\n### Why is this bad?\nDereferencing the resulting pointer may be undefined\nbehavior.\n\n### Known problems\nUsing `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar\non the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like\nu64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.\n\n### Example\n```rust\nlet _ = (&1u8 as *const u8) as *const u16;\nlet _ = (&mut 1u8 as *mut u8) as *mut u16;\n\n(&1u8 as *const u8).cast::<u16>();\n(&mut 1u8 as *mut u8).cast::<u16>();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_sign_loss",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 76
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts from a signed to an unsigned numerical\ntype. In this case, negative values wrap around to large positive values,\nwhich can be quite surprising in practice. However, as the cast works as\ndefined, this lint is `Allow` by default.\n\n### Why is this bad?\nPossibly surprising results. You can activate this lint\nas a one-time check to see where numerical wrapping can arise.\n\n### Example\n```rust\nlet y: i8 = -1;\ny as u128; // will return 18446744073709551615\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_slice_different_sizes",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 488
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `as` casts between raw pointers to slices with differently sized elements.\n\n### Why is this bad?\nThe produced raw pointer to a slice does not update its length metadata. The produced\npointer will point to a different number of bytes than the original pointer because the\nlength metadata of a raw slice pointer is in elements rather than bytes.\nProducing a slice reference from the raw pointer will either create a slice with\nless data (which can be surprising) or create a slice with more data and cause Undefined Behavior.\n\n### Example\n// Missing data\n```rust\nlet a = [1_i32, 2, 3, 4];\nlet p = &a as *const [i32] as *const [u8];\nunsafe {\n println!(\"{:?}\", &*p);\n}\n```\n// Undefined Behavior (note: also potential alignment issues)\n```rust\nlet a = [1_u8, 2, 3, 4];\nlet p = &a as *const [u8] as *const [u32];\nunsafe {\n println!(\"{:?}\", &*p);\n}\n```\nInstead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length\n```rust\nlet a = [1_i32, 2, 3, 4];\nlet old_ptr = &a as *const [i32];\n// The data pointer is cast to a pointer to the target `u8` not `[u8]`\n// The length comes from the known length of 4 i32s times the 4 bytes per i32\nlet new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);\nunsafe {\n println!(\"{:?}\", &*new_ptr);\n}\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cast_slice_from_raw_parts",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 617
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for a raw slice being cast to a slice pointer\n\n### Why is this bad?\nThis can result in multiple `&mut` references to the same location when only a pointer is\nrequired.\n`ptr::slice_from_raw_parts` is a safe alternative that doesn't require\nthe same [safety requirements] to be upheld.\n\n### Example\n```rust\nlet _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;\nlet _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;\n```\nUse instead:\n```rust\nlet _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);\nlet _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);\n```\n[safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "char_lit_as_u8",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 367
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions where a character literal is cast\nto `u8` and suggests using a byte literal instead.\n\n### Why is this bad?\nIn general, casting values to smaller types is\nerror-prone and should be avoided where possible. In the particular case of\nconverting a character literal to u8, it is easy to avoid by just using a\nbyte literal instead. As an added bonus, `b'a'` is even slightly shorter\nthan `'a' as u8`.\n\n### Example\n```rust\n'x' as u8\n```\n\nA better version, using the byte literal:\n\n```rust\nb'x'\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "chars_last_cmp",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1491
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.chars().last()` or\n`_.chars().next_back()` on a `str` to check if it ends with a given char.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.ends_with(_)`.\n\n### Example\n```rust\nname.chars().last() == Some('_') || name.chars().next_back() == Some('-');\n```\n\nUse instead:\n```rust\nname.ends_with('_') || name.ends_with('-');\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "chars_next_cmp",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 893
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.chars().next()` on a `str` to check\nif it starts with a given char.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.starts_with(_)`.\n\n### Example\n```rust\nlet name = \"foo\";\nif name.chars().next() == Some('_') {};\n```\n\nUse instead:\n```rust\nlet name = \"foo\";\nif name.starts_with('_') {};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "checked_conversions",
|
||
"id_span": {
|
||
"path": "src/checked_conversions.rs",
|
||
"line": 33
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for explicit bounds checking when casting.\n\n### Why is this bad?\nReduces the readability of statements & is error prone.\n\n### Example\n```rust\nfoo <= i32::MAX as u32;\n```\n\nUse instead:\n```rust\ni32::try_from(foo).is_ok();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.37.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "clear_with_drain",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3341
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.drain(..)` for the sole purpose of clearing a container.\n\n### Why is this bad?\nThis creates an unnecessary iterator that is dropped immediately.\n\nCalling `.clear()` also makes the intent clearer.\n\n### Example\n```rust\nlet mut v = vec![1, 2, 3];\nv.drain(..);\n```\nUse instead:\n```rust\nlet mut v = vec![1, 2, 3];\nv.clear();\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "clone_on_copy",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1020
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.clone()` on a `Copy` type.\n\n### Why is this bad?\nThe only reason `Copy` types implement `Clone` is for\ngenerics, not for using the `clone` method on a concrete type.\n\n### Example\n```rust\n42u64.clone();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "clone_on_ref_ptr",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1051
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.clone()` on a ref-counted pointer,\n(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified\nfunction syntax instead (e.g., `Rc::clone(foo)`).\n\n### Why is this bad?\nCalling '.clone()' on an Rc, Arc, or Weak\ncan obscure the fact that only the pointer is being cloned, not the underlying\ndata.\n\n### Example\n```rust\nlet x = Rc::new(1);\n\nx.clone();\n```\n\nUse instead:\n```rust\nRc::clone(&x);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "cloned_instead_of_copied",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 166
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `cloned()` on an `Iterator` or `Option` where\n`copied()` could be used instead.\n\n### Why is this bad?\n`copied()` is better because it guarantees that the type being cloned\nimplements `Copy`.\n\n### Example\n```rust\n[1, 2, 3].iter().cloned();\n```\nUse instead:\n```rust\n[1, 2, 3].iter().copied();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "cmp_null",
|
||
"id_span": {
|
||
"path": "src/ptr.rs",
|
||
"line": 94
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint checks for equality comparisons with `ptr::null`\n\n### Why is this bad?\nIt's easier and more readable to use the inherent\n`.is_null()`\nmethod instead\n\n### Example\n```rust\nuse std::ptr;\n\nif x == ptr::null {\n // ..\n}\n```\n\nUse instead:\n```rust\nif x.is_null() {\n // ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "cmp_owned",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 551
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for conversions to owned values just for the sake\nof a comparison.\n\n### Why is this bad?\nThe comparison can operate on a reference, so creating\nan owned value effectively throws it away directly afterwards, which is\nneedlessly consuming code and heap space.\n\n### Example\n```rust\nif x.to_owned() == y {}\n```\n\nUse instead:\n```rust\nif x == y {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "cognitive_complexity",
|
||
"id_span": {
|
||
"path": "src/cognitive_complexity.rs",
|
||
"line": 32
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for methods with high cognitive complexity.\n\n### Why is this bad?\nMethods of high cognitive complexity tend to be hard to\nboth read and maintain. Also LLVM will tend to optimize small methods better.\n\n### Known problems\nSometimes it's hard to find a way to reduce the\ncomplexity.\n\n### Example\nYou'll see it when you get the warning.\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `cognitive-complexity-threshold`: The maximum cognitive complexity a function can have (default: `25`)\n### Past names\n\n* `cyclomatic_complexity`\n\n",
|
||
"version": "1.35.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"cyclomatic_complexity"
|
||
]
|
||
},
|
||
{
|
||
"id": "collapsible_else_if",
|
||
"id_span": {
|
||
"path": "src/collapsible_if.rs",
|
||
"line": 87
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for collapsible `else { if ... }` expressions\nthat can be collapsed to `else if ...`.\n\n### Why is this bad?\nEach `if`-statement adds one level of nesting, which\nmakes code look more complex than it really is.\n\n### Example\n```rust\n\nif x {\n …\n} else {\n if y {\n …\n }\n}\n```\n\nShould be written:\n\n```rust\nif x {\n …\n} else if y {\n …\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "collapsible_if",
|
||
"id_span": {
|
||
"path": "src/collapsible_if.rs",
|
||
"line": 51
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for nested `if` statements which can be collapsed\nby `&&`-combining their conditions.\n\n### Why is this bad?\nEach `if`-statement adds one level of nesting, which\nmakes code look more complex than it really is.\n\n### Example\n```rust\nif x {\n if y {\n // …\n }\n}\n```\n\nUse instead:\n```rust\nif x && y {\n // …\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "collapsible_match",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 695
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nFinds nested `match` or `if let` expressions where the patterns may be \"collapsed\" together\nwithout adding any branches.\n\nNote that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only\ncases where merging would most likely make the code more readable.\n\n### Why is this bad?\nIt is unnecessarily verbose and complex.\n\n### Example\n```rust\nfn func(opt: Option<Result<u64, String>>) {\n let n = match opt {\n Some(n) => match n {\n Ok(n) => n,\n _ => return,\n }\n None => return,\n };\n}\n```\nUse instead:\n```rust\nfn func(opt: Option<Result<u64, String>>) {\n let n = match opt {\n Some(Ok(n)) => n,\n _ => return,\n };\n}\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "collapsible_str_replace",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 192
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for consecutive calls to `str::replace` (2 or more)\nthat can be collapsed into a single call.\n\n### Why is this bad?\nConsecutive `str::replace` calls scan the string multiple times\nwith repetitive code.\n\n### Example\n```rust\nlet hello = \"hesuo worpd\"\n .replace('s', \"l\")\n .replace(\"u\", \"l\")\n .replace('p', \"l\");\n```\nUse instead:\n```rust\nlet hello = \"hesuo worpd\".replace(['s', 'u', 'p'], \"l\");\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "collection_is_never_read",
|
||
"id_span": {
|
||
"path": "src/collection_is_never_read.rs",
|
||
"line": 41
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for collections that are never queried.\n\n### Why is this bad?\nPutting effort into constructing a collection but then never querying it might indicate that\nthe author forgot to do whatever they intended to do with the collection. Example: Clone\na vector, sort it for iteration, but then mistakenly iterate the original vector\ninstead.\n\n### Example\n```rust\nlet mut sorted_samples = samples.clone();\nsorted_samples.sort();\nfor sample in &samples { // Oops, meant to use `sorted_samples`.\n println!(\"{sample}\");\n}\n```\nUse instead:\n```rust\nlet mut sorted_samples = samples.clone();\nsorted_samples.sort();\nfor sample in &sorted_samples {\n println!(\"{sample}\");\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "comparison_chain",
|
||
"id_span": {
|
||
"path": "src/comparison_chain.rs",
|
||
"line": 53
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks comparison chains written with `if` that can be\nrewritten with `match` and `cmp`.\n\n### Why is this bad?\n`if` is not guaranteed to be exhaustive and conditionals can get\nrepetitive\n\n### Known problems\nThe match statement may be slower due to the compiler\nnot inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)\n\n### Example\n```rust\nfn f(x: u8, y: u8) {\n if x > y {\n a()\n } else if x < y {\n b()\n } else {\n c()\n }\n}\n```\n\nUse instead:\n```rust\nuse std::cmp::Ordering;\nfn f(x: u8, y: u8) {\n match x.cmp(&y) {\n Ordering::Greater => a(),\n Ordering::Less => b(),\n Ordering::Equal => c()\n }\n}\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "comparison_to_empty",
|
||
"id_span": {
|
||
"path": "src/len_zero.rs",
|
||
"line": 115
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for comparing to an empty slice such as `\"\"` or `[]`,\nand suggests using `.is_empty()` where applicable.\n\n### Why is this bad?\nSome structures can answer `.is_empty()` much faster\nthan checking for equality. So it is good to get into the habit of using\n`.is_empty()`, and having it is cheap.\nBesides, it makes the intent clearer than a manual comparison in some contexts.\n\n### Example\n\n```rust\nif s == \"\" {\n ..\n}\n\nif arr == [] {\n ..\n}\n```\nUse instead:\n```rust\nif s.is_empty() {\n ..\n}\n\nif arr.is_empty() {\n ..\n}\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "const_is_empty",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 4081
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nIt identifies calls to `.is_empty()` on constant values.\n\n### Why is this bad?\nString literals and constant values are known at compile time. Checking if they\nare empty will always return the same value. This might not be the intention of\nthe expression.\n\n### Example\n```rust\nlet value = \"\";\nif value.is_empty() {\n println!(\"the string is empty\");\n}\n```\nUse instead:\n```rust\nprintln!(\"the string is empty\");\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "copy_iterator",
|
||
"id_span": {
|
||
"path": "src/copy_iterator.rs",
|
||
"line": 30
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for types that implement `Copy` as well as\n`Iterator`.\n\n### Why is this bad?\nImplicit copies can be confusing when working with\niterator combinators.\n\n### Example\n```rust\n#[derive(Copy, Clone)]\nstruct Countdown(u8);\n\nimpl Iterator for Countdown {\n // ...\n}\n\nlet a: Vec<_> = my_iterator.take(1).collect();\nlet b: Vec<_> = my_iterator.collect();\n```",
|
||
"version": "1.30.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "crate_in_macro_def",
|
||
"id_span": {
|
||
"path": "src/crate_in_macro_def.rs",
|
||
"line": 48
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `crate` as opposed to `$crate` in a macro definition.\n\n### Why is this bad?\n`crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's\ncrate. Rarely is the former intended. See:\nhttps://doc.rust-lang.org/reference/macros-by-example.html#hygiene\n\n### Example\n```rust\n#[macro_export]\nmacro_rules! print_message {\n () => {\n println!(\"{}\", crate::MESSAGE);\n };\n}\npub const MESSAGE: &str = \"Hello!\";\n```\nUse instead:\n```rust\n#[macro_export]\nmacro_rules! print_message {\n () => {\n println!(\"{}\", $crate::MESSAGE);\n };\n}\npub const MESSAGE: &str = \"Hello!\";\n```\n\nNote that if the use of `crate` is intentional, an `allow` attribute can be applied to the\nmacro definition, e.g.:\n```rust\n#[allow(clippy::crate_in_macro_def)]\nmacro_rules! ok { ... crate::foo ... }\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "create_dir",
|
||
"id_span": {
|
||
"path": "src/create_dir.rs",
|
||
"line": 26
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.\n\n### Why is this bad?\nSometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.\n\n### Example\n```rust\nstd::fs::create_dir(\"foo\");\n```\n\nUse instead:\n```rust\nstd::fs::create_dir_all(\"foo\");\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "crosspointer_transmute",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 111
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes between a type `T` and `*T`.\n\n### Why is this bad?\nIt's easy to mistakenly transmute between a type and a\npointer to that type.\n\n### Example\n```rust\ncore::intrinsics::transmute(t) // where the result type is the same as\n // `*t` or `&t`'s\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "dbg_macro",
|
||
"id_span": {
|
||
"path": "src/dbg_macro.rs",
|
||
"line": 31
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro.\n\n### Why is this bad?\nThe `dbg!` macro is intended as a debugging tool. It should not be present in released\nsoftware or committed to a version control system.\n\n### Example\n```rust\ndbg!(true)\n```\n\nUse instead:\n```rust\ntrue\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-dbg-in-tests`: Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` (default: `false`)",
|
||
"version": "1.34.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "debug_assert_with_mut_call",
|
||
"id_span": {
|
||
"path": "src/mutable_debug_assertion.rs",
|
||
"line": 33
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for function/method calls with a mutable\nparameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros.\n\n### Why is this bad?\nIn release builds `debug_assert!` macros are optimized out by the\ncompiler.\nTherefore mutating something in a `debug_assert!` macro results in different behavior\nbetween a release and debug build.\n\n### Example\n```rust\ndebug_assert_eq!(vec![3].pop(), Some(3));\n\n// or\n\ndebug_assert!(takes_a_mut_parameter(&mut x));\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "decimal_literal_representation",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 146
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if there is a better representation for a numeric literal.\n\n### Why is this bad?\nEspecially for big powers of 2 a hexadecimal representation is more\nreadable than a decimal representation.\n\n### Example\n```text\n`255` => `0xFF`\n`65_535` => `0xFFFF`\n`4_042_322_160` => `0xF0F0_F0F0`\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `literal-representation-threshold`: The lower bound for linting decimal literals (default: `16384`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "declare_interior_mutable_const",
|
||
"id_span": {
|
||
"path": "src/non_copy_const.rs",
|
||
"line": 75
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for declaration of `const` items which is interior\nmutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).\n\n### Why is this bad?\nConsts are copied everywhere they are referenced, i.e.,\nevery time you refer to the const a fresh instance of the `Cell` or `Mutex`\nor `AtomicXxxx` will be created, which defeats the whole purpose of using\nthese types in the first place.\n\nThe `const` should better be replaced by a `static` item if a global\nvariable is wanted, or replaced by a `const fn` if a constructor is wanted.\n\n### Known problems\nA \"non-constant\" const item is a legacy way to supply an\ninitialized value to downstream `static` items (e.g., the\n`std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,\nand this lint should be suppressed.\n\nEven though the lint avoids triggering on a constant whose type has enums that have variants\nwith interior mutability, and its value uses non interior mutable variants (see\n[#3962](https://github.com/rust-lang/rust-clippy/issues/3962) and\n[#3825](https://github.com/rust-lang/rust-clippy/issues/3825) for examples);\nit complains about associated constants without default values only based on its types;\nwhich might not be preferable.\nThere're other enums plus associated constants cases that the lint cannot handle.\n\nTypes that have underlying or potential interior mutability trigger the lint whether\nthe interior mutable field is used or not. See issues\n[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and\n\n### Example\n```rust\nuse std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\n\nconst CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\nCONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged\nassert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct\n```\n\nUse instead:\n```rust\nstatic STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);\nSTATIC_ATOM.store(9, SeqCst);\nassert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "default_constructed_unit_structs",
|
||
"id_span": {
|
||
"path": "src/default_constructed_unit_structs.rs",
|
||
"line": 43
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for construction on unit struct using `default`.\n\n### Why is this bad?\nThis adds code complexity and an unnecessary function call.\n\n### Example\n```rust\n#[derive(Default)]\nstruct S<T> {\n _marker: PhantomData<T>\n}\n\nlet _: S<i32> = S {\n _marker: PhantomData::default()\n};\n```\nUse instead:\n```rust\nstruct S<T> {\n _marker: PhantomData<T>\n}\n\nlet _: S<i32> = S {\n _marker: PhantomData\n};\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "default_instead_of_iter_empty",
|
||
"id_span": {
|
||
"path": "src/default_instead_of_iter_empty.rs",
|
||
"line": 27
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nIt checks for `std::iter::Empty::default()` and suggests replacing it with\n`std::iter::empty()`.\n### Why is this bad?\n`std::iter::empty()` is the more idiomatic way.\n### Example\n```rust\nlet _ = std::iter::Empty::<usize>::default();\nlet iter: std::iter::Empty<usize> = std::iter::Empty::default();\n```\nUse instead:\n```rust\nlet _ = std::iter::empty::<usize>();\nlet iter: std::iter::Empty<usize> = std::iter::empty();\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "default_numeric_fallback",
|
||
"id_span": {
|
||
"path": "src/default_numeric_fallback.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of unconstrained numeric literals which may cause default numeric fallback in type\ninference.\n\nDefault numeric fallback means that if numeric types have not yet been bound to concrete\ntypes at the end of type inference, then integer type is bound to `i32`, and similarly\nfloating type is bound to `f64`.\n\nSee [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.\n\n### Why is this bad?\nFor those who are very careful about types, default numeric fallback\ncan be a pitfall that cause unexpected runtime behavior.\n\n### Known problems\nThis lint can only be allowed at the function level or above.\n\n### Example\n```rust\nlet i = 10;\nlet f = 1.23;\n```\n\nUse instead:\n```rust\nlet i = 10i32;\nlet f = 1.23f64;\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "default_trait_access",
|
||
"id_span": {
|
||
"path": "src/default.rs",
|
||
"line": 34
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for literal calls to `Default::default()`.\n\n### Why is this bad?\nIt's easier for the reader if the name of the type is used, rather than the\ngeneric `Default`.\n\n### Example\n```rust\nlet s: String = Default::default();\n```\n\nUse instead:\n```rust\nlet s = String::default();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "default_union_representation",
|
||
"id_span": {
|
||
"path": "src/default_union_representation.rs",
|
||
"line": 47
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDisplays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute).\n\n### Why is this bad?\nUnions in Rust have unspecified layout by default, despite many people thinking that they\nlay out each field at the start of the union (like C does). That is, there are no guarantees\nabout the offset of the fields for unions with multiple non-ZST fields without an explicitly\nspecified layout. These cases may lead to undefined behavior in unsafe blocks.\n\n### Example\n```rust\nunion Foo {\n a: i32,\n b: u32,\n}\n\nfn main() {\n let _x: u32 = unsafe {\n Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding\n };\n}\n```\nUse instead:\n```rust\n#[repr(C)]\nunion Foo {\n a: i32,\n b: u32,\n}\n\nfn main() {\n let _x: u32 = unsafe {\n Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute\n };\n}\n```",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "deprecated_cfg_attr",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 258
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it\nwith `#[rustfmt::skip]`.\n\n### Why is this bad?\nSince tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))\nare stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.\n\n### Known problems\nThis lint doesn't detect crate level inner attributes, because they get\nprocessed before the PreExpansionPass lints get executed. See\n[#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)\n\n### Example\n```rust\n#[cfg_attr(rustfmt, rustfmt_skip)]\nfn main() { }\n```\n\nUse instead:\n```rust\n#[rustfmt::skip]\nfn main() { }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "deprecated_clippy_cfg_attr",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 437
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `#[cfg_attr(feature = \"cargo-clippy\", ...)]` and for\n`#[cfg(feature = \"cargo-clippy\")]` and suggests to replace it with\n`#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.\n\n### Why is this bad?\nThis feature has been deprecated for years and shouldn't be used anymore.\n\n### Example\n```rust\n#[cfg(feature = \"cargo-clippy\")]\nstruct Bar;\n```\n\nUse instead:\n```rust\n#[cfg(clippy)]\nstruct Bar;\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "deprecated_semver",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 116
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `#[deprecated]` annotations with a `since`\nfield that is not a valid semantic version. Also allows \"TBD\" to signal\nfuture deprecation.\n\n### Why is this bad?\nFor checking the version of the deprecation, it must be\na valid semver. Failing that, the contained information is useless.\n\n### Example\n```rust\n#[deprecated(since = \"forever\")]\nfn something_else() { /* ... */ }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "deref_addrof",
|
||
"id_span": {
|
||
"path": "src/reference.rs",
|
||
"line": 33
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `*&` and `*&mut` in expressions.\n\n### Why is this bad?\nImmediately dereferencing a reference is no-op and\nmakes the code less clear.\n\n### Known problems\nMultiple dereference/addrof pairs are not handled so\nthe suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.\n\n### Example\n```rust\nlet a = f(*&mut b);\nlet c = *&d;\n```\n\nUse instead:\n```rust\nlet a = f(b);\nlet c = d;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "deref_by_slicing",
|
||
"id_span": {
|
||
"path": "src/redundant_slicing.rs",
|
||
"line": 63
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for slicing expressions which are equivalent to dereferencing the\nvalue.\n\n### Why is this bad?\nSome people may prefer to dereference rather than slice.\n\n### Example\n```rust\nlet vec = vec![1, 2, 3];\nlet slice = &vec[..];\n```\nUse instead:\n```rust\nlet vec = vec![1, 2, 3];\nlet slice = &*vec;\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "derivable_impls",
|
||
"id_span": {
|
||
"path": "src/derivable_impls.rs",
|
||
"line": 53
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects manual `std::default::Default` implementations that are identical to a derived implementation.\n\n### Why is this bad?\nIt is less concise.\n\n### Example\n```rust\nstruct Foo {\n bar: bool\n}\n\nimpl Default for Foo {\n fn default() -> Self {\n Self {\n bar: false\n }\n }\n}\n```\n\nUse instead:\n```rust\n#[derive(Default)]\nstruct Foo {\n bar: bool\n}\n```\n\n### Known problems\nDerive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)\nin generic types and the user defined `impl` may be more generalized or\nspecialized than what derive will produce. This lint can't detect the manual `impl`\nhas exactly equal bounds, and therefore this lint is disabled for types with\ngeneric parameters.\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "derive_ord_xor_partial_ord",
|
||
"id_span": {
|
||
"path": "src/derive.rs",
|
||
"line": 96
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nLints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord`\nor `PartialOrd` implementation.\n\n### Why is this bad?\nThe implementation of these traits must agree (for\nexample for use with `sort`) so it’s probably a bad idea to use a\ndefault-generated `Ord` implementation with an explicitly defined\n`PartialOrd`. In particular, the following must hold for any type\nimplementing `Ord`:\n\n```text\nk1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()\n```\n\n### Example\n```rust\n#[derive(Ord, PartialEq, Eq)]\nstruct Foo;\n\nimpl PartialOrd for Foo {\n ...\n}\n```\nUse instead:\n```rust\n#[derive(PartialEq, Eq)]\nstruct Foo;\n\nimpl PartialOrd for Foo {\n fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {\n Some(self.cmp(other))\n }\n}\n\nimpl Ord for Foo {\n ...\n}\n```\nor, if you don't need a custom ordering:\n```rust\n#[derive(Ord, PartialOrd, PartialEq, Eq)]\nstruct Foo;\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "derive_partial_eq_without_eq",
|
||
"id_span": {
|
||
"path": "src/derive.rs",
|
||
"line": 189
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for types that derive `PartialEq` and could implement `Eq`.\n\n### Why is this bad?\nIf a type `T` derives `PartialEq` and all of its members implement `Eq`,\nthen `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used\nin APIs that require `Eq` types. It also allows structs containing `T` to derive\n`Eq` themselves.\n\n### Example\n```rust\n#[derive(PartialEq)]\nstruct Foo {\n i_am_eq: i32,\n i_am_eq_too: Vec<String>,\n}\n```\nUse instead:\n```rust\n#[derive(PartialEq, Eq)]\nstruct Foo {\n i_am_eq: i32,\n i_am_eq_too: Vec<String>,\n}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "derived_hash_with_manual_eq",
|
||
"id_span": {
|
||
"path": "src/derive.rs",
|
||
"line": 45
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nLints against manual `PartialEq` implementations for types with a derived `Hash`\nimplementation.\n\n### Why is this bad?\nThe implementation of these traits must agree (for\nexample for use with `HashMap`) so it’s probably a bad idea to use a\ndefault-generated `Hash` implementation with an explicitly defined\n`PartialEq`. In particular, the following must hold for any type:\n\n```text\nk1 == k2 ⇒ hash(k1) == hash(k2)\n```\n\n### Example\n```rust\n#[derive(Hash)]\nstruct Foo;\n\nimpl PartialEq for Foo {\n ...\n}\n```\n### Past names\n\n* `derive_hash_xor_eq`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"derive_hash_xor_eq"
|
||
]
|
||
},
|
||
{
|
||
"id": "disallowed_macros",
|
||
"id_span": {
|
||
"path": "src/disallowed_macros.rs",
|
||
"line": 54
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDenies the configured macros in clippy.toml\n\nNote: Even though this lint is warn-by-default, it will only trigger if\nmacros are defined in the clippy.toml file.\n\n### Why is this bad?\nSome macros are undesirable in certain contexts, and it's beneficial to\nlint for them as needed.\n\n### Example\nAn example clippy.toml configuration:\n```toml\n# clippy.toml\ndisallowed-macros = [\n # Can use a string as the path of the disallowed macro.\n \"std::print\",\n # Can also use an inline table with a `path` key.\n { path = \"std::println\" },\n # When using an inline table, can add a `reason` for why the macro\n # is disallowed.\n { path = \"serde::Serialize\", reason = \"no serializing\" },\n]\n```\n```rust\nuse serde::Serialize;\n\n// Example code where clippy issues a warning\nprintln!(\"warns\");\n\n// The diagnostic will contain the message \"no serializing\"\n#[derive(Serialize)]\nstruct Data {\n name: String,\n value: usize,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `disallowed-macros`: The list of disallowed macros, written as fully qualified paths. (default: `[]`)",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "disallowed_methods",
|
||
"id_span": {
|
||
"path": "src/disallowed_methods.rs",
|
||
"line": 53
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDenies the configured methods and functions in clippy.toml\n\nNote: Even though this lint is warn-by-default, it will only trigger if\nmethods are defined in the clippy.toml file.\n\n### Why is this bad?\nSome methods are undesirable in certain contexts, and it's beneficial to\nlint for them as needed.\n\n### Example\nAn example clippy.toml configuration:\n```toml\n# clippy.toml\ndisallowed-methods = [\n # Can use a string as the path of the disallowed method.\n \"std::boxed::Box::new\",\n # Can also use an inline table with a `path` key.\n { path = \"std::time::Instant::now\" },\n # When using an inline table, can add a `reason` for why the method\n # is disallowed.\n { path = \"std::vec::Vec::leak\", reason = \"no leaking memory\" },\n]\n```\n\n```rust\n// Example code where clippy issues a warning\nlet xs = vec![1, 2, 3, 4];\nxs.leak(); // Vec::leak is disallowed in the config.\n// The diagnostic contains the message \"no leaking memory\".\n\nlet _now = Instant::now(); // Instant::now is disallowed in the config.\n\nlet _box = Box::new(3); // Box::new is disallowed in the config.\n```\n\nUse instead:\n```rust\n// Example code which does not raise clippy warning\nlet mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.\nxs.push(123); // Vec::push is _not_ disallowed in the config.\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `disallowed-methods`: The list of disallowed methods, written as fully qualified paths. (default: `[]`)\n### Past names\n\n* `disallowed_method`\n\n",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"disallowed_method"
|
||
]
|
||
},
|
||
{
|
||
"id": "disallowed_names",
|
||
"id_span": {
|
||
"path": "src/disallowed_names.rs",
|
||
"line": 22
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of disallowed names for variables, such\nas `foo`.\n\n### Why is this bad?\nThese names are usually placeholder names and should be\navoided.\n\n### Example\n```rust\nlet foo = 3.14;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `disallowed-names`: The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value\n `\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\n default configuration of Clippy. By default, any configuration will replace the default value. (default: `[\"foo\", \"baz\", \"quux\"]`)\n### Past names\n\n* `blacklisted_name`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"blacklisted_name"
|
||
]
|
||
},
|
||
{
|
||
"id": "disallowed_script_idents",
|
||
"id_span": {
|
||
"path": "src/disallowed_script_idents.rs",
|
||
"line": 42
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of unicode scripts other than those explicitly allowed\nby the lint config.\n\nThis lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.\nIt also ignores the `Common` script type.\nWhile configuring, be sure to use official script name [aliases] from\n[the list of supported scripts][supported_scripts].\n\nSee also: [`non_ascii_idents`].\n\n[aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases\n[supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html\n\n### Why is this bad?\nIt may be not desired to have many different scripts for\nidentifiers in the codebase.\n\nNote that if you only want to allow plain English, you might want to use\nbuilt-in [`non_ascii_idents`] lint instead.\n\n[`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents\n\n### Example\n```rust\n// Assuming that `clippy.toml` contains the following line:\n// allowed-scripts = [\"Latin\", \"Cyrillic\"]\nlet counter = 10; // OK, latin is allowed.\nlet счётчик = 10; // OK, cyrillic is allowed.\nlet zähler = 10; // OK, it's still latin.\nlet カウンタ = 10; // Will spawn the lint.\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-scripts`: The list of unicode scripts allowed to be used in the scope. (default: `[\"Latin\"]`)",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "disallowed_types",
|
||
"id_span": {
|
||
"path": "src/disallowed_types.rs",
|
||
"line": 47
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDenies the configured types in clippy.toml.\n\nNote: Even though this lint is warn-by-default, it will only trigger if\ntypes are defined in the clippy.toml file.\n\n### Why is this bad?\nSome types are undesirable in certain contexts.\n\n### Example:\nAn example clippy.toml configuration:\n```toml\n# clippy.toml\ndisallowed-types = [\n # Can use a string as the path of the disallowed type.\n \"std::collections::BTreeMap\",\n # Can also use an inline table with a `path` key.\n { path = \"std::net::TcpListener\" },\n # When using an inline table, can add a `reason` for why the type\n # is disallowed.\n { path = \"std::net::Ipv4Addr\", reason = \"no IPv4 allowed\" },\n]\n```\n\n```rust\nuse std::collections::BTreeMap;\n// or its use\nlet x = std::collections::BTreeMap::new();\n```\nUse instead:\n```rust\n// A similar type that is allowed by the config\nuse std::collections::HashMap;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `disallowed-types`: The list of disallowed types, written as fully qualified paths. (default: `[]`)\n### Past names\n\n* `disallowed_type`\n\n",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"disallowed_type"
|
||
]
|
||
},
|
||
{
|
||
"id": "diverging_sub_expression",
|
||
"id_span": {
|
||
"path": "src/mixed_read_write_in_expression.rs",
|
||
"line": 72
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for diverging calls that are not match arms or\nstatements.\n\n### Why is this bad?\nIt is often confusing to read. In addition, the\nsub-expression evaluation order for Rust is not well documented.\n\n### Known problems\nSomeone might want to use `some_bool || panic!()` as a\nshorthand.\n\n### Example\n```rust\nlet a = b() || panic!() || c();\n// `c()` is dead, `panic!()` is only called if `b()` returns `false`\nlet x = (a, b, c, panic!());\n// can simply be replaced by `panic!()`\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "doc_link_with_quotes",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 253
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)\noutside of code blocks\n### Why is this bad?\nIt is likely a typo when defining an intra-doc link\n\n### Example\n```rust\n/// See also: ['foo']\nfn bar() {}\n```\nUse instead:\n```rust\n/// See also: [`foo`]\nfn bar() {}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "doc_markdown",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 73
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the presence of `_`, `::` or camel-case words\noutside ticks in documentation.\n\n### Why is this bad?\n*Rustdoc* supports markdown formatting, `_`, `::` and\ncamel-case probably indicates some code which should be included between\nticks. `_` can also be used for emphasis in markdown, this lint tries to\nconsider that.\n\n### Known problems\nLots of bad docs won’t be fixed, what the lint checks\nfor is limited, and there are still false positives. HTML elements and their\ncontent are not linted.\n\nIn addition, when writing documentation comments, including `[]` brackets\ninside a link text would trip the parser. Therefore, documenting link with\n`[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec\nwould fail.\n\n### Examples\n```rust\n/// Do something with the foo_bar parameter. See also\n/// that::other::module::foo.\n// ^ `foo_bar` and `that::other::module::foo` should be ticked.\nfn doit(foo_bar: usize) {}\n```\n\n```rust\n// Link text with `[]` brackets should be written as following:\n/// Consume the array and return the inner\n/// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].\n/// [SmallVec]: SmallVec\nfn main() {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `doc-valid-idents`: The list of words this lint should not consider as identifiers needing ticks. The value\n `\"..\"` can be used as part of the list to indicate, that the configured values should be appended to the\n default configuration of Clippy. By default, any configuration will replace the default value. For example:\n * `doc-valid-idents = [\"ClipPy\"]` would replace the default list with `[\"ClipPy\"]`.\n * `doc-valid-idents = [\"ClipPy\", \"..\"]` would append `ClipPy` to the default list. (default: `[\"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"DirectX\", \"ECMAScript\", \"GPLv2\", \"GPLv3\", \"GitHub\", \"GitLab\", \"IPv4\", \"IPv6\", \"ClojureScript\", \"CoffeeScript\", \"JavaScript\", \"PureScript\", \"TypeScript\", \"WebAssembly\", \"NaN\", \"NaNs\", \"OAuth\", \"GraphQL\", \"OCaml\", \"OpenDNS\", \"OpenGL\", \"OpenMP\", \"OpenSSH\", \"OpenSSL\", \"OpenStreetMap\", \"OpenTelemetry\", \"WebGL\", \"WebGL2\", \"WebGPU\", \"TensorFlow\", \"TrueType\", \"iOS\", \"macOS\", \"FreeBSD\", \"TeX\", \"LaTeX\", \"BibTeX\", \"BibLaTeX\", \"MinGW\", \"CamelCase\"]`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "double_comparisons",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 297
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for double comparisons that could be simplified to a single expression.\n\n\n### Why is this bad?\nReadability.\n\n### Example\n```rust\nif x == y || x < y {}\n```\n\nUse instead:\n\n```rust\nif x <= y {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "double_must_use",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 161
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for a `#[must_use]` attribute without\nfurther information on functions and methods that return a type already\nmarked as `#[must_use]`.\n\n### Why is this bad?\nThe attribute isn't needed. Not using the result\nwill already be reported. Alternatively, one can add some text to the\nattribute to improve the lint message.\n\n### Examples\n```rust\n#[must_use]\nfn double_must_use() -> Result<(), ()> {\n unimplemented!();\n}\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "double_neg",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 102
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects expressions of the form `--x`.\n\n### Why is this bad?\nIt can mislead C/C++ programmers to think `x` was\ndecremented.\n\n### Example\n```rust\nlet mut x = 3;\n--x;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "double_parens",
|
||
"id_span": {
|
||
"path": "src/double_parens.rs",
|
||
"line": 34
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary double parentheses.\n\n### Why is this bad?\nThis makes code harder to read and might indicate a\nmistake.\n\n### Example\n```rust\nfn simple_double_parens() -> i32 {\n ((0))\n}\n\nfoo((0));\n```\n\nUse instead:\n```rust\nfn simple_no_parens() -> i32 {\n 0\n}\n\nfoo(0);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "drain_collect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3400
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `.drain()` that clear the collection, immediately followed by a call to `.collect()`.\n\n> \"Collection\" in this context refers to any type with a `drain` method:\n> `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String`\n\n### Why is this bad?\nUsing `mem::take` is faster as it avoids the allocation.\nWhen using `mem::take`, the old collection is replaced with an empty one and ownership of\nthe old collection is returned.\n\n### Known issues\n`mem::take(&mut vec)` is almost equivalent to `vec.drain(..).collect()`, except that\nit also moves the **capacity**. The user might have explicitly written it this way\nto keep the capacity on the original `Vec`.\n\n### Example\n```rust\nfn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n v.drain(..).collect()\n}\n```\nUse instead:\n```rust\nuse std::mem;\nfn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n mem::take(v)\n}\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "drop_non_drop",
|
||
"id_span": {
|
||
"path": "src/drop_forget_ref.rs",
|
||
"line": 25
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `std::mem::drop` with a value that does not implement `Drop`.\n\n### Why is this bad?\nCalling `std::mem::drop` is no different than dropping such a type. A different value may\nhave been intended.\n\n### Example\n```rust\nstruct Foo;\nlet x = Foo;\nstd::mem::drop(x);\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "duplicate_mod",
|
||
"id_span": {
|
||
"path": "src/duplicate_mod.rs",
|
||
"line": 43
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for files that are included as modules multiple times.\n\n### Why is this bad?\nLoading a file as a module more than once causes it to be compiled\nmultiple times, taking longer and putting duplicate content into the\nmodule tree.\n\n### Example\n```rust\n// lib.rs\nmod a;\nmod b;\n```\n```rust\n// a.rs\n#[path = \"./b.rs\"]\nmod b;\n```\n\nUse instead:\n\n```rust\n// lib.rs\nmod a;\nmod b;\n```\n```rust\n// a.rs\nuse crate::b;\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "duplicate_underscore_argument",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 83
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for function arguments having the similar names\ndiffering by an underscore.\n\n### Why is this bad?\nIt affects code readability.\n\n### Example\n```rust\nfn foo(a: i32, _a: i32) {}\n```\n\nUse instead:\n```rust\nfn bar(a: i32, _b: i32) {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "duplicated_attributes",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 524
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for attributes that appear two or more times.\n\n### Why is this bad?\nRepeating an attribute on the same item (or globally on the same crate)\nis unnecessary and doesn't have an effect.\n\n### Example\n```rust\n#[allow(dead_code)]\n#[allow(dead_code)]\nfn foo() {}\n```\n\nUse instead:\n```rust\n#[allow(dead_code)]\nfn foo() {}\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "duration_subsec",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 366
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calculation of subsecond microseconds or milliseconds\nfrom other `Duration` methods.\n\n### Why is this bad?\nIt's more concise to call `Duration::subsec_micros()` or\n`Duration::subsec_millis()` than to calculate them.\n\n### Example\n```rust\nlet micros = duration.subsec_nanos() / 1_000;\nlet millis = duration.subsec_nanos() / 1_000_000;\n```\n\nUse instead:\n```rust\nlet micros = duration.subsec_micros();\nlet millis = duration.subsec_millis();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "eager_transmute",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 519
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for integer validity checks, followed by a transmute that is (incorrectly) evaluated\neagerly (e.g. using `bool::then_some`).\n\n### Why is this bad?\nEager evaluation means that the `transmute` call is executed regardless of whether the condition is true or false.\nThis can introduce unsoundness and other subtle bugs.\n\n### Example\nConsider the following function which is meant to convert an unsigned integer to its enum equivalent via transmute.\n\n```rust\n#[repr(u8)]\nenum Opcode {\n Add = 0,\n Sub = 1,\n Mul = 2,\n Div = 3\n}\n\nfn int_to_opcode(op: u8) -> Option<Opcode> {\n (op < 4).then_some(unsafe { std::mem::transmute(op) })\n}\n```\nThis may appear fine at first given that it checks that the `u8` is within the validity range of the enum,\n*however* the transmute is evaluated eagerly, meaning that it executes even if `op >= 4`!\n\nThis makes the function unsound, because it is possible for the caller to cause undefined behavior\n(creating an enum with an invalid bitpattern) entirely in safe code only by passing an incorrect value,\nwhich is normally only a bug that is possible in unsafe code.\n\nOne possible way in which this can go wrong practically is that the compiler sees it as:\n```rust\nlet temp: Foo = unsafe { std::mem::transmute(op) };\n(0 < 4).then_some(temp)\n```\nand optimizes away the `(0 < 4)` check based on the assumption that since a `Foo` was created from `op` with the validity range `0..3`,\nit is **impossible** for this condition to be false.\n\nIn short, it is possible for this function to be optimized in a way that makes it [never return `None`](https://godbolt.org/z/ocrcenevq),\neven if passed the value `4`.\n\nThis can be avoided by instead using lazy evaluation. For the example above, this should be written:\n```rust\nfn int_to_opcode(op: u8) -> Option<Opcode> {\n (op < 4).then(|| unsafe { std::mem::transmute(op) })\n ^^^^ ^^ `bool::then` only executes the closure if the condition is true!\n}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "else_if_without_else",
|
||
"id_span": {
|
||
"path": "src/else_if_without_else.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of if expressions with an `else if` branch,\nbut without a final `else` branch.\n\n### Why is this bad?\nSome coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).\n\n### Example\n```rust\nif x.is_positive() {\n a();\n} else if x.is_negative() {\n b();\n}\n```\n\nUse instead:\n\n```rust\nif x.is_positive() {\n a();\n} else if x.is_negative() {\n b();\n} else {\n // We don't care about zero.\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_docs",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 360
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects documentation that is empty.\n### Why is this bad?\nEmpty docs clutter code without adding value, reducing readability and maintainability.\n### Example\n```rust\n///\nfn returns_true() -> bool {\n true\n}\n```\nUse instead:\n```rust\nfn returns_true() -> bool {\n true\n}\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_drop",
|
||
"id_span": {
|
||
"path": "src/empty_drop.rs",
|
||
"line": 30
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for empty `Drop` implementations.\n\n### Why is this bad?\nEmpty `Drop` implementations have no effect when dropping an instance of the type. They are\nmost likely useless. However, an empty `Drop` implementation prevents a type from being\ndestructured, which might be the intention behind adding the implementation as a marker.\n\n### Example\n```rust\nstruct S;\n\nimpl Drop for S {\n fn drop(&mut self) {}\n}\n```\nUse instead:\n```rust\nstruct S;\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_enum",
|
||
"id_span": {
|
||
"path": "src/empty_enum.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `enum`s with no variants.\n\nAs of this writing, the `never_type` is still a\nnightly-only experimental API. Therefore, this lint is only triggered\nif the `never_type` is enabled.\n\n### Why is this bad?\nIf you want to introduce a type which\ncan't be instantiated, you should use `!` (the primitive type \"never\"),\nor a wrapper around it, because `!` has more extensive\ncompiler support (type inference, etc...) and wrappers\naround it are the conventional way to define an uninhabited type.\nFor further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html)\n\n\n### Example\n```rust\nenum Test {}\n```\n\nUse instead:\n```rust\n#![feature(never_type)]\n\nstruct Test(!);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_enum_variants_with_brackets",
|
||
"id_span": {
|
||
"path": "src/empty_with_brackets.rs",
|
||
"line": 54
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nFinds enum variants without fields that are declared with empty brackets.\n\n### Why is this bad?\nEmpty brackets while defining enum variants are redundant and can be omitted.\n\n### Example\n```rust\nenum MyEnum {\n HasData(u8),\n HasNoData(), // redundant parentheses\n}\n```\n\nUse instead:\n```rust\nenum MyEnum {\n HasData(u8),\n HasNoData,\n}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_line_after_doc_comments",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 204
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for empty lines after documentation comments.\n\n### Why is this bad?\nThe documentation comment was most likely meant to be an inner attribute or regular comment.\nIf it was intended to be a documentation comment, then the empty line should be removed to\nbe more idiomatic.\n\n### Known problems\nOnly detects empty lines immediately following the documentation. If the doc comment is followed\nby an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`\nin combination with this lint to detect both cases.\n\nDoes not detect empty lines after doc attributes (e.g. `#[doc = \"\"]`).\n\n### Example\n```rust\n/// Some doc comment with a blank line after it.\n\nfn not_quite_good_code() { }\n```\n\nUse instead:\n```rust\n/// Good (no blank line)\nfn this_is_fine() { }\n```\n\n```rust\n// Good (convert to a regular comment)\n\nfn this_is_fine_too() { }\n```\n\n```rust\n//! Good (convert to a comment on an inner attribute)\n\nfn this_is_fine_as_well() { }\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_line_after_outer_attr",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 158
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for empty lines after outer attributes\n\n### Why is this bad?\nMost likely the attribute was meant to be an inner attribute using a '!'.\nIf it was meant to be an outer attribute, then the following item\nshould not be separated by empty lines.\n\n### Known problems\nCan cause false positives.\n\nFrom the clippy side it's difficult to detect empty lines between an attributes and the\nfollowing item because empty lines and comments are not part of the AST. The parsing\ncurrently works for basic cases but is not perfect.\n\n### Example\n```rust\n#[allow(dead_code)]\n\nfn not_quite_good_code() { }\n```\n\nUse instead:\n```rust\n// Good (as inner attribute)\n#![allow(dead_code)]\n\nfn this_is_fine() { }\n\n// or\n\n// Good (as outer attribute)\n#[allow(dead_code)]\nfn this_is_fine_too() { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 273
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for empty `loop` expressions.\n\n### Why is this bad?\nThese busy loops burn CPU cycles without doing\nanything. It is _almost always_ a better idea to `panic!` than to have\na busy loop.\n\nIf panicking isn't possible, think of the environment and either:\n - block on something\n - sleep the thread for some microseconds\n - yield or pause the thread\n\nFor `std` targets, this can be done with\n[`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)\nor [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).\n\nFor `no_std` targets, doing this is more complicated, especially because\n`#[panic_handler]`s can't panic. To stop/pause the thread, you will\nprobably need to invoke some target-specific intrinsic. Examples include:\n - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)\n - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)\n\n### Example\n```rust\nloop {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "empty_structs_with_brackets",
|
||
"id_span": {
|
||
"path": "src/empty_with_brackets.rs",
|
||
"line": 26
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nFinds structs without fields (a so-called \"empty struct\") that are declared with brackets.\n\n### Why is this bad?\nEmpty brackets after a struct declaration can be omitted.\n\n### Example\n```rust\nstruct Cookie {}\n```\nUse instead:\n```rust\nstruct Cookie;\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "enum_clike_unportable_variant",
|
||
"id_span": {
|
||
"path": "src/enum_clike.rs",
|
||
"line": 31
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for C-like enumerations that are\n`repr(isize/usize)` and have values that don't fit into an `i32`.\n\n### Why is this bad?\nThis will truncate the variant value on 32 bit\narchitectures, but works fine on 64 bit.\n\n### Example\n```rust\n#[repr(usize)]\nenum NonPortable {\n X = 0x1_0000_0000,\n Y = 0,\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "enum_glob_use",
|
||
"id_span": {
|
||
"path": "src/wildcard_imports.rs",
|
||
"line": 42
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `use Enum::*`.\n\n### Why is this bad?\nIt is usually better style to use the prefixed name of\nan enumeration variant, rather than importing variants.\n\n### Known problems\nOld-style enumerations that prefix the variants are\nstill around.\n\n### Example\n```rust\nuse std::cmp::Ordering::*;\n\nfoo(Less);\n```\n\nUse instead:\n```rust\nuse std::cmp::Ordering;\n\nfoo(Ordering::Less)\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "enum_variant_names",
|
||
"id_span": {
|
||
"path": "src/item_name_repetitions.rs",
|
||
"line": 47
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects enumeration variants that are prefixed or suffixed\nby the same characters.\n\n### Why is this bad?\nEnumeration variant names should specify their variant,\nnot repeat the enumeration name.\n\n### Limitations\nCharacters with no casing will be considered when comparing prefixes/suffixes\nThis applies to numbers and non-ascii characters without casing\ne.g. `Foo1` and `Foo2` is considered to have different prefixes\n(the prefixes are `Foo1` and `Foo2` respectively), as also `Bar螃`, `Bar蟹`\n\n### Example\n```rust\nenum Cake {\n BlackForestCake,\n HummingbirdCake,\n BattenbergCake,\n}\n```\nUse instead:\n```rust\nenum Cake {\n BlackForest,\n Hummingbird,\n Battenberg,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `enum-variant-name-threshold`: The minimum number of enum variants for the lints about variant names to trigger (default: `3`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "eq_op",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 398
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for equal operands to comparison, logical and\nbitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n`||`, `&`, `|`, `^`, `-` and `/`).\n\n### Why is this bad?\nThis is usually just a typo or a copy and paste error.\n\n### Known problems\nFalse negatives: We had some false positives regarding\ncalls (notably [racer](https://github.com/phildawes/racer) had one instance\nof `x.pop() && x.pop()`), so we removed matching any function or method\ncalls. We may introduce a list of known pure functions in the future.\n\n### Example\n```rust\nif x + 1 == x + 1 {}\n\n// or\n\nassert_eq!(a, a);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "equatable_if_let",
|
||
"id_span": {
|
||
"path": "src/equatable_if_let.rs",
|
||
"line": 36
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for pattern matchings that can be expressed using equality.\n\n### Why is this bad?\n\n* It reads better and has less cognitive load because equality won't cause binding.\n* It is a [Yoda condition](https://en.wikipedia.org/wiki/Yoda_conditions). Yoda conditions are widely\ncriticized for increasing the cognitive load of reading the code.\n* Equality is a simple bool expression and can be merged with `&&` and `||` and\nreuse if blocks\n\n### Example\n```rust\nif let Some(2) = x {\n do_thing();\n}\n```\nUse instead:\n```rust\nif x == Some(2) {\n do_thing();\n}\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "erasing_op",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 444
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for erasing operations, e.g., `x * 0`.\n\n### Why is this bad?\nThe whole expression can be replaced by zero.\nThis is most likely not the intended outcome and should probably be\ncorrected\n\n### Example\n```rust\nlet x = 1;\n0 / x;\n0 * x;\nx & 0;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "err_expect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 493
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.err().expect()` calls on the `Result` type.\n\n### Why is this bad?\n`.expect_err()` can be called directly to avoid the extra type conversion from `err()`.\n\n### Example\n```rust\nlet x: Result<u32, &str> = Ok(10);\nx.err().expect(\"Testing err().expect()\");\n```\nUse instead:\n```rust\nlet x: Result<u32, &str> = Ok(10);\nx.expect_err(\"Testing expect_err\");\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "error_impl_error",
|
||
"id_span": {
|
||
"path": "src/error_impl_error.rs",
|
||
"line": 31
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for types named `Error` that implement `Error`.\n\n### Why is this bad?\nIt can become confusing when a codebase has 20 types all named `Error`, requiring either\naliasing them in the `use` statement or qualifying them like `my_module::Error`. This\nhinders comprehension, as it requires you to memorize every variation of importing `Error`\nused across a codebase.\n\n### Example\n```rust\n#[derive(Debug)]\npub enum Error { ... }\n\nimpl std::fmt::Display for Error { ... }\n\nimpl std::error::Error for Error { ... }\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "excessive_nesting",
|
||
"id_span": {
|
||
"path": "src/excessive_nesting.rs",
|
||
"line": 60
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for blocks which are nested beyond a certain threshold.\n\nNote: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file.\n\n### Why is this bad?\nIt can severely hinder readability.\n\n### Example\nAn example clippy.toml configuration:\n```toml\n# clippy.toml\nexcessive-nesting-threshold = 3\n```\n```rust\n// lib.rs\npub mod a {\n pub struct X;\n impl X {\n pub fn run(&self) {\n if true {\n // etc...\n }\n }\n }\n}\n```\nUse instead:\n```rust\n// a.rs\nfn private_run(x: &X) {\n if true {\n // etc...\n }\n}\n\npub struct X;\nimpl X {\n pub fn run(&self) {\n private_run(self);\n }\n}\n```\n```rust\n// lib.rs\npub mod a;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `excessive-nesting-threshold`: The maximum amount of nesting a block can reside in (default: `0`)",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "excessive_precision",
|
||
"id_span": {
|
||
"path": "src/float_literal.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for float literals with a precision greater\nthan that supported by the underlying type.\n\n### Why is this bad?\nRust will truncate the literal silently.\n\n### Example\n```rust\nlet v: f32 = 0.123_456_789_9;\nprintln!(\"{}\", v); // 0.123_456_789\n```\n\nUse instead:\n```rust\nlet v: f64 = 0.123_456_789_9;\nprintln!(\"{}\", v); // 0.123_456_789_9\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "exhaustive_enums",
|
||
"id_span": {
|
||
"path": "src/exhaustive_items.rs",
|
||
"line": 34
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns on any exported `enum`s that are not tagged `#[non_exhaustive]`\n\n### Why is this bad?\nExhaustive enums are typically fine, but a project which does\nnot wish to make a stability commitment around exported enums may wish to\ndisable them by default.\n\n### Example\n```rust\nenum Foo {\n Bar,\n Baz\n}\n```\nUse instead:\n```rust\n#[non_exhaustive]\nenum Foo {\n Bar,\n Baz\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "exhaustive_structs",
|
||
"id_span": {
|
||
"path": "src/exhaustive_items.rs",
|
||
"line": 64
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns on any exported `struct`s that are not tagged `#[non_exhaustive]`\n\n### Why is this bad?\nExhaustive structs are typically fine, but a project which does\nnot wish to make a stability commitment around exported structs may wish to\ndisable them by default.\n\n### Example\n```rust\nstruct Foo {\n bar: u8,\n baz: String,\n}\n```\nUse instead:\n```rust\n#[non_exhaustive]\nstruct Foo {\n bar: u8,\n baz: String,\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "exit",
|
||
"id_span": {
|
||
"path": "src/exit.rs",
|
||
"line": 35
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects calls to the `exit()` function which terminates the program.\n\n### Why is this bad?\nExit terminates the program at the location it is called. For unrecoverable\nerrors `panics` should be used to provide a stacktrace and potentially other\ninformation. A normal termination or one with an error code should happen in\nthe main function.\n\n### Example\n```rust\nstd::process::exit(0)\n```\n\nUse instead:\n\n```rust\n// To provide a stacktrace and additional information\npanic!(\"message\");\n\n// or a main method with a return\nfn main() -> Result<(), i32> {\n Ok(())\n}\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "expect_fun_call",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1002
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,\netc., and suggests to use `unwrap_or_else` instead\n\n### Why is this bad?\nThe function will always be called.\n\n### Known problems\nIf the function has side-effects, not calling it will\nchange the semantics of the program, but you shouldn't rely on that anyway.\n\n### Example\n```rust\nfoo.expect(&format!(\"Err {}: {}\", err_code, err_msg));\n\n// or\n\nfoo.expect(format!(\"Err {}: {}\", err_code, err_msg).as_str());\n```\n\nUse instead:\n```rust\nfoo.unwrap_or_else(|| panic!(\"Err {}: {}\", err_code, err_msg));\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "expect_used",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 363
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.\n\n### Why is this bad?\nUsually it is better to handle the `None` or `Err` case.\nStill, for a lot of quick-and-dirty code, `expect` is a good choice, which is why\nthis lint is `Allow` by default.\n\n`result.expect()` will let the thread panic on `Err`\nvalues. Normally, you want to implement more sophisticated error handling,\nand propagate errors upwards with `?` operator.\n\n### Examples\n```rust\noption.expect(\"one\");\nresult.expect(\"one\");\n```\n\nUse instead:\n```rust\noption?;\n\n// or\n\nresult?;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-expect-in-tests`: Whether `expect` should be allowed in test functions or `#[cfg(test)]` (default: `false`)\n### Past names\n\n* `option_expect_used`\n* `result_expect_used`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"option_expect_used",
|
||
"result_expect_used"
|
||
]
|
||
},
|
||
{
|
||
"id": "expl_impl_clone_on_copy",
|
||
"id_span": {
|
||
"path": "src/derive.rs",
|
||
"line": 123
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for explicit `Clone` implementations for `Copy`\ntypes.\n\n### Why is this bad?\nTo avoid surprising behavior, these traits should\nagree and the behavior of `Copy` cannot be overridden. In almost all\nsituations a `Copy` type should have a `Clone` implementation that does\nnothing more than copy the object, which is what `#[derive(Copy, Clone)]`\ngets you.\n\n### Example\n```rust\n#[derive(Copy)]\nstruct Foo;\n\nimpl Clone for Foo {\n // ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_auto_deref",
|
||
"id_span": {
|
||
"path": "src/dereference.rs",
|
||
"line": 135
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for dereferencing expressions which would be covered by auto-deref.\n\n### Why is this bad?\nThis unnecessarily complicates the code.\n\n### Example\n```rust\nlet x = String::new();\nlet y: &str = &*x;\n```\nUse instead:\n```rust\nlet x = String::new();\nlet y: &str = &x;\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_counter_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 239
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks `for` loops over slices with an explicit counter\nand suggests the use of `.enumerate()`.\n\n### Why is this bad?\nUsing `.enumerate()` makes the intent more clear,\ndeclutters the code and may be faster in some instances.\n\n### Example\n```rust\nlet mut i = 0;\nfor item in &v {\n bar(i, *item);\n i += 1;\n}\n```\n\nUse instead:\n```rust\nfor (i, item) in v.iter().enumerate() { bar(i, *item); }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_deref_methods",
|
||
"id_span": {
|
||
"path": "src/dereference.rs",
|
||
"line": 50
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for explicit `deref()` or `deref_mut()` method calls.\n\n### Why is this bad?\nDereferencing by `&*x` or `&mut *x` is clearer and more concise,\nwhen not part of a method chain.\n\n### Example\n```rust\nuse std::ops::Deref;\nlet a: &mut String = &mut String::from(\"foo\");\nlet b: &str = a.deref();\n```\n\nUse instead:\n```rust\nlet a: &mut String = &mut String::from(\"foo\");\nlet b = &*a;\n```\n\nThis lint excludes all of:\n```rust\nlet _ = d.unwrap().deref();\nlet _ = Foo::deref(&foo);\nlet _ = <Foo as Deref>::deref(&foo);\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_into_iter_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 150
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for loops on `y.into_iter()` where `y` will do, and\nsuggests the latter.\n\n### Why is this bad?\nReadability.\n\n### Example\n```rust\n// with `y` a `Vec` or slice:\nfor x in y.into_iter() {\n // ..\n}\n```\ncan be rewritten to\n```rust\nfor x in y {\n // ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_iter_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 121
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for loops on `x.iter()` where `&x` will do, and\nsuggests the latter.\n\n### Why is this bad?\nReadability.\n\n### Known problems\nFalse negatives. We currently only warn on some known\ntypes.\n\n### Example\n```rust\n// with `y` a `Vec` or slice:\nfor x in y.iter() {\n // ..\n}\n```\n\nUse instead:\n```rust\nfor x in &y {\n // ..\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `enforce-iter-loop-reborrow`: Whether to recommend using implicit into iter for reborrowed values.\n\n #### Example\n```rust\n let mut vec = vec![1, 2, 3];\n let rmvec = &mut vec;\n for _ in rmvec.iter() {}\n for _ in rmvec.iter_mut() {}\n ```\n\n Use instead:\n```rust\n let mut vec = vec![1, 2, 3];\n let rmvec = &mut vec;\n for _ in &*rmvec {}\n for _ in &mut *rmvec {}\n ``` (default: `false`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "explicit_write",
|
||
"id_span": {
|
||
"path": "src/explicit_write.rs",
|
||
"line": 36
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `write!()` / `writeln()!` which can be\nreplaced with `(e)print!()` / `(e)println!()`\n\n### Why is this bad?\nUsing `(e)println!` is clearer and more concise\n\n### Example\n```rust\nwriteln!(&mut std::io::stderr(), \"foo: {:?}\", bar).unwrap();\nwriteln!(&mut std::io::stdout(), \"foo: {:?}\", bar).unwrap();\n```\n\nUse instead:\n```rust\neprintln!(\"foo: {:?}\", bar);\nprintln!(\"foo: {:?}\", bar);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "extend_from_slice",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 42
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis used to check for `Vec::extend`, which was slower than\n`Vec::extend_from_slice`. Thanks to specialization, this is no longer true.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "extend_with_drain",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1411
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for occurrences where one vector gets extended instead of append\n\n### Why is this bad?\nUsing `append` instead of `extend` is more concise and faster\n\n### Example\n```rust\nlet mut a = vec![1, 2, 3];\nlet mut b = vec![4, 5, 6];\n\na.extend(b.drain(..));\n```\n\nUse instead:\n```rust\nlet mut a = vec![1, 2, 3];\nlet mut b = vec![4, 5, 6];\n\na.append(&mut b);\n```",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "extra_unused_lifetimes",
|
||
"id_span": {
|
||
"path": "src/lifetimes.rs",
|
||
"line": 86
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for lifetimes in generics that are never used\nanywhere else.\n\n### Why is this bad?\nThe additional lifetimes make the code look more\ncomplicated, while there is nothing out of the ordinary going on. Removing\nthem leads to more readable code.\n\n### Example\n```rust\n// unnecessary lifetimes\nfn unused_lifetime<'a>(x: u8) {\n // ..\n}\n```\n\nUse instead:\n```rust\nfn no_lifetime(x: u8) {\n // ...\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "extra_unused_type_parameters",
|
||
"id_span": {
|
||
"path": "src/extra_unused_type_parameters.rs",
|
||
"line": 38
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for type parameters in generics that are never used anywhere else.\n\n### Why is this bad?\nFunctions cannot infer the value of unused type parameters; therefore, calling them\nrequires using a turbofish, which serves no purpose but to satisfy the compiler.\n\n### Example\n```rust\nfn unused_ty<T>(x: u8) {\n // ..\n}\n```\nUse instead:\n```rust\nfn no_unused_ty(x: u8) {\n // ..\n}\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "fallible_impl_from",
|
||
"id_span": {
|
||
"path": "src/fallible_impl_from.rs",
|
||
"line": 45
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for impls of `From<..>` that contain `panic!()` or `unwrap()`\n\n### Why is this bad?\n`TryFrom` should be used if there's a possibility of failure.\n\n### Example\n```rust\nstruct Foo(i32);\n\nimpl From<String> for Foo {\n fn from(s: String) -> Self {\n Foo(s.parse().unwrap())\n }\n}\n```\n\nUse instead:\n```rust\nstruct Foo(i32);\n\nimpl TryFrom<String> for Foo {\n type Error = ();\n fn try_from(s: String) -> Result<Self, Self::Error> {\n if let Ok(parsed) = s.parse() {\n Ok(Foo(parsed))\n } else {\n Err(())\n }\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "field_reassign_with_default",
|
||
"id_span": {
|
||
"path": "src/default.rs",
|
||
"line": 68
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for immediate reassignment of fields initialized\nwith Default::default().\n\n### Why is this bad?\nIt's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).\n\n### Known problems\nAssignments to patterns that are of tuple type are not linted.\n\n### Example\n```rust\nlet mut a: A = Default::default();\na.i = 42;\n```\n\nUse instead:\n```rust\nlet a = A {\n i: 42,\n .. Default::default()\n};\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "filetype_is_file",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1773
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `FileType::is_file()`.\n\n### Why is this bad?\nWhen people testing a file type with `FileType::is_file`\nthey are testing whether a path is something they can get bytes from. But\n`is_file` doesn't cover special file types in unix-like systems, and doesn't cover\nsymlink in windows. Using `!FileType::is_dir()` is a better way to that intention.\n\n### Example\n```rust\nlet metadata = std::fs::metadata(\"foo.txt\")?;\nlet filetype = metadata.file_type();\n\nif filetype.is_file() {\n // read file\n}\n```\n\nshould be written as:\n\n```rust\nlet metadata = std::fs::metadata(\"foo.txt\")?;\nlet filetype = metadata.file_type();\n\nif !filetype.is_dir() {\n // read file\n}\n```",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "filter_map",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 191
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint has been replaced by `manual_filter_map`, a\nmore specific lint.",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "filter_map_bool_then",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3575
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `bool::then` in `Iterator::filter_map`.\n\n### Why is this bad?\nThis can be written with `filter` then `map` instead, which would reduce nesting and\nseparates the filtering from the transformation phase. This comes with no cost to\nperformance and is just cleaner.\n\n### Limitations\nDoes not lint `bool::then_some`, as it eagerly evaluates its arguments rather than lazily.\nThis can create differing behavior, so better safe than sorry.\n\n### Example\n```rust\n_ = v.into_iter().filter_map(|i| (i % 2 == 0).then(|| really_expensive_fn(i)));\n```\nUse instead:\n```rust\n_ = v.into_iter().filter(|i| i % 2 == 0).map(|i| really_expensive_fn(i));\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "filter_map_identity",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1998
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `filter_map(|x| x)`.\n\n### Why is this bad?\nReadability, this can be written more concisely by using `flatten`.\n\n### Example\n```rust\niter.filter_map(|x| x);\n```\nUse instead:\n```rust\niter.flatten();\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "filter_map_next",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 811
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `_.filter_map(_).next()`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.find_map(_)`.\n\n### Example\n```rust\n (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next();\n```\nCan be written as\n\n```rust\n (0..3).find_map(|x| if x == 2 { Some(x) } else { None });\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.36.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "filter_next",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 679
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.filter(_).next()`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.find(_)`.\n\n### Example\n```rust\nvec.iter().filter(|x| **x == 0).next();\n```\n\nUse instead:\n```rust\nvec.iter().find(|x| **x == 0);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "find_map",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 179
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint has been replaced by `manual_find_map`, a\nmore specific lint.",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "flat_map_identity",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 834
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `flat_map(|x| x)`.\n\n### Why is this bad?\nReadability, this can be written more concisely by using `flatten`.\n\n### Example\n```rust\niter.flat_map(|x| x);\n```\nCan be written as\n```rust\niter.flatten();\n```",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "flat_map_option",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 250
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Iterator::flat_map()` where `filter_map()` could be\nused instead.\n\n### Why is this bad?\n`filter_map()` is known to always produce 0 or 1 output items per input item,\nrather than however many the inner iterator type produces.\nTherefore, it maintains the upper bound in `Iterator::size_hint()`,\nand communicates to the reader that the input items are not being expanded into\nmultiple output items without their having to notice that the mapping function\nreturns an `Option`.\n\n### Example\n```rust\nlet nums: Vec<i32> = [\"1\", \"2\", \"whee!\"].iter().flat_map(|x| x.parse().ok()).collect();\n```\nUse instead:\n```rust\nlet nums: Vec<i32> = [\"1\", \"2\", \"whee!\"].iter().filter_map(|x| x.parse().ok()).collect();\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "float_arithmetic",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 113
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for float arithmetic.\n\n### Why is this bad?\nFor some embedded systems or kernel development, it\ncan be useful to rule out floating-point numbers.\n\n### Example\n```rust\na + 1.0;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "float_cmp",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 588
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for (in-)equality comparisons on floating-point\nvalues (apart from zero), except in functions called `*eq*` (which probably\nimplement equality for a type involving floats).\n\n### Why is this bad?\nFloating point calculations are usually imprecise, so\nasking if two values are *exactly* equal is asking for trouble. For a good\nguide on what to do, see [the floating point\nguide](http://www.floating-point-gui.de/errors/comparison).\n\n### Example\n```rust\nlet x = 1.2331f64;\nlet y = 1.2332f64;\n\nif y == 1.23f64 { }\nif y != x {} // where both are floats\n```\n\nUse instead:\n```rust\nlet error_margin = f64::EPSILON; // Use an epsilon for comparison\n// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.\n// let error_margin = std::f64::EPSILON;\nif (y - 1.23f64).abs() < error_margin { }\nif (y - x).abs() > error_margin { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "float_cmp_const",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 623
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for (in-)equality comparisons on floating-point\nvalue and constant, except in functions called `*eq*` (which probably\nimplement equality for a type involving floats).\n\n### Why is this bad?\nFloating point calculations are usually imprecise, so\nasking if two values are *exactly* equal is asking for trouble. For a good\nguide on what to do, see [the floating point\nguide](http://www.floating-point-gui.de/errors/comparison).\n\n### Example\n```rust\nlet x: f64 = 1.0;\nconst ONE: f64 = 1.00;\n\nif x == ONE { } // where both are floats\n```\n\nUse instead:\n```rust\nlet error_margin = f64::EPSILON; // Use an epsilon for comparison\n// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.\n// let error_margin = std::f64::EPSILON;\nif (x - ONE).abs() < error_margin { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "float_equality_without_abs",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 477
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for statements of the form `(a - b) < f32::EPSILON` or\n`(a - b) < f64::EPSILON`. Notes the missing `.abs()`.\n\n### Why is this bad?\nThe code without `.abs()` is more likely to have a bug.\n\n### Known problems\nIf the user can ensure that b is larger than a, the `.abs()` is\ntechnically unnecessary. However, it will make the code more robust and doesn't have any\nlarge performance implications. If the abs call was deliberately left out for performance\nreasons, it is probably better to state this explicitly in the code, which then can be done\nwith an allow.\n\n### Example\n```rust\npub fn is_roughly_equal(a: f32, b: f32) -> bool {\n (a - b) < f32::EPSILON\n}\n```\nUse instead:\n```rust\npub fn is_roughly_equal(a: f32, b: f32) -> bool {\n (a - b).abs() < f32::EPSILON\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "fn_address_comparisons",
|
||
"id_span": {
|
||
"path": "src/unnamed_address.rs",
|
||
"line": 26
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for comparisons with an address of a function item.\n\n### Why is this bad?\nFunction item address is not guaranteed to be unique and could vary\nbetween different code generation units. Furthermore different function items could have\nthe same address after being merged together.\n\n### Example\n```rust\ntype F = fn();\nfn a() {}\nlet f: F = a;\nif f == a {\n // ...\n}\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "fn_params_excessive_bools",
|
||
"id_span": {
|
||
"path": "src/excessive_bools.rs",
|
||
"line": 80
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for excessive use of\nbools in function definitions.\n\n### Why is this bad?\nCalls to such functions\nare confusing and error prone, because it's\nhard to remember argument order and you have\nno type system support to back you up. Using\ntwo-variant enums instead of bools often makes\nAPI easier to use.\n\n### Example\n```rust\nfn f(is_round: bool, is_hot: bool) { ... }\n```\n\nUse instead:\n```rust\nenum Shape {\n Round,\n Spiky,\n}\n\nenum Temperature {\n Hot,\n IceCold,\n}\n\nfn f(shape: Shape, temperature: Temperature) { ... }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `max-fn-params-bools`: The maximum number of bool parameters a function can have (default: `3`)",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "fn_to_numeric_cast",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 264
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for casts of function pointers to something other than usize\n\n### Why is this bad?\nCasting a function pointer to anything other than usize/isize is not portable across\narchitectures, because you end up losing bits if the target type is too small or end up with a\nbunch of extra bits that waste space and add more instructions to the final binary than\nstrictly necessary for the problem\n\nCasting to isize also doesn't make sense since there are no signed addresses.\n\n### Example\n```rust\nfn fun() -> i32 { 1 }\nlet _ = fun as i64;\n```\n\nUse instead:\n```rust\nlet _ = fun as usize;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "fn_to_numeric_cast_any",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 339
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts of a function pointer to any integer type.\n\n### Why is this bad?\nCasting a function pointer to an integer can have surprising results and can occur\naccidentally if parentheses are omitted from a function call. If you aren't doing anything\nlow-level with function pointers then you can opt-out of casting functions to integers in\norder to avoid mistakes. Alternatively, you can use this lint to audit all uses of function\npointer casts in your code.\n\n### Example\n```rust\n// fn1 is cast as `usize`\nfn fn1() -> u16 {\n 1\n};\nlet _ = fn1 as usize;\n```\n\nUse instead:\n```rust\n// maybe you intended to call the function?\nfn fn2() -> u16 {\n 1\n};\nlet _ = fn2() as usize;\n\n// or\n\n// maybe you intended to cast it to a function type?\nfn fn3() -> u16 {\n 1\n}\nlet _ = fn3 as fn() -> u16;\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "fn_to_numeric_cast_with_truncation",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 297
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for casts of a function pointer to a numeric type not wide enough to\nstore address.\n\n### Why is this bad?\nSuch a cast discards some bits of the function's address. If this is intended, it would be more\nclearly expressed by casting to usize first, then casting the usize to the intended type (with\na comment) to perform the truncation.\n\n### Example\n```rust\nfn fn1() -> i16 {\n 1\n};\nlet _ = fn1 as i32;\n```\n\nUse instead:\n```rust\n// Cast to usize first, then comment with the reason for the truncation\nfn fn1() -> i16 {\n 1\n};\nlet fn_ptr = fn1 as usize;\nlet fn_ptr_truncated = fn_ptr as i32;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "for_kv_map",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 329
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values.\n\n### Why is this bad?\nReadability. There are `keys` and `values` methods that\ncan be used to express that don't need the values or keys.\n\n### Example\n```rust\nfor (k, _) in &map {\n ..\n}\n```\n\ncould be replaced by\n\n```rust\nfor k in map.keys() {\n ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "forget_non_drop",
|
||
"id_span": {
|
||
"path": "src/drop_forget_ref.rs",
|
||
"line": 45
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `std::mem::forget` with a value that does not implement `Drop`.\n\n### Why is this bad?\nCalling `std::mem::forget` is no different than dropping such a type. A different value may\nhave been intended.\n\n### Example\n```rust\nstruct Foo;\nlet x = Foo;\nstd::mem::forget(x);\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "format_collect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3523
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.map(|_| format!(..)).collect::<String>()`.\n\n### Why is this bad?\nThis allocates a new string for every element in the iterator.\nThis can be done more efficiently by creating the `String` once and appending to it in `Iterator::fold`,\nusing either the `write!` macro which supports exactly the same syntax as the `format!` macro,\nor concatenating with `+` in case the iterator yields `&str`/`String`.\n\nNote also that `write!`-ing into a `String` can never fail, despite the return type of `write!` being `std::fmt::Result`,\nso it can be safely ignored or unwrapped.\n\n### Example\n```rust\nfn hex_encode(bytes: &[u8]) -> String {\n bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n}\n```\nUse instead:\n```rust\nuse std::fmt::Write;\nfn hex_encode(bytes: &[u8]) -> String {\n bytes.iter().fold(String::new(), |mut output, b| {\n let _ = write!(output, \"{b:02X}\");\n output\n })\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "format_in_format_args",
|
||
"id_span": {
|
||
"path": "src/format_args.rs",
|
||
"line": 46
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects `format!` within the arguments of another macro that does\nformatting such as `format!` itself, `write!` or `println!`. Suggests\ninlining the `format!` call.\n\n### Why is this bad?\nThe recommended code is both shorter and avoids a temporary allocation.\n\n### Example\n```rust\nprintln!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n```\nUse instead:\n```rust\nprintln!(\"error: something failed at {}\", Location::caller());\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "format_push_string",
|
||
"id_span": {
|
||
"path": "src/format_push_string.rs",
|
||
"line": 37
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects cases where the result of a `format!` call is\nappended to an existing `String`.\n\n### Why is this bad?\nIntroduces an extra, avoidable heap allocation.\n\n### Known problems\n`format!` returns a `String` but `write!` returns a `Result`.\nThus you are forced to ignore the `Err` variant to achieve the same API.\n\nWhile using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.\n\n### Example\n```rust\nlet mut s = String::new();\ns += &format!(\"0x{:X}\", 1024);\ns.push_str(&format!(\"0x{:X}\", 1024));\n```\nUse instead:\n```rust\nuse std::fmt::Write as _; // import without risk of name clashing\n\nlet mut s = String::new();\nlet _ = write!(s, \"0x{:X}\", 1024);\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "four_forward_slashes",
|
||
"id_span": {
|
||
"path": "src/four_forward_slashes.rs",
|
||
"line": 32
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for outer doc comments written with 4 forward slashes (`////`).\n\n### Why is this bad?\nThis is (probably) a typo, and results in it not being a doc comment; just a regular\ncomment.\n\n### Example\n```rust\n//// My amazing data structure\npub struct Foo {\n // ...\n}\n```\n\nUse instead:\n```rust\n/// My amazing data structure\npub struct Foo {\n // ...\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "from_iter_instead_of_collect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1945
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `from_iter()` function calls on types that implement the `FromIterator`\ntrait.\n\n### Why is this bad?\nIt is recommended style to use collect. See\n[FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html)\n\n### Example\n```rust\nlet five_fives = std::iter::repeat(5).take(5);\n\nlet v = Vec::from_iter(five_fives);\n\nassert_eq!(v, vec![5, 5, 5, 5, 5]);\n```\nUse instead:\n```rust\nlet five_fives = std::iter::repeat(5).take(5);\n\nlet v: Vec<i32> = five_fives.collect();\n\nassert_eq!(v, vec![5, 5, 5, 5, 5]);\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "from_over_into",
|
||
"id_span": {
|
||
"path": "src/from_over_into.rs",
|
||
"line": 47
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSearches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.\n\n### Why is this bad?\nAccording the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.\n\n### Example\n```rust\nstruct StringWrapper(String);\n\nimpl Into<StringWrapper> for String {\n fn into(self) -> StringWrapper {\n StringWrapper(self)\n }\n}\n```\nUse instead:\n```rust\nstruct StringWrapper(String);\n\nimpl From<String> for StringWrapper {\n fn from(s: String) -> StringWrapper {\n StringWrapper(s)\n }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "from_raw_with_void_ptr",
|
||
"id_span": {
|
||
"path": "src/from_raw_with_void_ptr.rs",
|
||
"line": 34
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`\n\n### Why is this bad?\nWhen dealing with `c_void` raw pointers in FFI, it is easy to run into the pitfall of calling `from_raw` with the `c_void` pointer.\nThe type signature of `Box::from_raw` is `fn from_raw(raw: *mut T) -> Box<T>`, so if you pass a `*mut c_void` you will get a `Box<c_void>` (and similarly for `Rc`, `Arc` and `Weak`).\nFor this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.\n\n### Example\n```rust\nlet ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;\nlet _ = unsafe { Box::from_raw(ptr) };\n```\nUse instead:\n```rust\nlet _ = unsafe { Box::from_raw(ptr as *mut usize) };\n```\n",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "from_str_radix_10",
|
||
"id_span": {
|
||
"path": "src/from_str_radix_10.rs",
|
||
"line": 39
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for function invocations of the form `primitive::from_str_radix(s, 10)`\n\n### Why is this bad?\n\nThis specific common use case can be rewritten as `s.parse::<primitive>()`\n(and in most cases, the turbofish can be removed), which reduces code length\nand complexity.\n\n### Known problems\n\nThis lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly\nin some cases, which is correct but adds unnecessary complexity to the code.\n\n### Example\n```rust\nlet input: &str = get_input();\nlet num = u16::from_str_radix(input, 10)?;\n```\nUse instead:\n```rust\nlet input: &str = get_input();\nlet num: u16 = input.parse()?;\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "future_not_send",
|
||
"id_span": {
|
||
"path": "src/future_not_send.rs",
|
||
"line": 45
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint requires Future implementations returned from\nfunctions and methods to implement the `Send` marker trait. It is mostly\nused by library authors (public and internal) that target an audience where\nmultithreaded executors are likely to be used for running these Futures.\n\n### Why is this bad?\nA Future implementation captures some state that it\nneeds to eventually produce its final value. When targeting a multithreaded\nexecutor (which is the norm on non-embedded devices) this means that this\nstate may need to be transported to other threads, in other words the\nwhole Future needs to implement the `Send` marker trait. If it does not,\nthen the resulting Future cannot be submitted to a thread pool in the\nend user’s code.\n\nEspecially for generic functions it can be confusing to leave the\ndiscovery of this problem to the end user: the reported error location\nwill be far from its cause and can in many cases not even be fixed without\nmodifying the library where the offending Future implementation is\nproduced.\n\n### Example\n```rust\nasync fn not_send(bytes: std::rc::Rc<[u8]>) {}\n```\nUse instead:\n```rust\nasync fn is_send(bytes: std::sync::Arc<[u8]>) {}\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "get_first",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2621
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `x.get(0)` instead of\n`x.first()` or `x.front()`.\n\n### Why is this bad?\nUsing `x.first()` for `Vec`s and slices or `x.front()`\nfor `VecDeque`s is easier to read and has the same result.\n\n### Example\n```rust\nlet x = vec![2, 3, 5];\nlet first_element = x.get(0);\n```\n\nUse instead:\n```rust\nlet x = vec![2, 3, 5];\nlet first_element = x.first();\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "get_last_with_len",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1346
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `x.get(x.len() - 1)` instead of\n`x.last()`.\n\n### Why is this bad?\nUsing `x.last()` is easier to read and has the same\nresult.\n\nNote that using `x[x.len() - 1]` is semantically different from\n`x.last()`. Indexing into the array will panic on out-of-bounds\naccesses, while `x.get()` and `x.last()` will return `None`.\n\nThere is another lint (get_unwrap) that covers the case of using\n`x.get(index).unwrap()` instead of `x[index]`.\n\n### Example\n```rust\nlet x = vec![2, 3, 5];\nlet last_element = x.get(x.len() - 1);\n```\n\nUse instead:\n```rust\nlet x = vec![2, 3, 5];\nlet last_element = x.last();\n```",
|
||
"version": "1.37.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "get_unwrap",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1383
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.get().unwrap()` (or\n`.get_mut().unwrap`) on a standard library type which implements `Index`\n\n### Why is this bad?\nUsing the Index trait (`[]`) is more clear and more\nconcise.\n\n### Known problems\nNot a replacement for error handling: Using either\n`.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`\nif the value being accessed is `None`. If the use of `.get().unwrap()` is a\ntemporary placeholder for dealing with the `Option` type, then this does\nnot mitigate the need for error handling. If there is a chance that `.get()`\nwill be `None` in your program, then it is advisable that the `None` case\nis handled in a future refactor instead of using `.unwrap()` or the Index\ntrait.\n\n### Example\n```rust\nlet mut some_vec = vec![0, 1, 2, 3];\nlet last = some_vec.get(3).unwrap();\n*some_vec.get_mut(0).unwrap() = 1;\n```\nThe correct use would be:\n```rust\nlet mut some_vec = vec![0, 1, 2, 3];\nlet last = some_vec[3];\nsome_vec[0] = 1;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "host_endian_bytes",
|
||
"id_span": {
|
||
"path": "src/endian_bytes.rs",
|
||
"line": 25
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`.\n\n### Why is this bad?\nIt's not, but some may prefer to specify the target endianness explicitly.\n\n### Example\n```rust\nlet _x = 2i32.to_ne_bytes();\nlet _y = 2i64.to_ne_bytes();\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "identity_op",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 496
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for identity operations, e.g., `x + 0`.\n\n### Why is this bad?\nThis code can be removed without changing the\nmeaning. So it just obscures what's going on. Delete it mercilessly.\n\n### Example\n```rust\nx / 1 + 0 * 1 - 0 | 0;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "if_let_mutex",
|
||
"id_span": {
|
||
"path": "src/if_let_mutex.rs",
|
||
"line": 38
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `Mutex::lock` calls in `if let` expression\nwith lock calls in any of the else blocks.\n\n### Why is this bad?\nThe Mutex lock remains held for the whole\n`if let ... else` block and deadlocks.\n\n### Example\n```rust\nif let Ok(thing) = mutex.lock() {\n do_thing();\n} else {\n mutex.lock();\n}\n```\nShould be written\n```rust\nlet locked = mutex.lock();\nif let Ok(thing) = locked {\n do_thing(thing);\n} else {\n use_locked(locked);\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "if_let_redundant_pattern_matching",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 120
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThe original rule will only lint for `if let`. After\nmaking it support to lint `match`, naming as `if let` is not suitable for it.\nSo, this lint is deprecated.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "if_not_else",
|
||
"id_span": {
|
||
"path": "src/if_not_else.rs",
|
||
"line": 44
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `!` or `!=` in an if condition with an\nelse branch.\n\n### Why is this bad?\nNegations reduce the readability of statements.\n\n### Example\n```rust\nif !v.is_empty() {\n a()\n} else {\n b()\n}\n```\n\nCould be written:\n\n```rust\nif v.is_empty() {\n b()\n} else {\n a()\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "if_same_then_else",
|
||
"id_span": {
|
||
"path": "src/copies.rs",
|
||
"line": 118
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `if/else` with the same body as the *then* part\nand the *else* part.\n\n### Why is this bad?\nThis is probably a copy & paste error.\n\n### Example\n```rust\nlet foo = if … {\n 42\n} else {\n 42\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "if_then_some_else_none",
|
||
"id_span": {
|
||
"path": "src/if_then_some_else_none.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for if-else that could be written using either `bool::then` or `bool::then_some`.\n\n### Why is this bad?\nLooks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity.\nFor simple calculations and known values, use `bool::then_some`, which is eagerly evaluated\nin comparison to `bool::then`.\n\n### Example\n```rust\nlet a = if v.is_empty() {\n println!(\"true!\");\n Some(42)\n} else {\n None\n};\n```\n\nCould be written:\n\n```rust\nlet a = v.is_empty().then(|| {\n println!(\"true!\");\n 42\n});\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ifs_same_cond",
|
||
"id_span": {
|
||
"path": "src/copies.rs",
|
||
"line": 48
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for consecutive `if`s with the same condition.\n\n### Why is this bad?\nThis is probably a copy & paste error.\n\n### Example\n```rust\nif a == b {\n …\n} else if a == b {\n …\n}\n```\n\nNote that this lint ignores all conditions with a function call as it could\nhave side effects:\n\n```rust\nif foo() {\n …\n} else if foo() { // not linted\n …\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `ignore-interior-mutability`: A list of paths to types that should be treated like `Arc`, i.e. ignored but\n for the generic parameters for determining interior mutability (default: `[\"bytes::Bytes\"]`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ignored_unit_patterns",
|
||
"id_span": {
|
||
"path": "src/ignored_unit_patterns.rs",
|
||
"line": 32
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `_` in patterns of type `()`.\n\n### Why is this bad?\nMatching with `()` explicitly instead of `_` outlines\nthe fact that the pattern contains no data. Also it\nwould detect a type change that `_` would ignore.\n\n### Example\n```rust\nmatch std::fs::create_dir(\"tmp-work-dir\") {\n Ok(_) => println!(\"Working directory created\"),\n Err(s) => eprintln!(\"Could not create directory: {s}\"),\n}\n```\nUse instead:\n```rust\nmatch std::fs::create_dir(\"tmp-work-dir\") {\n Ok(()) => println!(\"Working directory created\"),\n Err(s) => eprintln!(\"Could not create directory: {s}\"),\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "impl_hash_borrow_with_str_and_bytes",
|
||
"id_span": {
|
||
"path": "src/impl_hash_with_borrow_str_and_bytes.rs",
|
||
"line": 67
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\n\nThis lint is concerned with the semantics of `Borrow` and `Hash` for a\ntype that implements all three of `Hash`, `Borrow<str>` and `Borrow<[u8]>`\nas it is impossible to satisfy the semantics of Borrow and `Hash` for\nboth `Borrow<str>` and `Borrow<[u8]>`.\n\n### Why is this bad?\n\nWhen providing implementations for `Borrow<T>`, one should consider whether the different\nimplementations should act as facets or representations of the underlying type. Generic code\ntypically uses `Borrow<T>` when it relies on the identical behavior of these additional trait\nimplementations. These traits will likely appear as additional trait bounds.\n\nIn particular `Eq`, `Ord` and `Hash` must be equivalent for borrowed and owned values:\n`x.borrow() == y.borrow()` should give the same result as `x == y`.\nIt follows then that the following equivalence must hold:\n`hash(x) == hash((x as Borrow<[u8]>).borrow()) == hash((x as Borrow<str>).borrow())`\n\nUnfortunately it doesn't hold as `hash(\"abc\") != hash(\"abc\".as_bytes())`.\nThis happens because the `Hash` impl for str passes an additional `0xFF` byte to\nthe hasher to avoid collisions. For example, given the tuples `(\"a\", \"bc\")`, and `(\"ab\", \"c\")`,\nthe two tuples would have the same hash value if the `0xFF` byte was not added.\n\n### Example\n\n```rust\nuse std::borrow::Borrow;\nuse std::hash::{Hash, Hasher};\n\nstruct ExampleType {\n data: String\n}\n\nimpl Hash for ExampleType {\n fn hash<H: Hasher>(&self, state: &mut H) {\n self.data.hash(state);\n }\n}\n\nimpl Borrow<str> for ExampleType {\n fn borrow(&self) -> &str {\n &self.data\n }\n}\n\nimpl Borrow<[u8]> for ExampleType {\n fn borrow(&self) -> &[u8] {\n self.data.as_bytes()\n }\n}\n```\nAs a consequence, hashing a `&ExampleType` and hashing the result of the two\nborrows will result in different values.\n",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "impl_trait_in_params",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 357
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLints when `impl Trait` is being used in a function's parameters.\n### Why is this bad?\nTurbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor.\n\n### Example\n```rust\ntrait MyTrait {}\nfn foo(a: impl MyTrait) {\n\t// [...]\n}\n```\nUse instead:\n```rust\ntrait MyTrait {}\nfn foo<T: MyTrait>(a: T) {\n\t// [...]\n}\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "implicit_clone",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2072
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer.\n\n### Why is this bad?\nThese methods do the same thing as `_.clone()` but may be confusing as\nto why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned.\n\n### Example\n```rust\nlet a = vec![1, 2, 3];\nlet b = a.to_vec();\nlet c = a.to_owned();\n```\nUse instead:\n```rust\nlet a = vec![1, 2, 3];\nlet b = a.clone();\nlet c = a.clone();\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "implicit_hasher",
|
||
"id_span": {
|
||
"path": "src/implicit_hasher.rs",
|
||
"line": 54
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for public `impl` or `fn` missing generalization\nover different hashers and implicitly defaulting to the default hashing\nalgorithm (`SipHash`).\n\n### Why is this bad?\n`HashMap` or `HashSet` with custom hashers cannot be\nused with them.\n\n### Known problems\nSuggestions for replacing constructors can contain\nfalse-positives. Also applying suggestions can require modification of other\npieces of code, possibly including external crates.\n\n### Example\n```rust\nimpl<K: Hash + Eq, V> Serialize for HashMap<K, V> { }\n\npub fn foo(map: &mut HashMap<i32, i32>) { }\n```\ncould be rewritten as\n```rust\nimpl<K: Hash + Eq, V, S: BuildHasher> Serialize for HashMap<K, V, S> { }\n\npub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "implicit_return",
|
||
"id_span": {
|
||
"path": "src/implicit_return.rs",
|
||
"line": 39
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for missing return statements at the end of a block.\n\n### Why is this bad?\nActually omitting the return keyword is idiomatic Rust code. Programmers\ncoming from other languages might prefer the expressiveness of `return`. It's possible to miss\nthe last returning statement because the only difference is a missing `;`. Especially in bigger\ncode with multiple return paths having a `return` keyword makes it easier to find the\ncorresponding statements.\n\n### Example\n```rust\nfn foo(x: usize) -> usize {\n x\n}\n```\nadd return\n```rust\nfn foo(x: usize) -> usize {\n return x;\n}\n```",
|
||
"version": "1.33.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "implicit_saturating_add",
|
||
"id_span": {
|
||
"path": "src/implicit_saturating_add.rs",
|
||
"line": 35
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for implicit saturating addition.\n\n### Why is this bad?\nThe built-in function is more readable and may be faster.\n\n### Example\n```rust\nlet mut u:u32 = 7000;\n\nif u != u32::MAX {\n u += 1;\n}\n```\nUse instead:\n```rust\nlet mut u:u32 = 7000;\n\nu = u.saturating_add(1);\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "implicit_saturating_sub",
|
||
"id_span": {
|
||
"path": "src/implicit_saturating_sub.rs",
|
||
"line": 37
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for implicit saturating subtraction.\n\n### Why is this bad?\nSimplicity and readability. Instead we can easily use an builtin function.\n\n### Example\n```rust\nlet mut i: u32 = end - start;\n\nif i != 0 {\n i -= 1;\n}\n```\n\nUse instead:\n```rust\nlet mut i: u32 = end - start;\n\ni = i.saturating_sub(1);\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "implied_bounds_in_impls",
|
||
"id_span": {
|
||
"path": "src/implied_bounds_in_impls.rs",
|
||
"line": 46
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for bounds in `impl Trait` in return position that are implied by other bounds.\nThis can happen when a trait is specified that another trait already has as a supertrait\n(e.g. `fn() -> impl Deref + DerefMut<Target = i32>` has an unnecessary `Deref` bound,\nbecause `Deref` is a supertrait of `DerefMut`)\n\n### Why is this bad?\nSpecifying more bounds than necessary adds needless complexity for the reader.\n\n### Limitations\nThis lint does not check for implied bounds transitively. Meaning that\nit does't check for implied bounds from supertraits of supertraits\n(e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)\n\n### Example\n```rust\nfn f() -> impl Deref<Target = i32> + DerefMut<Target = i32> {\n// ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound\n Box::new(123)\n}\n```\nUse instead:\n```rust\nfn f() -> impl DerefMut<Target = i32> {\n Box::new(123)\n}\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "impossible_comparisons",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 316
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for double comparisons that can never succeed\n\n### Why is this bad?\nThe whole expression can be replaced by `false`,\nwhich is probably not the programmer's intention\n\n### Example\n```rust\nif status_code <= 400 && status_code > 500 {}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "imprecise_flops",
|
||
"id_span": {
|
||
"path": "src/floating_point_arithmetic.rs",
|
||
"line": 44
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLooks for floating-point expressions that\ncan be expressed using built-in methods to improve accuracy\nat the cost of performance.\n\n### Why is this bad?\nNegatively impacts accuracy.\n\n### Example\n```rust\nlet a = 3f32;\nlet _ = a.powf(1.0 / 3.0);\nlet _ = (1.0 + a).ln();\nlet _ = a.exp() - 1.0;\n```\n\nUse instead:\n```rust\nlet a = 3f32;\nlet _ = a.cbrt();\nlet _ = a.ln_1p();\nlet _ = a.exp_m1();\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "incompatible_msrv",
|
||
"id_span": {
|
||
"path": "src/incompatible_msrv.rs",
|
||
"line": 37
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nThis lint checks that no function newer than the defined MSRV (minimum\nsupported rust version) is used in the crate.\n\n### Why is this bad?\n\nIt would prevent the crate to be actually used with the specified MSRV.\n\n### Example\n```rust\n// MSRV of 1.3.0\nuse std::thread::sleep;\nuse std::time::Duration;\n\n// Sleep was defined in `1.4.0`.\nsleep(Duration::new(1, 0));\n```\n\nTo fix this problem, either increase your MSRV or use another item\navailable in your current MSRV.",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "inconsistent_digit_grouping",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 88
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns if an integral or floating-point constant is\ngrouped inconsistently with underscores.\n\n### Why is this bad?\nReaders may incorrectly interpret inconsistently\ngrouped digits.\n\n### Example\n```rust\n618_64_9189_73_511\n```\n\nUse instead:\n```rust\n61_864_918_973_511\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "inconsistent_struct_constructor",
|
||
"id_span": {
|
||
"path": "src/inconsistent_struct_constructor.rs",
|
||
"line": 59
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for struct constructors where all fields are shorthand and\nthe order of the field init shorthand in the constructor is inconsistent\nwith the order in the struct definition.\n\n### Why is this bad?\nSince the order of fields in a constructor doesn't affect the\nresulted instance as the below example indicates,\n\n```rust\n#[derive(Debug, PartialEq, Eq)]\nstruct Foo {\n x: i32,\n y: i32,\n}\nlet x = 1;\nlet y = 2;\n\n// This assertion never fails:\nassert_eq!(Foo { x, y }, Foo { y, x });\n```\n\ninconsistent order can be confusing and decreases readability and consistency.\n\n### Example\n```rust\nstruct Foo {\n x: i32,\n y: i32,\n}\nlet x = 1;\nlet y = 2;\n\nFoo { y, x };\n```\n\nUse instead:\n```rust\nFoo { x, y };\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "index_refutable_slice",
|
||
"id_span": {
|
||
"path": "src/index_refutable_slice.rs",
|
||
"line": 50
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThe lint checks for slice bindings in patterns that are only used to\naccess individual slice values.\n\n### Why is this bad?\nAccessing slice values using indices can lead to panics. Using refutable\npatterns can avoid these. Binding to individual values also improves the\nreadability as they can be named.\n\n### Limitations\nThis lint currently only checks for immutable access inside `if let`\npatterns.\n\n### Example\n```rust\nlet slice: Option<&[u32]> = Some(&[1, 2, 3]);\n\nif let Some(slice) = slice {\n println!(\"{}\", slice[0]);\n}\n```\nUse instead:\n```rust\nlet slice: Option<&[u32]> = Some(&[1, 2, 3]);\n\nif let Some(&[first, ..]) = slice {\n println!(\"{}\", first);\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `max-suggested-slice-pattern-length`: When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in\n the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.\n For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. (default: `3`)- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "indexing_slicing",
|
||
"id_span": {
|
||
"path": "src/indexing_slicing.rs",
|
||
"line": 80
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of indexing or slicing. Arrays are special cases, this lint\ndoes report on arrays if we can tell that slicing operations are in bounds and does not\nlint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.\n\n### Why is this bad?\nIndexing and slicing can panic at runtime and there are\nsafe alternatives.\n\n### Example\n```rust\n// Vector\nlet x = vec![0; 5];\n\nx[2];\n&x[2..100];\n\n// Array\nlet y = [0, 1, 2, 3];\n\n&y[10..100];\n&y[10..];\n```\n\nUse instead:\n```rust\n\nx.get(2);\nx.get(2..100);\n\ny.get(10);\ny.get(10..100);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `suppress-restriction-lint-in-const`: Whether to suppress a restriction lint in constant code. In same\n cases the restructured operation might not be unavoidable, as the\n suggested counterparts are unavailable in constant code. This\n configuration will cause restriction lints to trigger even\n if no suggestion can be made. (default: `false`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ineffective_bit_mask",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 246
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for bit masks in comparisons which can be removed\nwithout changing the outcome. The basic structure can be seen in the\nfollowing table:\n\n|Comparison| Bit Op |Example |equals |\n|----------|----------|------------|-------|\n|`>` / `<=`|`\\|` / `^`|`x \\| 2 > 3`|`x > 3`|\n|`<` / `>=`|`\\|` / `^`|`x ^ 1 < 4` |`x < 4`|\n\n### Why is this bad?\nNot equally evil as [`bad_bit_mask`](#bad_bit_mask),\nbut still a bit misleading, because the bit mask is ineffective.\n\n### Known problems\nFalse negatives: This lint will only match instances\nwhere we have figured out the math (which is for a power-of-two compared\nvalue). This means things like `x | 1 >= 7` (which would be better written\nas `x >= 6`) will not be reported (but bit masks like this are fairly\nuncommon).\n\n### Example\n```rust\nif (x | 1 > 3) { }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ineffective_open_options",
|
||
"id_span": {
|
||
"path": "src/ineffective_open_options.rs",
|
||
"line": 39
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if both `.write(true)` and `.append(true)` methods are called\non a same `OpenOptions`.\n\n### Why is this bad?\n`.append(true)` already enables `write(true)`, making this one\nsuperfluous.\n\n### Example\n```rust\nlet _ = OpenOptions::new()\n .write(true)\n .append(true)\n .create(true)\n .open(\"file.json\");\n```\nUse instead:\n```rust\nlet _ = OpenOptions::new()\n .append(true)\n .create(true)\n .open(\"file.json\");\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "inefficient_to_string",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1075
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.to_string()` on an `&&T` where\n`T` implements `ToString` directly (like `&&str` or `&&String`).\n\n### Why is this bad?\nThis bypasses the specialized implementation of\n`ToString` and instead goes through the more expensive string formatting\nfacilities.\n\n### Example\n```rust\n// Generic implementation for `T: Display` is used (slow)\n[\"foo\", \"bar\"].iter().map(|s| s.to_string());\n\n// OK, the specialized impl is used\n[\"foo\", \"bar\"].iter().map(|&s| s.to_string());\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "infallible_destructuring_match",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 395
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for matches being used to destructure a single-variant enum\nor tuple struct where a `let` will suffice.\n\n### Why is this bad?\nJust readability – `let` doesn't nest, whereas a `match` does.\n\n### Example\n```rust\nenum Wrapper {\n Data(i32),\n}\n\nlet wrapper = Wrapper::Data(42);\n\nlet data = match wrapper {\n Wrapper::Data(i) => i,\n};\n```\n\nThe correct use would be:\n```rust\nenum Wrapper {\n Data(i32),\n}\n\nlet wrapper = Wrapper::Data(42);\nlet Wrapper::Data(data) = wrapper;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "infinite_iter",
|
||
"id_span": {
|
||
"path": "src/infinite_iter.rs",
|
||
"line": 24
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for iteration that is guaranteed to be infinite.\n\n### Why is this bad?\nWhile there may be places where this is acceptable\n(e.g., in event streams), in most cases this is simply an error.\n\n### Example\n```rust\nuse std::iter;\n\niter::repeat(1_u8).collect::<Vec<_>>();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "infinite_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 676
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for infinite loops in a function where the return type is not `!`\nand lint accordingly.\n\n### Why is this bad?\nA loop should be gently exited somewhere, or at least mark its parent function as\nnever return (`!`).\n\n### Example\n```rust\nfn run_forever() {\n loop {\n // do something\n }\n}\n```\nIf infinite loops are as intended:\n```rust\nfn run_forever() -> ! {\n loop {\n // do something\n }\n}\n```\nOtherwise add a `break` or `return` condition:\n```rust\nfn run_forever() {\n loop {\n // do something\n if condition {\n break;\n }\n }\n}\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "inherent_to_string",
|
||
"id_span": {
|
||
"path": "src/inherent_to_string.rs",
|
||
"line": 41
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the definition of inherent methods with a signature of `to_string(&self) -> String`.\n\n### Why is this bad?\nThis 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.\n\n### Example\n```rust\npub struct A;\n\nimpl A {\n pub fn to_string(&self) -> String {\n \"I am A\".to_string()\n }\n}\n```\n\nUse instead:\n```rust\nuse std::fmt;\n\npub struct A;\n\nimpl fmt::Display for A {\n fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n write!(f, \"I am A\")\n }\n}\n```",
|
||
"version": "1.38.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "inherent_to_string_shadow_display",
|
||
"id_span": {
|
||
"path": "src/inherent_to_string.rs",
|
||
"line": 85
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks 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.\n\n### Why is this bad?\nThis 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`.\n\n### Example\n```rust\nuse std::fmt;\n\npub struct A;\n\nimpl A {\n pub fn to_string(&self) -> String {\n \"I am A\".to_string()\n }\n}\n\nimpl fmt::Display for A {\n fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n write!(f, \"I am A, too\")\n }\n}\n```\n\nUse instead:\n```rust\nuse std::fmt;\n\npub struct A;\n\nimpl fmt::Display for A {\n fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n write!(f, \"I am A\")\n }\n}\n```",
|
||
"version": "1.38.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "init_numbered_fields",
|
||
"id_span": {
|
||
"path": "src/init_numbered_fields.rs",
|
||
"line": 38
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for tuple structs initialized with field syntax.\nIt will however not lint if a base initializer is present.\nThe lint will also ignore code in macros.\n\n### Why is this bad?\nThis may be confusing to the uninitiated and adds no\nbenefit as opposed to tuple initializers\n\n### Example\n```rust\nstruct TupleStruct(u8, u16);\n\nlet _ = TupleStruct {\n 0: 1,\n 1: 23,\n};\n\n// should be written as\nlet base = TupleStruct(1, 23);\n\n// This is OK however\nlet _ = TupleStruct { 0: 42, ..base };\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "inline_always",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 52
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for items annotated with `#[inline(always)]`,\nunless the annotated function is empty or simply panics.\n\n### Why is this bad?\nWhile there are valid uses of this annotation (and once\nyou know when to use it, by all means `allow` this lint), it's a common\nnewbie-mistake to pepper one's code with it.\n\nAs a rule of thumb, before slapping `#[inline(always)]` on a function,\nmeasure if that additional function call really affects your runtime profile\nsufficiently to make up for the increase in compile time.\n\n### Known problems\nFalse positives, big time. This lint is meant to be\ndeactivated by everyone doing serious performance work. This means having\ndone the measurement.\n\n### Example\n```rust\n#[inline(always)]\nfn not_quite_hot_code(..) { ... }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "inline_asm_x86_att_syntax",
|
||
"id_span": {
|
||
"path": "src/asm_syntax.rs",
|
||
"line": 141
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of AT&T x86 assembly syntax.\n\n### Why is this bad?\nThe lint has been enabled to indicate a preference\nfor Intel x86 assembly syntax.\n\n### Example\n\n```rust\nasm!(\"lea ({}), {}\", in(reg) ptr, lateout(reg) _, options(att_syntax));\n```\nUse instead:\n```rust\nasm!(\"lea {}, [{}]\", lateout(reg) _, in(reg) ptr);\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "inline_asm_x86_intel_syntax",
|
||
"id_span": {
|
||
"path": "src/asm_syntax.rs",
|
||
"line": 92
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of Intel x86 assembly syntax.\n\n### Why is this bad?\nThe lint has been enabled to indicate a preference\nfor AT&T x86 assembly syntax.\n\n### Example\n\n```rust\nasm!(\"lea {}, [{}]\", lateout(reg) _, in(reg) ptr);\n```\nUse instead:\n```rust\nasm!(\"lea ({}), {}\", in(reg) ptr, lateout(reg) _, options(att_syntax));\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "inline_fn_without_body",
|
||
"id_span": {
|
||
"path": "src/inline_fn_without_body.rs",
|
||
"line": 28
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `#[inline]` on trait methods without bodies\n\n### Why is this bad?\nOnly implementations of trait methods may be inlined.\nThe inline attribute is ignored for trait methods without bodies.\n\n### Example\n```rust\ntrait Animal {\n #[inline]\n fn name(&self) -> &'static str;\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "inspect_for_each",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1975
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `inspect().for_each()`.\n\n### Why is this bad?\nIt is the same as performing the computation\ninside `inspect` at the beginning of the closure in `for_each`.\n\n### Example\n```rust\n[1,2,3,4,5].iter()\n.inspect(|&x| println!(\"inspect the number: {}\", x))\n.for_each(|&x| {\n assert!(x >= 0);\n});\n```\nCan be written as\n```rust\n[1,2,3,4,5].iter()\n.for_each(|&x| {\n println!(\"inspect the number: {}\", x);\n assert!(x >= 0);\n});\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "int_plus_one",
|
||
"id_span": {
|
||
"path": "src/int_plus_one.rs",
|
||
"line": 32
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block\n\n### Why is this bad?\nReadability -- better to use `> y` instead of `>= y + 1`.\n\n### Example\n```rust\nif x >= y + 1 {}\n```\n\nUse instead:\n```rust\nif x > y {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "integer_division",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 522
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for division of integers\n\n### Why is this bad?\nWhen outside of some very specific algorithms,\ninteger division is very often a mistake because it discards the\nremainder.\n\n### Example\n```rust\nlet x = 3 / 2;\nprintln!(\"{}\", x);\n```\n\nUse instead:\n```rust\nlet x = 3f32 / 2f32;\nprintln!(\"{}\", x);\n```",
|
||
"version": "1.37.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "integer_division_remainder_used",
|
||
"id_span": {
|
||
"path": "src/integer_division_remainder_used.rs",
|
||
"line": 26
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of division (/) and remainder (%) operations\nwhen performed on any integer types using the default Div and Rem trait implementations.\n\n### Why is this bad?\nIn cryptographic contexts, division can result in timing sidechannel vulnerabilities,\nand needs to be replaced with constant-time code instead (e.g. Barrett reduction).\n\n### Example\n```rust\nlet my_div = 10 / 2;\n```\nUse instead:\n```rust\nlet my_div = 10 >> 1;\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "into_iter_on_ref",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1629
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `into_iter` calls on references which should be replaced by `iter`\nor `iter_mut`.\n\n### Why is this bad?\nReadability. Calling `into_iter` on a reference will not move out its\ncontent into the resulting iterator, which is confusing. It is better just call `iter` or\n`iter_mut` directly.\n\n### Example\n```rust\n(&vec).into_iter();\n```\n\nUse instead:\n```rust\n(&vec).iter();\n```",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "into_iter_without_iter",
|
||
"id_span": {
|
||
"path": "src/iter_without_into_iter.rs",
|
||
"line": 106
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis is the opposite of the `iter_without_into_iter` lint.\nIt looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method\non the type or on any of the types in its `Deref` chain.\n\n### Why is this bad?\nIt's not bad, but having them is idiomatic and allows the type to be used in iterator chains\nby just calling `.iter()`, instead of the more awkward `<&Type>::into_iter` or `(&val).into_iter()` syntax\nin case of ambiguity with another `IntoIterator` impl.\n\n### Limitations\nThis lint focuses on providing an idiomatic API. Therefore, it will only\nlint on types which are accessible outside of the crate. For internal types,\nthese methods can be added on demand if they are actually needed. Otherwise,\nit would trigger the [`dead_code`] lint for the unused method.\n\n[`dead_code`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code\n\n### Example\n```rust\nstruct MySlice<'a>(&'a [u8]);\nimpl<'a> IntoIterator for &MySlice<'a> {\n type Item = &'a u8;\n type IntoIter = std::slice::Iter<'a, u8>;\n fn into_iter(self) -> Self::IntoIter {\n self.0.iter()\n }\n}\n```\nUse instead:\n```rust\nstruct MySlice<'a>(&'a [u8]);\nimpl<'a> MySlice<'a> {\n pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n self.into_iter()\n }\n}\nimpl<'a> IntoIterator for &MySlice<'a> {\n type Item = &'a u8;\n type IntoIter = std::slice::Iter<'a, u8>;\n fn into_iter(self) -> Self::IntoIter {\n self.0.iter()\n }\n}\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "invalid_null_ptr_usage",
|
||
"id_span": {
|
||
"path": "src/ptr.rs",
|
||
"line": 150
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nThis lint checks for invalid usages of `ptr::null`.\n\n### Why is this bad?\nThis causes undefined behavior.\n\n### Example\n```rust\n// Undefined behavior\nunsafe { std::slice::from_raw_parts(ptr::null(), 0); }\n```\n\nUse instead:\n```rust\nunsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "invalid_regex",
|
||
"id_span": {
|
||
"path": "src/regex.rs",
|
||
"line": 28
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks [regex](https://crates.io/crates/regex) creation\n(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct\nregex syntax.\n\n### Why is this bad?\nThis will lead to a runtime panic.\n\n### Example\n```rust\nRegex::new(\"(\")\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "invalid_upcast_comparisons",
|
||
"id_span": {
|
||
"path": "src/invalid_upcast_comparisons.rs",
|
||
"line": 34
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for comparisons where the relation is always either\ntrue or false, but where one side has been upcast so that the comparison is\nnecessary. Only integer types are checked.\n\n### Why is this bad?\nAn expression like `let x : u8 = ...; (x as u32) > 300`\nwill mistakenly imply that it is possible for `x` to be outside the range of\n`u8`.\n\n### Known problems\nhttps://github.com/rust-lang/rust-clippy/issues/886\n\n### Example\n```rust\nlet x: u8 = 1;\n(x as u32) > 300;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "invisible_characters",
|
||
"id_span": {
|
||
"path": "src/unicode.rs",
|
||
"line": 25
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for invisible Unicode characters in the code.\n\n### Why is this bad?\nHaving an invisible character in the code makes for all\nsorts of April fools, but otherwise is very much frowned upon.\n\n### Example\nYou don't see it, but there may be a zero-width space or soft hyphen\nsomewhere in this text.\n### Past names\n\n* `zero_width_space`\n\n",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"zero_width_space"
|
||
]
|
||
},
|
||
{
|
||
"id": "is_digit_ascii_radix",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2377
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nFinds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that\ncan be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or\n[`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit).\n\n### Why is this bad?\n`is_digit(..)` is slower and requires specifying the radix.\n\n### Example\n```rust\nlet c: char = '6';\nc.is_digit(10);\nc.is_digit(16);\n```\nUse instead:\n```rust\nlet c: char = '6';\nc.is_ascii_digit();\nc.is_ascii_hexdigit();\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "items_after_statements",
|
||
"id_span": {
|
||
"path": "src/items_after_statements.rs",
|
||
"line": 48
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for items declared after some statement in a block.\n\n### Why is this bad?\nItems live for the entire scope they are declared\nin. But statements are processed in order. This might cause confusion as\nit's hard to figure out which item is meant in a statement.\n\n### Example\n```rust\nfn foo() {\n println!(\"cake\");\n}\n\nfn main() {\n foo(); // prints \"foo\"\n fn foo() {\n println!(\"foo\");\n }\n foo(); // prints \"foo\"\n}\n```\n\nUse instead:\n```rust\nfn foo() {\n println!(\"cake\");\n}\n\nfn main() {\n fn foo() {\n println!(\"foo\");\n }\n foo(); // prints \"foo\"\n foo(); // prints \"foo\"\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "items_after_test_module",
|
||
"id_span": {
|
||
"path": "src/items_after_test_module.rs",
|
||
"line": 39
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nTriggers if an item is declared after the testing module marked with `#[cfg(test)]`.\n### Why is this bad?\nHaving items declared after the testing module is confusing and may lead to bad test coverage.\n### Example\n```rust\n#[cfg(test)]\nmod tests {\n // [...]\n}\n\nfn my_function() {\n // [...]\n}\n```\nUse instead:\n```rust\nfn my_function() {\n // [...]\n}\n\n#[cfg(test)]\nmod tests {\n // [...]\n}\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_cloned_collect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1465
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`.\n\n### Why is this bad?\n`.to_vec()` is clearer\n\n### Example\n```rust\nlet s = [1, 2, 3, 4, 5];\nlet s2: Vec<isize> = s[..].iter().cloned().collect();\n```\nThe better use would be:\n```rust\nlet s = [1, 2, 3, 4, 5];\nlet s2: Vec<isize> = s.to_vec();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_count",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2102
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `.iter().count()`.\n\n### Why is this bad?\n`.len()` is more efficient and more\nreadable.\n\n### Example\n```rust\nlet some_vec = vec![0, 1, 2, 3];\n\nsome_vec.iter().count();\n&some_vec[..].iter().count();\n```\n\nUse instead:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\n\nsome_vec.len();\n&some_vec[..].len();\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_filter_is_ok",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3886
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call.\nThis lint will require additional changes to the follow-up calls as it affects the type.\n\n### Why is this bad?\nThis pattern is often followed by manual unwrapping of `Result`. The simplification\nresults in more readable and succinct code without the need for manual unwrapping.\n\n### Example\n```rust\n// example code where clippy issues a warning\nvec![Ok::<i32, String>(1)].into_iter().filter(Result::is_ok);\n\n```\nUse instead:\n```rust\n// example code which does not raise clippy warning\nvec![Ok::<i32, String>(1)].into_iter().flatten();\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_filter_is_some",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3860
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call.\nThis lint will require additional changes to the follow-up calls as it affects the type.\n\n### Why is this bad?\nThis pattern is often followed by manual unwrapping of the `Option`. The simplification\nresults in more readable and succinct code without the need for manual unwrapping.\n\n### Example\n```rust\n// example code where clippy issues a warning\nvec![Some(1)].into_iter().filter(Option::is_some);\n\n```\nUse instead:\n```rust\n// example code which does not raise clippy warning\nvec![Some(1)].into_iter().flatten();\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_kv_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3191
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values.\n\n### Why is this bad?\n\nReadability. There are `keys` and `values` methods that\ncan be used to express that we only need the keys or the values.\n\n### Example\n\n```rust\nlet map: HashMap<u32, u32> = HashMap::new();\nlet values = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n```\n\nUse instead:\n```rust\nlet map: HashMap<u32, u32> = HashMap::new();\nlet values = map.values().collect::<Vec<_>>();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_next_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 174
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for loops on `x.next()`.\n\n### Why is this bad?\n`next()` returns either `Some(value)` if there was a\nvalue, or `None` otherwise. The insidious thing is that `Option<_>`\nimplements `IntoIterator`, so that possibly one value will be iterated,\nleading to some hard to find bugs. No one will want to write such code\n[except to win an Underhanded Rust\nContest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).\n\n### Example\n```rust\nfor x in y.next() {\n ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_next_slice",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1826
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `iter().next()` on a Slice or an Array\n\n### Why is this bad?\nThese can be shortened into `.get()`\n\n### Example\n```rust\na[2..].iter().next();\nb.iter().next();\n```\nshould be written as:\n```rust\na.get(2);\nb.get(0);\n```",
|
||
"version": "1.46.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_not_returning_iterator",
|
||
"id_span": {
|
||
"path": "src/iter_not_returning_iterator.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`.\n\n### Why is this bad?\nMethods named `iter` or `iter_mut` conventionally return an `Iterator`.\n\n### Example\n```rust\n// `String` does not implement `Iterator`\nstruct Data {}\nimpl Data {\n fn iter(&self) -> String {\n todo!()\n }\n}\n```\nUse instead:\n```rust\nuse std::str::Chars;\nstruct Data {}\nimpl Data {\n fn iter(&self) -> Chars<'static> {\n todo!()\n }\n}\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_nth",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1263
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have\nequivalent `.get()`/`.get_mut()` methods.\n\n### Why is this bad?\n`.get()` and `.get_mut()` are equivalent but more concise.\n\n### Example\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().nth(3);\nlet bad_slice = &some_vec[..].iter().nth(3);\n```\nThe correct use would be:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.get(3);\nlet bad_slice = &some_vec[..].get(3);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_nth_zero",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1237
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `iter.nth(0)`.\n\n### Why is this bad?\n`iter.next()` is equivalent to\n`iter.nth(0)`, as they both consume the next element,\n but is more readable.\n\n### Example\n```rust\nlet x = s.iter().nth(0);\n```\n\nUse instead:\n```rust\nlet x = s.iter().next();\n```",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_on_empty_collections",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2511
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nChecks for calls to `iter`, `iter_mut` or `into_iter` on empty collections\n\n### Why is this bad?\n\nIt is simpler to use the empty function from the standard library:\n\n### Example\n\n```rust\nuse std::{slice, option};\nlet a: slice::Iter<i32> = [].iter();\nlet f: option::IntoIter<i32> = None.into_iter();\n```\nUse instead:\n```rust\nuse std::iter;\nlet a: iter::Empty<i32> = iter::empty();\nlet b: iter::Empty<i32> = iter::empty();\n```\n\n### Known problems\n\nThe type of the resulting iterator might become incompatible with its usage",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_on_single_items",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2479
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nChecks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item\n\n### Why is this bad?\n\nIt is simpler to use the once function from the standard library:\n\n### Example\n\n```rust\nlet a = [123].iter();\nlet b = Some(123).into_iter();\n```\nUse instead:\n```rust\nuse std::iter;\nlet a = iter::once(&123);\nlet b = iter::once(123);\n```\n\n### Known problems\n\nThe type of the resulting iterator might become incompatible with its usage",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_out_of_bounds",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3630
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for iterator combinator calls such as `.take(x)` or `.skip(x)`\nwhere `x` is greater than the amount of items that an iterator will produce.\n\n### Why is this bad?\nTaking or skipping more items than there are in an iterator either creates an iterator\nwith all items from the original iterator or an iterator with no items at all.\nThis is most likely not what the user intended to do.\n\n### Example\n```rust\nfor _ in [1, 2, 3].iter().take(4) {}\n```\nUse instead:\n```rust\nfor _ in [1, 2, 3].iter() {}\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_over_hash_type",
|
||
"id_span": {
|
||
"path": "src/iter_over_hash_type.rs",
|
||
"line": 38
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops.\n\n### Why is this bad?\nBecause hash types are unordered, when iterated through such as in a for loop, the values are returned in\nan undefined order. As a result, on redundant systems this may cause inconsistencies and anomalies.\nIn addition, the unknown order of the elements may reduce readability or introduce other undesired\nside effects.\n\n### Example\n```rust\n let my_map = std::collections::HashMap::<i32, String>::new();\n for (key, value) in my_map { /* ... */ }\n```\nUse instead:\n```rust\n let my_map = std::collections::HashMap::<i32, String>::new();\n let mut keys = my_map.keys().clone().collect::<Vec<_>>();\n keys.sort();\n for key in keys {\n let value = &my_map[key];\n }\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_overeager_cloned",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 223
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed.\n\n### Why is this bad?\nIt's often inefficient to clone all elements of an iterator, when eventually, only some\nof them will be consumed.\n\n### Known Problems\nThis `lint` removes the side of effect of cloning items in the iterator.\nA code that relies on that side-effect could fail.\n\n### Examples\n```rust\nvec.iter().cloned().take(10);\nvec.iter().cloned().last();\n```\n\nUse instead:\n```rust\nvec.iter().take(10).cloned();\nvec.iter().last().cloned();\n```",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_skip_next",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1288
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.skip(x).next()` on iterators.\n\n### Why is this bad?\n`.nth(x)` is cleaner\n\n### Example\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().skip(3).next();\nlet bad_slice = &some_vec[..].iter().skip(3).next();\n```\nThe correct use would be:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().nth(3);\nlet bad_slice = &some_vec[..].iter().nth(3);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_skip_zero",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3544
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for usage of `.skip(0)` on iterators.\n\n### Why is this bad?\nThis was likely intended to be `.skip(1)` to skip the first element, as `.skip(0)` does\nnothing. If not, the call should be removed.\n\n### Example\n```rust\nlet v = vec![1, 2, 3];\nlet x = v.iter().skip(0).collect::<Vec<_>>();\nlet y = v.iter().collect::<Vec<_>>();\nassert_eq!(x, y);\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_with_drain",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1313
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration.\n\n### Why is this bad?\n`.into_iter()` is simpler with better performance.\n\n### Example\n```rust\nlet mut foo = vec![0, 1, 2, 3];\nlet bar: HashSet<usize> = foo.drain(..).collect();\n```\nUse instead:\n```rust\nlet foo = vec![0, 1, 2, 3];\nlet bar: HashSet<usize> = foo.into_iter().collect();\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "iter_without_into_iter",
|
||
"id_span": {
|
||
"path": "src/iter_without_into_iter.rs",
|
||
"line": 54
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLooks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation.\n\n### Why is this bad?\nIt's not bad, but having them is idiomatic and allows the type to be used in for loops directly\n(`for val in &iter {}`), without having to first call `iter()` or `iter_mut()`.\n\n### Limitations\nThis lint focuses on providing an idiomatic API. Therefore, it will only\nlint on types which are accessible outside of the crate. For internal types,\nthe `IntoIterator` trait can be implemented on demand if it is actually needed.\n\n### Example\n```rust\nstruct MySlice<'a>(&'a [u8]);\nimpl<'a> MySlice<'a> {\n pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n self.0.iter()\n }\n}\n```\nUse instead:\n```rust\nstruct MySlice<'a>(&'a [u8]);\nimpl<'a> MySlice<'a> {\n pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n self.0.iter()\n }\n}\nimpl<'a> IntoIterator for &MySlice<'a> {\n type Item = &'a u8;\n type IntoIter = std::slice::Iter<'a, u8>;\n fn into_iter(self) -> Self::IntoIter {\n self.iter()\n }\n}\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "iterator_step_by_zero",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1184
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for calling `.step_by(0)` on iterators which panics.\n\n### Why is this bad?\nThis very much looks like an oversight. Use `panic!()` instead if you\nactually intend to panic.\n\n### Example\n```rust\nfor x in (0..100).step_by(0) {\n //..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "join_absolute_paths",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3786
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `Path::join` that start with a path separator (`\\\\` or `/`).\n\n### Why is this bad?\nIf the argument to `Path::join` starts with a separator, it will overwrite\nthe original path. If this is intentional, prefer using `Path::new` instead.\n\nNote the behavior is platform dependent. A leading `\\\\` will be accepted\non unix systems as part of the file name\n\nSee [`Path::join`](https://doc.rust-lang.org/std/path/struct.Path.html#method.join)\n\n### Example\n```rust\nlet path = Path::new(\"/bin\");\nlet joined_path = path.join(\"/sh\");\nassert_eq!(joined_path, PathBuf::from(\"/sh\"));\n```\n\nUse instead;\n```rust\nlet path = Path::new(\"/bin\");\n\n// If this was unintentional, remove the leading separator\nlet joined_path = path.join(\"sh\");\nassert_eq!(joined_path, PathBuf::from(\"/bin/sh\"));\n\n// If this was intentional, create a new path instead\nlet new = Path::new(\"/sh\");\nassert_eq!(new, PathBuf::from(\"/sh\"));\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "just_underscores_and_digits",
|
||
"id_span": {
|
||
"path": "src/non_expressive_names.rs",
|
||
"line": 71
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if you have variables whose name consists of just\nunderscores and digits.\n\n### Why is this bad?\nIt's hard to memorize what a variable means without a\ndescriptive name.\n\n### Example\n```rust\nlet _1 = 1;\nlet ___1 = 1;\nlet __1___2 = 11;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_const_arrays",
|
||
"id_span": {
|
||
"path": "src/large_const_arrays.rs",
|
||
"line": 29
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for large `const` arrays that should\nbe defined as `static` instead.\n\n### Why is this bad?\nPerformance: const variables are inlined upon use.\nStatic items result in only one instance and has a fixed location in memory.\n\n### Example\n```rust\npub const a = [0u32; 1_000_000];\n```\n\nUse instead:\n```rust\npub static a = [0u32; 1_000_000];\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `array-size-threshold`: The maximum allowed size for arrays on the stack (default: `512000`)",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_digit_groups",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 126
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if the digits of an integral or floating-point\nconstant are grouped into groups that\nare too large.\n\n### Why is this bad?\nNegatively impacts readability.\n\n### Example\n```rust\nlet x: u64 = 6186491_8973511;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_enum_variant",
|
||
"id_span": {
|
||
"path": "src/large_enum_variant.rs",
|
||
"line": 57
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for large size differences between variants on\n`enum`s.\n\n### Why is this bad?\nEnum size is bounded by the largest variant. Having one\nlarge variant can penalize the memory layout of that enum.\n\n### Known problems\nThis lint obviously cannot take the distribution of\nvariants in your running program into account. It is possible that the\nsmaller variants make up less than 1% of all instances, in which case\nthe overhead is negligible and the boxing is counter-productive. Always\nmeasure the change this lint suggests.\n\nFor types that implement `Copy`, the suggestion to `Box` a variant's\ndata would require removing the trait impl. The types can of course\nstill be `Clone`, but that is worse ergonomically. Depending on the\nuse case it may be possible to store the large data in an auxiliary\nstructure (e.g. Arena or ECS).\n\nThe lint will ignore the impact of generic types to the type layout by\nassuming every type parameter is zero-sized. Depending on your use case,\nthis may lead to a false positive.\n\n### Example\n```rust\nenum Test {\n A(i32),\n B([i32; 8000]),\n}\n```\n\nUse instead:\n```rust\n// Possibly better\nenum Test2 {\n A(i32),\n B(Box<[i32; 8000]>),\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `enum-variant-size-threshold`: The maximum size of an enum's variant to avoid box suggestion (default: `200`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_futures",
|
||
"id_span": {
|
||
"path": "src/large_futures.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nIt checks for the size of a `Future` created by `async fn` or `async {}`.\n\n### Why is this bad?\nDue to the current [unideal implementation](https://github.com/rust-lang/rust/issues/69826) of `Coroutine`,\nlarge size of a `Future` may cause stack overflows.\n\n### Example\n```rust\nasync fn large_future(_x: [u8; 16 * 1024]) {}\n\npub async fn trigger() {\n large_future([0u8; 16 * 1024]).await;\n}\n```\n\n`Box::pin` the big future instead.\n\n```rust\nasync fn large_future(_x: [u8; 16 * 1024]) {}\n\npub async fn trigger() {\n Box::pin(large_future([0u8; 16 * 1024])).await;\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `future-size-threshold`: The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint (default: `16384`)",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_include_file",
|
||
"id_span": {
|
||
"path": "src/large_include_file.rs",
|
||
"line": 33
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the inclusion of large files via `include_bytes!()`\nand `include_str!()`\n\n### Why is this bad?\nIncluding large files can increase the size of the binary\n\n### Example\n```rust\nlet included_str = include_str!(\"very_large_file.txt\");\nlet included_bytes = include_bytes!(\"very_large_file.txt\");\n```\n\nUse instead:\n```rust\nuse std::fs;\n\n// You can load the file at runtime\nlet string = fs::read_to_string(\"very_large_file.txt\")?;\nlet bytes = fs::read(\"very_large_file.txt\")?;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `max-include-file-size`: The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes (default: `1000000`)",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_stack_arrays",
|
||
"id_span": {
|
||
"path": "src/large_stack_arrays.rs",
|
||
"line": 21
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for local arrays that may be too large.\n\n### Why is this bad?\nLarge local arrays may cause stack overflow.\n\n### Example\n```rust\nlet a = [0u32; 1_000_000];\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `array-size-threshold`: The maximum allowed size for arrays on the stack (default: `512000`)",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_stack_frames",
|
||
"id_span": {
|
||
"path": "src/large_stack_frames.rs",
|
||
"line": 78
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions that use a lot of stack space.\n\nThis often happens when constructing a large type, such as an array with a lot of elements,\nor constructing *many* smaller-but-still-large structs, or copying around a lot of large types.\n\nThis lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays)\nthat is intended to look at functions as a whole instead of only individual array expressions inside of a function.\n\n### Why is this bad?\nThe stack region of memory is very limited in size (usually *much* smaller than the heap) and attempting to\nuse too much will result in a stack overflow and crash the program.\nTo avoid this, you should consider allocating large types on the heap instead (e.g. by boxing them).\n\nKeep in mind that the code path to construction of large types does not even need to be reachable;\nit purely needs to *exist* inside of the function to contribute to the stack size.\nFor example, this causes a stack overflow even though the branch is unreachable:\n```rust\nfn main() {\n if false {\n let x = [0u8; 10000000]; // 10 MB stack array\n black_box(&x);\n }\n}\n```\n\n### Known issues\nFalse positives. The stack size that clippy sees is an estimated value and can be vastly different\nfrom the actual stack usage after optimizations passes have run (especially true in release mode).\nModern compilers are very smart and are able to optimize away a lot of unnecessary stack allocations.\nIn debug mode however, it is usually more accurate.\n\nThis lint works by summing up the size of all variables that the user typed, variables that were\nimplicitly introduced by the compiler for temporaries, function arguments and the return value,\nand comparing them against a (configurable, but high-by-default).\n\n### Example\nThis function creates four 500 KB arrays on the stack. Quite big but just small enough to not trigger `large_stack_arrays`.\nHowever, looking at the function as a whole, it's clear that this uses a lot of stack space.\n```rust\nstruct QuiteLargeType([u8; 500_000]);\nfn foo() {\n // ... some function that uses a lot of stack space ...\n let _x1 = QuiteLargeType([0; 500_000]);\n let _x2 = QuiteLargeType([0; 500_000]);\n let _x3 = QuiteLargeType([0; 500_000]);\n let _x4 = QuiteLargeType([0; 500_000]);\n}\n```\n\nInstead of doing this, allocate the arrays on the heap.\nThis currently requires going through a `Vec` first and then converting it to a `Box`:\n```rust\nstruct NotSoLargeType(Box<[u8]>);\n\nfn foo() {\n let _x1 = NotSoLargeType(vec![0; 500_000].into_boxed_slice());\n// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now heap allocated.\n// The size of `NotSoLargeType` is 16 bytes.\n// ...\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `stack-size-threshold`: The maximum allowed stack size for functions in bytes (default: `512000`)",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "large_types_passed_by_value",
|
||
"id_span": {
|
||
"path": "src/pass_by_ref_or_value.rs",
|
||
"line": 101
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions taking arguments by value, where\nthe argument type is `Copy` and large enough to be worth considering\npassing by reference. Does not trigger if the function is being exported,\nbecause that might induce API breakage, if the parameter is declared as mutable,\nor if the argument is a `self`.\n\n### Why is this bad?\nArguments passed by value might result in an unnecessary\nshallow copy, taking up more space in the stack and requiring a call to\n`memcpy`, which can be expensive.\n\n### Example\n```rust\n#[derive(Clone, Copy)]\nstruct TooLarge([u8; 2048]);\n\nfn foo(v: TooLarge) {}\n```\n\nUse instead:\n```rust\nfn foo(v: &TooLarge) {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `pass-by-value-size-limit`: The minimum size (in bytes) to consider a type for passing by reference instead of by value. (default: `256`)",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "legacy_numeric_constants",
|
||
"id_span": {
|
||
"path": "src/legacy_numeric_constants.rs",
|
||
"line": 32
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `<integer>::max_value()`, `std::<integer>::MAX`,\n`std::<float>::EPSILON`, etc.\n\n### Why is this bad?\nAll of these have been superseded by the associated constants on their respective types,\nsuch as `i128::MAX`. These legacy items may be deprecated in a future version of rust.\n\n### Example\n```rust\nlet eps = std::f32::EPSILON;\n```\nUse instead:\n```rust\nlet eps = f32::EPSILON;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "len_without_is_empty",
|
||
"id_span": {
|
||
"path": "src/len_zero.rs",
|
||
"line": 77
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for items that implement `.len()` but not\n`.is_empty()`.\n\n### Why is this bad?\nIt is good custom to have both methods, because for\nsome data structures, asking about the length will be a costly operation,\nwhereas `.is_empty()` can usually answer in constant time. Also it used to\nlead to false positives on the [`len_zero`](#len_zero) lint – currently that\nlint will ignore such entities.\n\n### Example\n```rust\nimpl X {\n pub fn len(&self) -> usize {\n ..\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "len_zero",
|
||
"id_span": {
|
||
"path": "src/len_zero.rs",
|
||
"line": 51
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for getting the length of something via `.len()`\njust to compare to zero, and suggests using `.is_empty()` where applicable.\n\n### Why is this bad?\nSome structures can answer `.is_empty()` much faster\nthan calculating their length. So it is good to get into the habit of using\n`.is_empty()`, and having it is cheap.\nBesides, it makes the intent clearer than a manual comparison in some contexts.\n\n### Example\n```rust\nif x.len() == 0 {\n ..\n}\nif y.len() != 0 {\n ..\n}\n```\ninstead use\n```rust\nif x.is_empty() {\n ..\n}\nif !y.is_empty() {\n ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_and_return",
|
||
"id_span": {
|
||
"path": "src/returns.rs",
|
||
"line": 56
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `let`-bindings, which are subsequently\nreturned.\n\n### Why is this bad?\nIt is just extraneous code. Remove it to make your code\nmore rusty.\n\n### Known problems\nIn the case of some temporaries, e.g. locks, eliding the variable binding could lead\nto deadlocks. See [this issue](https://github.com/rust-lang/rust/issues/37612).\nThis could become relevant if the code is later changed to use the code that would have been\nbound without first assigning it to a let-binding.\n\n### Example\n```rust\nfn foo() -> String {\n let x = String::new();\n x\n}\n```\ninstead, use\n```rust\nfn foo() -> String {\n String::new()\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_underscore_future",
|
||
"id_span": {
|
||
"path": "src/let_underscore.rs",
|
||
"line": 89
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `let _ = <expr>` where the resulting type of expr implements `Future`\n\n### Why is this bad?\nFutures must be polled for work to be done. The original intention was most likely to await the future\nand ignore the resulting value.\n\n### Example\n```rust\nasync fn foo() -> Result<(), ()> {\n Ok(())\n}\nlet _ = foo();\n```\n\nUse instead:\n```rust\nasync fn foo() -> Result<(), ()> {\n Ok(())\n}\nlet _ = foo().await;\n```",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_underscore_lock",
|
||
"id_span": {
|
||
"path": "src/let_underscore.rs",
|
||
"line": 58
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in\n`parking_lot`. For `std` locks see the `rustc` lint\n[`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)\n\n### Why is this bad?\nThis statement immediately drops the lock instead of\nextending its lifetime to the end of the scope, which is often not intended.\nTo extend lock lifetime to the end of the scope, use an underscore-prefixed\nname instead (i.e. _lock). If you want to explicitly drop the lock,\n`std::mem::drop` conveys your intention better and is less error-prone.\n\n### Example\n```rust\nlet _ = mutex.lock();\n```\n\nUse instead:\n```rust\nlet _lock = mutex.lock();\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_underscore_must_use",
|
||
"id_span": {
|
||
"path": "src/let_underscore.rs",
|
||
"line": 30
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `let _ = <expr>` where expr is `#[must_use]`\n\n### Why is this bad?\nIt's better to explicitly handle the value of a `#[must_use]`\nexpr\n\n### Example\n```rust\nfn f() -> Result<u32, u32> {\n Ok(0)\n}\n\nlet _ = f();\n// is_ok() is marked #[must_use]\nlet _ = f().is_ok();\n```",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_underscore_untyped",
|
||
"id_span": {
|
||
"path": "src/let_underscore.rs",
|
||
"line": 127
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `let _ = <expr>` without a type annotation, and suggests to either provide one,\nor remove the `let` keyword altogether.\n\n### Why is this bad?\nThe `let _ = <expr>` expression ignores the value of `<expr>` but will remain doing so even\nif the type were to change, thus potentially introducing subtle bugs. By supplying a type\nannotation, one will be forced to re-visit the decision to ignore the value in such cases.\n\n### Known problems\nThe `_ = <expr>` is not properly supported by some tools (e.g. IntelliJ) and may seem odd\nto many developers. This lint also partially overlaps with the other `let_underscore_*`\nlints.\n\n### Example\n```rust\nfn foo() -> Result<u32, ()> {\n Ok(123)\n}\nlet _ = foo();\n```\nUse instead:\n```rust\nfn foo() -> Result<u32, ()> {\n Ok(123)\n}\n// Either provide a type annotation:\nlet _: Result<u32, ()> = foo();\n// …or drop the let keyword:\n_ = foo();\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_unit_value",
|
||
"id_span": {
|
||
"path": "src/unit_types/mod.rs",
|
||
"line": 25
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for binding a unit value.\n\n### Why is this bad?\nA unit value cannot usefully be used anywhere. So\nbinding one is kind of pointless.\n\n### Example\n```rust\nlet x = {\n 1;\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "let_with_type_underscore",
|
||
"id_span": {
|
||
"path": "src/let_with_type_underscore.rs",
|
||
"line": 22
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects when a variable is declared with an explicit type of `_`.\n### Why is this bad?\nIt adds noise, `: _` provides zero clarity or utility.\n### Example\n```rust\nlet my_number: _ = 1;\n```\nUse instead:\n```rust\nlet my_number = 1;\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "lines_filter_map_ok",
|
||
"id_span": {
|
||
"path": "src/lines_filter_map_ok.rs",
|
||
"line": 54
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`\nwhen `lines` has type `std::io::Lines`.\n\n### Why is this bad?\n`Lines` instances might produce a never-ending stream of `Err`, in which case\n`filter_map(Result::ok)` will enter an infinite loop while waiting for an\n`Ok` variant. Calling `next()` once is sufficient to enter the infinite loop,\neven in the absence of explicit loops in the user code.\n\nThis situation can arise when working with user-provided paths. On some platforms,\n`std::fs::File::open(path)` might return `Ok(fs)` even when `path` is a directory,\nbut any later attempt to read from `fs` will return an error.\n\n### Known problems\nThis lint suggests replacing `filter_map()` or `flat_map()` applied to a `Lines`\ninstance in all cases. There are two cases where the suggestion might not be\nappropriate or necessary:\n\n- If the `Lines` instance can never produce any error, or if an error is produced\n only once just before terminating the iterator, using `map_while()` is not\n necessary but will not do any harm.\n- If the `Lines` instance can produce intermittent errors then recover and produce\n successful results, using `map_while()` would stop at the first error.\n\n### Example\n```rust\nlet mut lines = BufReader::new(File::open(\"some-path\")?).lines().filter_map(Result::ok);\n// If \"some-path\" points to a directory, the next statement never terminates:\nlet first_line: Option<String> = lines.next();\n```\nUse instead:\n```rust\nlet mut lines = BufReader::new(File::open(\"some-path\")?).lines().map_while(Result::ok);\nlet first_line: Option<String> = lines.next();\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "linkedlist",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 160
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of any `LinkedList`, suggesting to use a\n`Vec` or a `VecDeque` (formerly called `RingBuf`).\n\n### Why is this bad?\nGankra says:\n\n> The TL;DR of `LinkedList` is that it's built on a massive amount of\npointers and indirection.\n> It wastes memory, it has terrible cache locality, and is all-around slow.\n`RingBuf`, while\n> \"only\" amortized for push/pop, should be faster in the general case for\nalmost every possible\n> workload, and isn't even amortized at all if you can predict the capacity\nyou need.\n>\n> `LinkedList`s are only really good if you're doing a lot of merging or\nsplitting of lists.\n> This is because they can just mangle some pointers instead of actually\ncopying the data. Even\n> if you're doing a lot of insertion in the middle of the list, `RingBuf`\ncan still be better\n> because of how expensive it is to seek to the middle of a `LinkedList`.\n\n### Known problems\nFalse positives – the instances where using a\n`LinkedList` makes sense are few and far between, but they can still happen.\n\n### Example\n```rust\nlet x: LinkedList<usize> = LinkedList::new();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "lint_groups_priority",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 201
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for lint groups with the same priority as lints in the `Cargo.toml`\n[`[lints]` table](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section).\n\nThis lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918)\nis resolved.\n\n### Why is this bad?\nThe order of lints in the `[lints]` is ignored, to have a lint override a group the\n`priority` field needs to be used, otherwise the sort order is undefined.\n\n### Known problems\nDoes not check lints inherited using `lints.workspace = true`\n\n### Example\n```toml\n# Passed as `--allow=clippy::similar_names --warn=clippy::pedantic`\n# which results in `similar_names` being `warn`\n[lints.clippy]\npedantic = \"warn\"\nsimilar_names = \"allow\"\n```\nUse instead:\n```toml\n# Passed as `--warn=clippy::pedantic --allow=clippy::similar_names`\n# which results in `similar_names` being `allow`\n[lints.clippy]\npedantic = { level = \"warn\", priority = -1 }\nsimilar_names = \"allow\"\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "little_endian_bytes",
|
||
"id_span": {
|
||
"path": "src/endian_bytes.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`.\n\n### Why is this bad?\nIt's not, but some may wish to lint usage of this method, either to suggest using the host\nendianness or big endian.\n\n### Example\n```rust\nlet _x = 2i32.to_le_bytes();\nlet _y = 2i64.to_le_bytes();\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "lossy_float_literal",
|
||
"id_span": {
|
||
"path": "src/float_literal.rs",
|
||
"line": 56
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for whole number float literals that\ncannot be represented as the underlying type without loss.\n\n### Why is this bad?\nRust will silently lose precision during\nconversion to a float.\n\n### Example\n```rust\nlet _: f32 = 16_777_217.0; // 16_777_216.0\n```\n\nUse instead:\n```rust\nlet _: f32 = 16_777_216.0;\nlet _: f64 = 16_777_217.0;\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "macro_use_imports",
|
||
"id_span": {
|
||
"path": "src/macro_use.rs",
|
||
"line": 28
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `#[macro_use] use...`.\n\n### Why is this bad?\nSince the Rust 2018 edition you can import\nmacro's directly, this is considered idiomatic.\n\n### Example\n```rust\n#[macro_use]\nuse some_macro;\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "main_recursion",
|
||
"id_span": {
|
||
"path": "src/main_recursion.rs",
|
||
"line": 23
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for recursion using the entrypoint.\n\n### Why is this bad?\nApart from special setups (which we could detect following attributes like #![no_std]),\nrecursing into main() seems like an unintuitive anti-pattern we should be able to detect.\n\n### Example\n```rust\nfn main() {\n main();\n}\n```",
|
||
"version": "1.38.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_assert",
|
||
"id_span": {
|
||
"path": "src/manual_assert.rs",
|
||
"line": 31
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects `if`-then-`panic!` that can be replaced with `assert!`.\n\n### Why is this bad?\n`assert!` is simpler than `if`-then-`panic!`.\n\n### Example\n```rust\nlet sad_people: Vec<&str> = vec![];\nif !sad_people.is_empty() {\n panic!(\"there are sad people: {:?}\", sad_people);\n}\n```\nUse instead:\n```rust\nlet sad_people: Vec<&str> = vec![];\nassert!(sad_people.is_empty(), \"there are sad people: {:?}\", sad_people);\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_async_fn",
|
||
"id_span": {
|
||
"path": "src/manual_async_fn.rs",
|
||
"line": 33
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nIt checks for manual implementations of `async` functions.\n\n### Why is this bad?\nIt's more idiomatic to use the dedicated syntax.\n\n### Example\n```rust\nuse std::future::Future;\n\nfn foo() -> impl Future<Output = i32> { async { 42 } }\n```\nUse instead:\n```rust\nasync fn foo() -> i32 { 42 }\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_bits",
|
||
"id_span": {
|
||
"path": "src/manual_bits.rs",
|
||
"line": 32
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `std::mem::size_of::<T>() * 8` when\n`T::BITS` is available.\n\n### Why is this bad?\nCan be written as the shorter `T::BITS`.\n\n### Example\n```rust\nstd::mem::size_of::<usize>() * 8;\n```\nUse instead:\n```rust\nusize::BITS as usize;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_c_str_literals",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 4026
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the manual creation of C strings (a string with a `NUL` byte at the end), either\nthrough one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`\non a (byte) string literal with a hardcoded `\\0` byte at the end.\n\n### Why is this bad?\nThis can be written more concisely using `c\"str\"` literals and is also less error-prone,\nbecause the compiler checks for interior `NUL` bytes and the terminating `NUL` byte is inserted automatically.\n\n### Example\n```rust\nfn needs_cstr(_: &CStr) {}\n\nneeds_cstr(CStr::from_bytes_with_nul(b\"Hello\\0\").unwrap());\nunsafe { libc::puts(\"World\\0\".as_ptr().cast()) }\n```\nUse instead:\n```rust\nfn needs_cstr(_: &CStr) {}\n\nneeds_cstr(c\"Hello\");\nunsafe { libc::puts(c\"World\".as_ptr()) }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_clamp",
|
||
"id_span": {
|
||
"path": "src/manual_clamp.rs",
|
||
"line": 89
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nIdentifies good opportunities for a clamp function from std or core, and suggests using it.\n\n### Why is this bad?\nclamp is much shorter, easier to read, and doesn't use any control flow.\n\n### Limitations\n\nThis lint will only trigger if max and min are known at compile time, and max is\ngreater than min.\n\n### Known issue(s)\nIf the clamped variable is NaN this suggestion will cause the code to propagate NaN\nrather than returning either `max` or `min`.\n\n`clamp` functions will panic if `max < min`, `max.is_nan()`, or `min.is_nan()`.\nSome may consider panicking in these situations to be desirable, but it also may\nintroduce panicking where there wasn't any before.\n\nSee also [the discussion in the\nPR](https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1278922613).\n\n### Examples\n```rust\nif input > max {\n max\n} else if input < min {\n min\n} else {\n input\n}\n```\n\n```rust\ninput.max(min).min(max)\n```\n\n```rust\nmatch input {\n x if x > max => max,\n x if x < min => min,\n x => x,\n}\n```\n\n```rust\nlet mut x = input;\nif x < min { x = min; }\nif x > max { x = max; }\n```\nUse instead:\n```rust\ninput.clamp(min, max)\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_filter",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 942
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `match` which could be implemented using `filter`\n\n### Why is this bad?\nUsing the `filter` method is clearer and more concise.\n\n### Example\n```rust\nmatch Some(0) {\n Some(x) => if x % 2 == 0 {\n Some(x)\n } else {\n None\n },\n None => None,\n};\n```\nUse instead:\n```rust\nSome(0).filter(|&x| x % 2 == 0);\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_filter_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 762
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.filter(_).map(_)` that can be written more simply\nas `filter_map(_)`.\n\n### Why is this bad?\nRedundant code in the `filter` and `map` operations is poor style and\nless performant.\n\n### Example\n```rust\n(0_i32..10)\n .filter(|n| n.checked_add(1).is_some())\n .map(|n| n.checked_add(1).unwrap());\n```\n\nUse instead:\n```rust\n(0_i32..10).filter_map(|n| n.checked_add(1));\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_find",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 577
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual implementations of Iterator::find\n\n### Why is this bad?\nIt doesn't affect performance, but using `find` is shorter and easier to read.\n\n### Example\n\n```rust\nfn example(arr: Vec<i32>) -> Option<i32> {\n for el in arr {\n if el == 1 {\n return Some(el);\n }\n }\n None\n}\n```\nUse instead:\n```rust\nfn example(arr: Vec<i32>) -> Option<i32> {\n arr.into_iter().find(|&el| el == 1)\n}\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_find_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 788
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.find(_).map(_)` that can be written more simply\nas `find_map(_)`.\n\n### Why is this bad?\nRedundant code in the `find` and `map` operations is poor style and\nless performant.\n\n### Example\n```rust\n(0_i32..10)\n .find(|n| n.checked_add(1).is_some())\n .map(|n| n.checked_add(1).unwrap());\n```\n\nUse instead:\n```rust\n(0_i32..10).find_map(|n| n.checked_add(1));\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_flatten",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 510
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary `if let` usage in a for loop\nwhere only the `Some` or `Ok` variant of the iterator element is used.\n\n### Why is this bad?\nIt is verbose and can be simplified\nby first calling the `flatten` method on the `Iterator`.\n\n### Example\n\n```rust\nlet x = vec![Some(1), Some(2), Some(3)];\nfor n in x {\n if let Some(n) = n {\n println!(\"{}\", n);\n }\n}\n```\nUse instead:\n```rust\nlet x = vec![Some(1), Some(2), Some(3)];\nfor n in x.into_iter().flatten() {\n println!(\"{}\", n);\n}\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_hash_one",
|
||
"id_span": {
|
||
"path": "src/manual_hash_one.rs",
|
||
"line": 44
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for cases where [`BuildHasher::hash_one`] can be used.\n\n[`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one\n\n### Why is this bad?\nIt is more concise to use the `hash_one` method.\n\n### Example\n```rust\nuse std::hash::{BuildHasher, Hash, Hasher};\nuse std::collections::hash_map::RandomState;\n\nlet s = RandomState::new();\nlet value = vec![1, 2, 3];\n\nlet mut hasher = s.build_hasher();\nvalue.hash(&mut hasher);\nlet hash = hasher.finish();\n```\nUse instead:\n```rust\nuse std::hash::BuildHasher;\nuse std::collections::hash_map::RandomState;\n\nlet s = RandomState::new();\nlet value = vec![1, 2, 3];\n\nlet hash = s.hash_one(&value);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_instant_elapsed",
|
||
"id_span": {
|
||
"path": "src/instant_subtraction.rs",
|
||
"line": 36
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLints subtraction between `Instant::now()` and another `Instant`.\n\n### Why is this bad?\nIt is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns\nas `Instant` subtraction saturates.\n\n`prev_instant.elapsed()` also more clearly signals intention.\n\n### Example\n```rust\nuse std::time::Instant;\nlet prev_instant = Instant::now();\nlet duration = Instant::now() - prev_instant;\n```\nUse instead:\n```rust\nuse std::time::Instant;\nlet prev_instant = Instant::now();\nlet duration = prev_instant.elapsed();\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_is_ascii_check",
|
||
"id_span": {
|
||
"path": "src/manual_is_ascii_check.rs",
|
||
"line": 54
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSuggests to use dedicated built-in methods,\n`is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding\nascii range\n\n### Why is this bad?\nUsing the built-in functions is more readable and makes it\nclear that it's not a specific subset of characters, but all\nASCII (lowercase|uppercase|digit|hexdigit) characters.\n### Example\n```rust\nfn main() {\n assert!(matches!('x', 'a'..='z'));\n assert!(matches!(b'X', b'A'..=b'Z'));\n assert!(matches!('2', '0'..='9'));\n assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n assert!(matches!('C', '0'..='9' | 'a'..='f' | 'A'..='F'));\n\n ('0'..='9').contains(&'0');\n ('a'..='z').contains(&'a');\n ('A'..='Z').contains(&'A');\n}\n```\nUse instead:\n```rust\nfn main() {\n assert!('x'.is_ascii_lowercase());\n assert!(b'X'.is_ascii_uppercase());\n assert!('2'.is_ascii_digit());\n assert!('x'.is_ascii_alphabetic());\n assert!('C'.is_ascii_hexdigit());\n\n '0'.is_ascii_digit();\n 'a'.is_ascii_lowercase();\n 'A'.is_ascii_uppercase();\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_is_finite",
|
||
"id_span": {
|
||
"path": "src/manual_float_methods.rs",
|
||
"line": 55
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual `is_finite` reimplementations\n(i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`).\n\n### Why is this bad?\nThe method `is_finite` is shorter and more readable.\n\n### Example\n```rust\nif x != f32::INFINITY && x != f32::NEG_INFINITY {}\nif x.abs() < f32::INFINITY {}\n```\nUse instead:\n```rust\nif x.is_finite() {}\nif x.is_finite() {}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_is_infinite",
|
||
"id_span": {
|
||
"path": "src/manual_float_methods.rs",
|
||
"line": 30
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual `is_infinite` reimplementations\n(i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`).\n\n### Why is this bad?\nThe method `is_infinite` is shorter and more readable.\n\n### Example\n```rust\nif x == f32::INFINITY || x == f32::NEG_INFINITY {}\n```\nUse instead:\n```rust\nif x.is_infinite() {}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_is_variant_and",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3913
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type.\n\n### Why is this bad?\nReadability. These can be written more concisely as `option.is_some_and(f)` and `result.is_ok_and(f)`.\n\n### Example\n```rust\noption.map(|a| a > 10).unwrap_or_default();\nresult.map(|a| a > 10).unwrap_or_default();\n```\nUse instead:\n```rust\noption.is_some_and(|a| a > 10);\nresult.is_ok_and(|a| a > 10);\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_let_else",
|
||
"id_span": {
|
||
"path": "src/manual_let_else.rs",
|
||
"line": 45
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nWarn of cases where `let...else` could be used\n\n### Why is this bad?\n\n`let...else` provides a standard construct for this pattern\nthat people can easily recognize. It's also more compact.\n\n### Example\n\n```rust\nlet v = if let Some(v) = w { v } else { return };\n```\n\nCould be written:\n\n```rust\nlet Some(v) = w else { return };\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `matches-for-let-else`: Whether the matches should be considered by the lint, and whether there should\n be filtering for common types. (default: `\"WellKnownTypes\"`)- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_main_separator_str",
|
||
"id_span": {
|
||
"path": "src/manual_main_separator_str.rs",
|
||
"line": 30
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for references on `std::path::MAIN_SEPARATOR.to_string()` used\nto build a `&str`.\n\n### Why is this bad?\nThere exists a `std::path::MAIN_SEPARATOR_STR` which does not require\nan extra memory allocation.\n\n### Example\n```rust\nlet s: &str = &std::path::MAIN_SEPARATOR.to_string();\n```\nUse instead:\n```rust\nlet s: &str = std::path::MAIN_SEPARATOR_STR;\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_map",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 914
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `match` which could be implemented using `map`\n\n### Why is this bad?\nUsing the `map` method is clearer and more concise.\n\n### Example\n```rust\nmatch Some(0) {\n Some(x) => Some(x + 1),\n None => None,\n};\n```\nUse instead:\n```rust\nSome(0).map(|x| x + 1);\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_memcpy",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 56
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for for-loops that manually copy items between\nslices that could be optimized by having a memcpy.\n\n### Why is this bad?\nIt is not as fast as a memcpy.\n\n### Example\n```rust\nfor i in 0..src.len() {\n dst[i + 64] = src[i];\n}\n```\n\nUse instead:\n```rust\ndst[64..(src.len() + 64)].clone_from_slice(&src[..]);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_next_back",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3364
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.rev().next()` on a `DoubleEndedIterator`\n\n### Why is this bad?\n`.next_back()` is cleaner.\n\n### Example\n```rust\nfoo.iter().rev().next();\n```\nUse instead:\n```rust\nfoo.iter().next_back();\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_non_exhaustive",
|
||
"id_span": {
|
||
"path": "src/manual_non_exhaustive.rs",
|
||
"line": 59
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual implementations of the non-exhaustive pattern.\n\n### Why is this bad?\nUsing the #[non_exhaustive] attribute expresses better the intent\nand allows possible optimizations when applied to enums.\n\n### Example\n```rust\nstruct S {\n pub a: i32,\n pub b: i32,\n _c: (),\n}\n\nenum E {\n A,\n B,\n #[doc(hidden)]\n _C,\n}\n\nstruct T(pub i32, pub i32, ());\n```\nUse instead:\n```rust\n#[non_exhaustive]\nstruct S {\n pub a: i32,\n pub b: i32,\n}\n\n#[non_exhaustive]\nenum E {\n A,\n B,\n}\n\n#[non_exhaustive]\nstruct T(pub i32, pub i32);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_ok_or",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2647
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nFinds patterns that reimplement `Option::ok_or`.\n\n### Why is this bad?\n\nConcise code helps focusing on behavior instead of boilerplate.\n\n### Examples\n```rust\nlet foo: Option<i32> = None;\nfoo.map_or(Err(\"error\"), |v| Ok(v));\n```\n\nUse instead:\n```rust\nlet foo: Option<i32> = None;\nfoo.ok_or(\"error\");\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_range_contains",
|
||
"id_span": {
|
||
"path": "src/ranges.rs",
|
||
"line": 157
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions like `x >= 3 && x < 8` that could\nbe more readably expressed as `(3..8).contains(x)`.\n\n### Why is this bad?\n`contains` expresses the intent better and has less\nfailure modes (such as fencepost errors or using `||` instead of `&&`).\n\n### Example\n```rust\n// given\nlet x = 6;\n\nassert!(x >= 3 && x < 8);\n```\nUse instead:\n```rust\nassert!((3..8).contains(&x));\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_range_patterns",
|
||
"id_span": {
|
||
"path": "src/manual_range_patterns.rs",
|
||
"line": 35
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for combined OR patterns that are all contained in a specific range,\ne.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`.\n\n### Why is this bad?\nUsing an explicit range is more concise and easier to read.\n\n### Known issues\nThis lint intentionally does not handle numbers greater than `i128::MAX` for `u128` literals\nin order to support negative numbers.\n\n### Example\n```rust\nlet x = 6;\nlet foo = matches!(x, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10);\n```\nUse instead:\n```rust\nlet x = 6;\nlet foo = matches!(x, 1..=10);\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_rem_euclid",
|
||
"id_span": {
|
||
"path": "src/manual_rem_euclid.rs",
|
||
"line": 31
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation\nof `x.rem_euclid(4)`.\n\n### Why is this bad?\nIt's simpler and more readable.\n\n### Example\n```rust\nlet x: i32 = 24;\nlet rem = ((x % 4) + 4) % 4;\n```\nUse instead:\n```rust\nlet x: i32 = 24;\nlet rem = x.rem_euclid(4);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_retain",
|
||
"id_span": {
|
||
"path": "src/manual_retain.rs",
|
||
"line": 52
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for code to be replaced by `.retain()`.\n### Why is this bad?\n`.retain()` is simpler and avoids needless allocation.\n### Example\n```rust\nlet mut vec = vec![0, 1, 2];\nvec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\nvec = vec.into_iter().filter(|x| x % 2 == 0).collect();\n```\nUse instead:\n```rust\nlet mut vec = vec![0, 1, 2];\nvec.retain(|x| x % 2 == 0);\nvec.retain(|x| x % 2 == 0);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_saturating_arithmetic",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1713
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`.\n\n### Why is this bad?\nThese can be written simply with `saturating_add/sub` methods.\n\n### Example\n```rust\nlet add = x.checked_add(y).unwrap_or(u32::MAX);\nlet sub = x.checked_sub(y).unwrap_or(u32::MIN);\n```\n\ncan be written using dedicated methods for saturating addition/subtraction as:\n\n```rust\nlet add = x.saturating_add(y);\nlet sub = x.saturating_sub(y);\n```",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_slice_size_calculation",
|
||
"id_span": {
|
||
"path": "src/manual_slice_size_calculation.rs",
|
||
"line": 35
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWhen `a` is `&[T]`, detect `a.len() * size_of::<T>()` and suggest `size_of_val(a)`\ninstead.\n\n### Why is this better?\n* Shorter to write\n* Removes the need for the human and the compiler to worry about overflow in the\n multiplication\n* Potentially faster at runtime as rust emits special no-wrapping flags when it\n calculates the byte length\n* Less turbofishing\n\n### Example\n```rust\nlet newlen = data.len() * std::mem::size_of::<i32>();\n```\nUse instead:\n```rust\nlet newlen = std::mem::size_of_val(data);\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_split_once",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2239
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `str::splitn(2, _)`\n\n### Why is this bad?\n`split_once` is both clearer in intent and slightly more efficient.\n\n### Example\n```rust\nlet s = \"key=value=add\";\nlet (key, value) = s.splitn(2, '=').next_tuple()?;\nlet value = s.splitn(2, '=').nth(1)?;\n\nlet mut parts = s.splitn(2, '=');\nlet key = parts.next()?;\nlet value = parts.next()?;\n```\n\nUse instead:\n```rust\nlet s = \"key=value=add\";\nlet (key, value) = s.split_once('=')?;\nlet value = s.split_once('=')?.1;\n\nlet (key, value) = s.split_once('=')?;\n```\n\n### Limitations\nThe multiple statement variant currently only detects `iter.next()?`/`iter.next().unwrap()`\nin two separate `let` statements that immediately follow the `splitn()`\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_str_repeat",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2203
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual implementations of `str::repeat`\n\n### Why is this bad?\nThese are both harder to read, as well as less performant.\n\n### Example\n```rust\nlet x: String = std::iter::repeat('x').take(10).collect();\n```\n\nUse instead:\n```rust\nlet x: String = \"x\".repeat(10);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_string_new",
|
||
"id_span": {
|
||
"path": "src/manual_string_new.rs",
|
||
"line": 32
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nChecks for usage of `\"\"` to create a `String`, such as `\"\".to_string()`, `\"\".to_owned()`,\n`String::from(\"\")` and others.\n\n### Why is this bad?\n\nDifferent ways of creating an empty string makes your code less standardized, which can\nbe confusing.\n\n### Example\n```rust\nlet a = \"\".to_string();\nlet b: String = \"\".into();\n```\nUse instead:\n```rust\nlet a = String::new();\nlet b = String::new();\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_strip",
|
||
"id_span": {
|
||
"path": "src/manual_strip.rs",
|
||
"line": 43
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSuggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length.\n\n### Why is this bad?\nUsing `str:strip_{prefix,suffix}` is safer and may have better performance as there is no\nslicing which may panic and the compiler does not need to insert this panic code. It is\nalso sometimes more readable as it removes the need for duplicating or storing the pattern\nused by `str::{starts,ends}_with` and in the slicing.\n\n### Example\n```rust\nlet s = \"hello, world!\";\nif s.starts_with(\"hello, \") {\n assert_eq!(s[\"hello, \".len()..].to_uppercase(), \"WORLD!\");\n}\n```\nUse instead:\n```rust\nlet s = \"hello, world!\";\nif let Some(end) = s.strip_prefix(\"hello, \") {\n assert_eq!(end.to_uppercase(), \"WORLD!\");\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_swap",
|
||
"id_span": {
|
||
"path": "src/swap.rs",
|
||
"line": 48
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual swapping.\n\nNote that the lint will not be emitted in const blocks, as the suggestion would not be applicable.\n\n### Why is this bad?\nThe `std::mem::swap` function exposes the intent better\nwithout deinitializing or copying either variable.\n\n### Example\n```rust\nlet mut a = 42;\nlet mut b = 1337;\n\nlet t = b;\nb = a;\na = t;\n```\nUse std::mem::swap():\n```rust\nlet mut a = 1;\nlet mut b = 2;\nstd::mem::swap(&mut a, &mut b);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_try_fold",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3429
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `Iterator::fold` with a type that implements `Try`.\n\n### Why is this bad?\nThe code should use `try_fold` instead, which short-circuits on failure, thus opening the\ndoor for additional optimizations not possible with `fold` as rustc can guarantee the\nfunction is never called on `None`, `Err`, etc., alleviating otherwise necessary checks. It's\nalso slightly more idiomatic.\n\n### Known issues\nThis lint doesn't take into account whether a function does something on the failure case,\ni.e., whether short-circuiting will affect behavior. Refactoring to `try_fold` is not\ndesirable in those cases.\n\n### Example\n```rust\nvec![1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i));\n```\nUse instead:\n```rust\nvec![1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i));\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_unwrap_or",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 722
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nFinds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`.\n\n### Why is this bad?\nConcise code helps focusing on behavior instead of boilerplate.\n\n### Example\n```rust\nlet foo: Option<i32> = None;\nmatch foo {\n Some(v) => v,\n None => 1,\n};\n```\n\nUse instead:\n```rust\nlet foo: Option<i32> = None;\nfoo.unwrap_or(1);\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_unwrap_or_default",
|
||
"id_span": {
|
||
"path": "src/manual_unwrap_or_default.rs",
|
||
"line": 47
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if a `match` or `if let` expression can be simplified using\n`.unwrap_or_default()`.\n\n### Why is this bad?\nIt can be done in one call with `.unwrap_or_default()`.\n\n### Example\n```rust\nlet x: Option<String> = Some(String::new());\nlet y: String = match x {\n Some(v) => v,\n None => String::new(),\n};\n\nlet x: Option<Vec<String>> = Some(Vec::new());\nlet y: Vec<String> = if let Some(v) = x {\n v\n} else {\n Vec::new()\n};\n```\nUse instead:\n```rust\nlet x: Option<String> = Some(String::new());\nlet y: String = x.unwrap_or_default();\n\nlet x: Option<Vec<String>> = Some(Vec::new());\nlet y: Vec<String> = x.unwrap_or_default();\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "manual_while_let_some",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 634
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for loops that check for emptiness of a `Vec` in the condition and pop an element\nin the body as a separate operation.\n\n### Why is this bad?\nSuch loops can be written in a more idiomatic way by using a while-let loop and directly\npattern matching on the return value of `Vec::pop()`.\n\n### Example\n```rust\nlet mut numbers = vec![1, 2, 3, 4, 5];\nwhile !numbers.is_empty() {\n let number = numbers.pop().unwrap();\n // use `number`\n}\n```\nUse instead:\n```rust\nlet mut numbers = vec![1, 2, 3, 4, 5];\nwhile let Some(number) = numbers.pop() {\n // use `number`\n}\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "many_single_char_names",
|
||
"id_span": {
|
||
"path": "src/non_expressive_names.rs",
|
||
"line": 50
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for too many variables whose name consists of a\nsingle character.\n\n### Why is this bad?\nIt's hard to memorize what a variable means without a\ndescriptive name.\n\n### Example\n```rust\nlet (a, b, c, d, e, f, g) = (...);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `single-char-binding-names-threshold`: The maximum number of single char bindings a scope may have (default: `4`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_clone",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2676
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `map(|x| x.clone())` or\ndereferencing closures for `Copy` types, on `Iterator` or `Option`,\nand suggests `cloned()` or `copied()` instead\n\n### Why is this bad?\nReadability, this can be written more concisely\n\n### Example\n```rust\nlet x = vec![42, 43];\nlet y = x.iter();\nlet z = y.map(|i| *i);\n```\n\nThe correct use would be:\n\n```rust\nlet x = vec![42, 43];\nlet y = x.iter();\nlet z = y.cloned();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_collect_result_unit",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1914
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.map(_).collect::<Result<(), _>()`.\n\n### Why is this bad?\nUsing `try_for_each` instead is more readable and idiomatic.\n\n### Example\n```rust\n(0..3).map(|t| Err(t)).collect::<Result<(), _>>();\n```\nUse instead:\n```rust\n(0..3).try_for_each(|t| Err(t));\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_entry",
|
||
"id_span": {
|
||
"path": "src/entry.rs",
|
||
"line": 54
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `contains_key` + `insert` on `HashMap`\nor `BTreeMap`.\n\n### Why is this bad?\nUsing `entry` is more efficient.\n\n### Known problems\nThe suggestion may have type inference errors in some cases. e.g.\n```rust\nlet mut map = std::collections::HashMap::new();\nlet _ = if !map.contains_key(&0) {\n map.insert(0, 0)\n} else {\n None\n};\n```\n\n### Example\n```rust\nif !map.contains_key(&k) {\n map.insert(k, v);\n}\n```\nUse instead:\n```rust\nmap.entry(k).or_insert(v);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_err_ignore",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2776
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for instances of `map_err(|_| Some::Enum)`\n\n### Why is this bad?\nThis `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error\n\n### Example\nBefore:\n```rust\nuse std::fmt;\n\n#[derive(Debug)]\nenum Error {\n Indivisible,\n Remainder(u8),\n}\n\nimpl fmt::Display for Error {\n fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n match self {\n Error::Indivisible => write!(f, \"could not divide input by three\"),\n Error::Remainder(remainder) => write!(\n f,\n \"input is not divisible by three, remainder = {}\",\n remainder\n ),\n }\n }\n}\n\nimpl std::error::Error for Error {}\n\nfn divisible_by_3(input: &str) -> Result<(), Error> {\n input\n .parse::<i32>()\n .map_err(|_| Error::Indivisible)\n .map(|v| v % 3)\n .and_then(|remainder| {\n if remainder == 0 {\n Ok(())\n } else {\n Err(Error::Remainder(remainder as u8))\n }\n })\n}\n ```\n\n After:\n```rust\nuse std::{fmt, num::ParseIntError};\n\n#[derive(Debug)]\nenum Error {\n Indivisible(ParseIntError),\n Remainder(u8),\n}\n\nimpl fmt::Display for Error {\n fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n match self {\n Error::Indivisible(_) => write!(f, \"could not divide input by three\"),\n Error::Remainder(remainder) => write!(\n f,\n \"input is not divisible by three, remainder = {}\",\n remainder\n ),\n }\n }\n}\n\nimpl std::error::Error for Error {\n fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n match self {\n Error::Indivisible(source) => Some(source),\n _ => None,\n }\n }\n}\n\nfn divisible_by_3(input: &str) -> Result<(), Error> {\n input\n .parse::<i32>()\n .map_err(Error::Indivisible)\n .map(|v| v % 3)\n .and_then(|remainder| {\n if remainder == 0 {\n Ok(())\n } else {\n Err(Error::Remainder(remainder as u8))\n }\n })\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_flatten",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 734
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.flat_map(_)` for `Iterator` or `_.and_then(_)` for `Option`\n\n### Example\n```rust\nlet vec = vec![vec![1]];\nlet opt = Some(5);\n\nvec.iter().map(|x| x.iter()).flatten();\nopt.map(|x| Some(x * 2)).flatten();\n```\n\nUse instead:\n```rust\nvec.iter().flat_map(|x| x.iter());\nopt.and_then(|x| Some(x * 2));\n```",
|
||
"version": "1.31.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_identity",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2021
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for instances of `map(f)` where `f` is the identity function.\n\n### Why is this bad?\nIt can be written more concisely without the call to `map`.\n\n### Example\n```rust\nlet x = [1, 2, 3];\nlet y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();\n```\nUse instead:\n```rust\nlet x = [1, 2, 3];\nlet y: Vec<_> = x.iter().map(|x| 2*x).collect();\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "map_unwrap_or",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 568
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or\n`result.map(_).unwrap_or_else(_)`.\n\n### Why is this bad?\nReadability, these can be written more concisely (resp.) as\n`option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`.\n\n### Known problems\nThe order of the arguments is not in execution order\n\n### Examples\n```rust\noption.map(|a| a + 1).unwrap_or(0);\noption.map(|a| a > 10).unwrap_or(false);\nresult.map(|a| a + 1).unwrap_or_else(some_function);\n```\n\nUse instead:\n```rust\noption.map_or(0, |a| a + 1);\noption.is_some_and(|a| a > 10);\nresult.map_or_else(some_function, |a| a + 1);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n### Past names\n\n* `option_map_unwrap_or`\n* `option_map_unwrap_or_else`\n* `result_map_unwrap_or_else`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"option_map_unwrap_or",
|
||
"option_map_unwrap_or_else",
|
||
"result_map_unwrap_or_else"
|
||
]
|
||
},
|
||
{
|
||
"id": "match_as_ref",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 254
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for match which is used to add a reference to an\n`Option` value.\n\n### Why is this bad?\nUsing `as_ref()` or `as_mut()` instead is shorter.\n\n### Example\n```rust\nlet x: Option<()> = None;\n\nlet r: Option<&()> = match x {\n None => None,\n Some(ref v) => Some(v),\n};\n```\n\nUse instead:\n```rust\nlet x: Option<()> = None;\n\nlet r: Option<&()> = x.as_ref();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_bool",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 178
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for matches where match expression is a `bool`. It\nsuggests to replace the expression with an `if...else` block.\n\n### Why is this bad?\nIt makes the code less readable.\n\n### Example\n```rust\nlet condition: bool = true;\nmatch condition {\n true => foo(),\n false => bar(),\n}\n```\nUse if/else instead:\n```rust\nlet condition: bool = true;\nif condition {\n foo();\n} else {\n bar();\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_like_matches_macro",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 566
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `match` or `if let` expressions producing a\n`bool` that could be written using `matches!`\n\n### Why is this bad?\nReadability and needless complexity.\n\n### Known problems\nThis lint falsely triggers, if there are arms with\n`cfg` attributes that remove an arm evaluating to `false`.\n\n### Example\n```rust\nlet x = Some(5);\n\nlet a = match x {\n Some(0) => true,\n _ => false,\n};\n\nlet a = if let Some(0) = x {\n true\n} else {\n false\n};\n```\n\nUse instead:\n```rust\nlet x = Some(5);\nlet a = matches!(x, Some(0));\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_on_vec_items",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 758
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `match vec[idx]` or `match vec[n..m]`.\n\n### Why is this bad?\nThis can panic at runtime.\n\n### Example\n```rust\nlet arr = vec![0, 1, 2, 3];\nlet idx = 1;\n\nmatch arr[idx] {\n 0 => println!(\"{}\", 0),\n 1 => println!(\"{}\", 3),\n _ => {},\n}\n```\n\nUse instead:\n```rust\nlet arr = vec![0, 1, 2, 3];\nlet idx = 1;\n\nmatch arr.get(idx) {\n Some(0) => println!(\"{}\", 0),\n Some(1) => println!(\"{}\", 3),\n _ => {},\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_overlapping_arm",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 201
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for overlapping match arms.\n\n### Why is this bad?\nIt is likely to be an error and if not, makes the code\nless obvious.\n\n### Example\n```rust\nlet x = 5;\nmatch x {\n 1..=10 => println!(\"1 ... 10\"),\n 5..=15 => println!(\"5 ... 15\"),\n _ => (),\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_ref_pats",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 143
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for matches where all arms match a reference,\nsuggesting to remove the reference and deref the matched expression\ninstead. It also checks for `if let &foo = bar` blocks.\n\n### Why is this bad?\nIt just makes the code less readable. That reference\ndestructuring adds nothing to the code.\n\n### Example\n```rust\nmatch x {\n &A(ref y) => foo(y),\n &B => bar(),\n _ => frob(&x),\n}\n```\n\nUse instead:\n```rust\nmatch *x {\n A(ref y) => foo(y),\n B => bar(),\n _ => frob(x),\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_result_ok",
|
||
"id_span": {
|
||
"path": "src/match_result_ok.rs",
|
||
"line": 40
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary `ok()` in `while let`.\n\n### Why is this bad?\nCalling `ok()` in `while let` is unnecessary, instead match\non `Ok(pat)`\n\n### Example\n```rust\nwhile let Some(value) = iter.next().ok() {\n vec.push(value)\n}\n\nif let Some(value) = iter.next().ok() {\n vec.push(value)\n}\n```\nUse instead:\n```rust\nwhile let Ok(value) = iter.next() {\n vec.push(value)\n}\n\nif let Ok(value) = iter.next() {\n vec.push(value)\n}\n```\n### Past names\n\n* `if_let_some_result`\n\n",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"if_let_some_result"
|
||
]
|
||
},
|
||
{
|
||
"id": "match_same_arms",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 614
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `match` with identical arm bodies.\n\nNote: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is\nenabled and disallowed.\n\n### Why is this bad?\nThis is probably a copy & paste error. If arm bodies\nare the same on purpose, you can factor them\n[using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).\n\n### Known problems\nFalse positive possible with order dependent `match`\n(see issue\n[#860](https://github.com/rust-lang/rust-clippy/issues/860)).\n\n### Example\n```rust\nmatch foo {\n Bar => bar(),\n Quz => quz(),\n Baz => bar(), // <= oops\n}\n```\n\nThis should probably be\n```rust\nmatch foo {\n Bar => bar(),\n Quz => quz(),\n Baz => baz(), // <= fixed\n}\n```\n\nor if the original code was not a typo:\n```rust\nmatch foo {\n Bar | Baz => bar(), // <= shows the intent better\n Quz => quz(),\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_single_binding",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 429
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for useless match that binds to only one value.\n\n### Why is this bad?\nReadability and needless complexity.\n\n### Known problems\n Suggested replacements may be incorrect when `match`\nis actually binding temporary value, bringing a 'dropped while borrowed' error.\n\n### Example\n```rust\nmatch (a, b) {\n (c, d) => {\n // useless match\n }\n}\n```\n\nUse instead:\n```rust\nlet (c, d) = (a, b);\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_str_case_mismatch",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 789
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `match` expressions modifying the case of a string with non-compliant arms\n\n### Why is this bad?\nThe arm is unreachable, which is likely a mistake\n\n### Example\n```rust\nmatch &*text.to_ascii_lowercase() {\n \"foo\" => {},\n \"Bar\" => {},\n _ => {},\n}\n```\nUse instead:\n```rust\nmatch &*text.to_ascii_lowercase() {\n \"foo\" => {},\n \"bar\" => {},\n _ => {},\n}\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_wild_err_arm",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 224
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for arm which matches all errors with `Err(_)`\nand take drastic actions like `panic!`.\n\n### Why is this bad?\nIt is generally a bad practice, similar to\ncatching all exceptions in java with `catch(Exception)`\n\n### Example\n```rust\nlet x: Result<i32, &str> = Ok(3);\nmatch x {\n Ok(_) => println!(\"ok\"),\n Err(_) => panic!(\"err\"),\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "match_wildcard_for_single_variants",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 328
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for wildcard enum matches for a single variant.\n\n### Why is this bad?\nNew enum variants added by library updates can be missed.\n\n### Known problems\nSuggested replacements may not use correct path to enum\nif it's not present in the current scope.\n\n### Example\n```rust\nmatch x {\n Foo::A => {},\n Foo::B => {},\n _ => {},\n}\n```\n\nUse instead:\n```rust\nmatch x {\n Foo::A => {},\n Foo::B => {},\n Foo::C => {},\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "maybe_infinite_iter",
|
||
"id_span": {
|
||
"path": "src/infinite_iter.rs",
|
||
"line": 48
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for iteration that may be infinite.\n\n### Why is this bad?\nWhile there may be places where this is acceptable\n(e.g., in event streams), in most cases this is simply an error.\n\n### Known problems\nThe code may have a condition to stop iteration, but\nthis lint is not clever enough to analyze it.\n\n### Example\n```rust\nlet infinite_iter = 0..;\n[0..].iter().zip(infinite_iter.take_while(|x| *x > 5));\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "maybe_misused_cfg",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 411
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `#[cfg(features = \"...\")]` and suggests to replace it with\n`#[cfg(feature = \"...\")]`.\n\nIt also checks if `cfg(test)` was misspelled.\n\n### Why is this bad?\nMisspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It\nmay cause conditional compilation not work quietly.\n\n### Example\n```rust\n#[cfg(features = \"some-feature\")]\nfn conditional() { }\n#[cfg(tests)]\nmod tests { }\n```\n\nUse instead:\n```rust\n#[cfg(feature = \"some-feature\")]\nfn conditional() { }\n#[cfg(test)]\nmod tests { }\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "mem_forget",
|
||
"id_span": {
|
||
"path": "src/drop_forget_ref.rs",
|
||
"line": 66
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `std::mem::forget(t)` where `t` is\n`Drop` or has a field that implements `Drop`.\n\n### Why is this bad?\n`std::mem::forget(t)` prevents `t` from running its\ndestructor, possibly causing leaks.\n\n### Example\n```rust\nmem::forget(Rc::new(55))\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mem_replace_option_with_none",
|
||
"id_span": {
|
||
"path": "src/mem_replace.rs",
|
||
"line": 41
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `mem::replace()` on an `Option` with\n`None`.\n\n### Why is this bad?\n`Option` already has the method `take()` for\ntaking its current value (Some(..) or None) and replacing it with\n`None`.\n\n### Example\n```rust\nuse std::mem;\n\nlet mut an_option = Some(0);\nlet replaced = mem::replace(&mut an_option, None);\n```\nIs better expressed with:\n```rust\nlet mut an_option = Some(0);\nlet taken = an_option.take();\n```",
|
||
"version": "1.31.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "mem_replace_with_default",
|
||
"id_span": {
|
||
"path": "src/mem_replace.rs",
|
||
"line": 98
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `std::mem::replace` on a value of type\n`T` with `T::default()`.\n\n### Why is this bad?\n`std::mem` module already has the method `take` to\ntake the current value and replace it with the default value of that type.\n\n### Example\n```rust\nlet mut text = String::from(\"foo\");\nlet replaced = std::mem::replace(&mut text, String::default());\n```\nIs better expressed with:\n```rust\nlet mut text = String::from(\"foo\");\nlet taken = std::mem::take(&mut text);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "mem_replace_with_uninit",
|
||
"id_span": {
|
||
"path": "src/mem_replace.rs",
|
||
"line": 73
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `mem::replace(&mut _, mem::uninitialized())`\nand `mem::replace(&mut _, mem::zeroed())`.\n\n### Why is this bad?\nThis will lead to undefined behavior even if the\nvalue is overwritten later, because the uninitialized value may be\nobserved in the case of a panic.\n\n### Example\n```rust\nuse std::mem;\n\n#[allow(deprecated, invalid_value)]\nfn myfunc (v: &mut Vec<i32>) {\n let taken_v = unsafe { mem::replace(v, mem::uninitialized()) };\n let new_v = may_panic(taken_v); // undefined behavior on panic\n mem::forget(mem::replace(v, new_v));\n}\n```\n\nThe [take_mut](https://docs.rs/take_mut) crate offers a sound solution,\nat the cost of either lazily creating a replacement value or aborting\non panic, to ensure that the uninitialized value cannot be observed.",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "min_ident_chars",
|
||
"id_span": {
|
||
"path": "src/min_ident_chars.rs",
|
||
"line": 37
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for idents which comprise of a single letter.\n\nNote: This lint can be very noisy when enabled; it may be desirable to only enable it\ntemporarily.\n\n### Why is this bad?\nIn many cases it's not, but at times it can severely hinder readability. Some codebases may\nwish to disallow this to improve readability.\n\n### Example\n```rust\nfor m in movies {\n let title = m.t;\n}\n```\nUse instead:\n```rust\nfor movie in movies {\n let title = movie.title;\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-idents-below-min-chars`: Allowed names below the minimum allowed characters. The value `\"..\"` can be used as part of\n the list to indicate, that the configured values should be appended to the default\n configuration of Clippy. By default, any configuration will replace the default value. (default: `[\"j\", \"z\", \"i\", \"y\", \"n\", \"x\", \"w\"]`)- `min-ident-chars-threshold`: Minimum chars an ident can have, anything below or equal to this will be linted. (default: `1`)",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "min_max",
|
||
"id_span": {
|
||
"path": "src/minmax.rs",
|
||
"line": 30
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for expressions where `std::cmp::min` and `max` are\nused to clamp values, but switched so that the result is constant.\n\n### Why is this bad?\nThis is in all probability not the intended outcome. At\nthe least it hurts readability of the code.\n\n### Example\n```rust\nmin(0, max(100, x))\n\n// or\n\nx.max(100).min(0)\n```\nIt will always be equal to `0`. Probably the author meant to clamp the value\nbetween 0 and 100, but has erroneously swapped `min` and `max`.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "misaligned_transmute",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 94
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint should never have applied to non-pointer types, as transmuting\nbetween non-pointer types of differing alignment is well-defined behavior (it's semantically\nequivalent to a memcpy). This lint has thus been refactored into two separate lints:\ncast_ptr_alignment and transmute_ptr_to_ptr.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mismatched_target_os",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 291
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for cfg attributes having operating systems used in target family position.\n\n### Why is this bad?\nThe configuration option will not be recognised and the related item will not be included\nby the conditional compilation engine.\n\n### Example\n```rust\n#[cfg(linux)]\nfn conditional() { }\n```\n\nUse instead:\n```rust\n#[cfg(target_os = \"linux\")]\nfn conditional() { }\n\n// or\n\n#[cfg(unix)]\nfn conditional() { }\n```\nCheck the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "mismatching_type_param_order",
|
||
"id_span": {
|
||
"path": "src/mismatching_type_param_order.rs",
|
||
"line": 44
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for type parameters which are positioned inconsistently between\na type definition and impl block. Specifically, a parameter in an impl\nblock which has the same name as a parameter in the type def, but is in\na different place.\n\n### Why is this bad?\nType parameters are determined by their position rather than name.\nNaming type parameters inconsistently may cause you to refer to the\nwrong type parameter.\n\n### Limitations\nThis lint only applies to impl blocks with simple generic params, e.g.\n`A`. If there is anything more complicated, such as a tuple, it will be\nignored.\n\n### Example\n```rust\nstruct Foo<A, B> {\n x: A,\n y: B,\n}\n// inside the impl, B refers to Foo::A\nimpl<B, A> Foo<B, A> {}\n```\nUse instead:\n```rust\nstruct Foo<A, B> {\n x: A,\n y: B,\n}\nimpl<A, B> Foo<A, B> {}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "misnamed_getters",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 331
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for getter methods that return a field that doesn't correspond\nto the name of the method, when there is a field's whose name matches that of the method.\n\n### Why is this bad?\nIt is most likely that such a method is a bug caused by a typo or by copy-pasting.\n\n### Example\n```rust\nstruct A {\n a: String,\n b: String,\n}\n\nimpl A {\n fn a(&self) -> &str{\n &self.b\n }\n}\n```\nUse instead:\n```rust\nstruct A {\n a: String,\n b: String,\n}\n\nimpl A {\n fn a(&self) -> &str{\n &self.a\n }\n}\n```",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "misrefactored_assign_op",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 175
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `a op= a op b` or `a op= b op a` patterns.\n\n### Why is this bad?\nMost likely these are bugs where one meant to write `a\nop= b`.\n\n### Known problems\nClippy cannot know for sure if `a op= a op b` should have\nbeen `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.\nIf `a op= a op b` is really the correct behavior it should be\nwritten as `a = a op a op b` as it's less confusing.\n\n### Example\n```rust\nlet mut a = 5;\nlet b = 2;\n// ...\na += a + b;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_assert_message",
|
||
"id_span": {
|
||
"path": "src/missing_assert_message.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks assertions without a custom panic message.\n\n### Why is this bad?\nWithout a good custom message, it'd be hard to understand what went wrong when the assertion fails.\nA good custom message should be more about why the failure of the assertion is problematic\nand not what is failed because the assertion already conveys that.\n\nAlthough the same reasoning applies to testing functions, this lint ignores them as they would be too noisy.\nAlso, in most cases understanding the test failure would be easier\ncompared to understanding a complex invariant distributed around the codebase.\n\n### Known problems\nThis lint cannot check the quality of the custom panic messages.\nHence, you can suppress this lint simply by adding placeholder messages\nlike \"assertion failed\". However, we recommend coming up with good messages\nthat provide useful information instead of placeholder messages that\ndon't provide any extra information.\n\n### Example\n```rust\nfn call(service: Service) {\n assert!(service.ready);\n}\n```\nUse instead:\n```rust\nfn call(service: Service) {\n assert!(service.ready, \"`service.poll_ready()` must be called first to ensure that service is ready to receive requests\");\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_asserts_for_indexing",
|
||
"id_span": {
|
||
"path": "src/missing_asserts_for_indexing.rs",
|
||
"line": 62
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for repeated slice indexing without asserting beforehand that the length\nis greater than the largest index used to index into the slice.\n\n### Why is this bad?\nIn the general case where the compiler does not have a lot of information\nabout the length of a slice, indexing it repeatedly will generate a bounds check\nfor every single index.\n\nAsserting that the length of the slice is at least as large as the largest value\nto index beforehand gives the compiler enough information to elide the bounds checks,\neffectively reducing the number of bounds checks from however many times\nthe slice was indexed to just one (the assert).\n\n### Drawbacks\nFalse positives. It is, in general, very difficult to predict how well\nthe optimizer will be able to elide bounds checks and it very much depends on\nthe surrounding code. For example, indexing into the slice yielded by the\n[`slice::chunks_exact`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.chunks_exact)\niterator will likely have all of the bounds checks elided even without an assert\nif the `chunk_size` is a constant.\n\nAsserts are not tracked across function calls. Asserting the length of a slice\nin a different function likely gives the optimizer enough information\nabout the length of a slice, but this lint will not detect that.\n\n### Example\n```rust\nfn sum(v: &[u8]) -> u8 {\n // 4 bounds checks\n v[0] + v[1] + v[2] + v[3]\n}\n```\nUse instead:\n```rust\nfn sum(v: &[u8]) -> u8 {\n assert!(v.len() > 3);\n // no bounds checks\n v[0] + v[1] + v[2] + v[3]\n}\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_const_for_fn",
|
||
"id_span": {
|
||
"path": "src/missing_const_for_fn.rs",
|
||
"line": 69
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nSuggests the use of `const` in functions and methods where possible.\n\n### Why is this bad?\nNot having the function const prevents callers of the function from being const as well.\n\n### Known problems\nConst functions are currently still being worked on, with some features only being available\non nightly. This lint does not consider all edge cases currently and the suggestions may be\nincorrect if you are using this lint on stable.\n\nAlso, the lint only runs one pass over the code. Consider these two non-const functions:\n\n```rust\nfn a() -> i32 {\n 0\n}\nfn b() -> i32 {\n a()\n}\n```\n\nWhen running Clippy, the lint will only suggest to make `a` const, because `b` at this time\ncan't be const as it calls a non-const function. Making `a` const and running Clippy again,\nwill suggest to make `b` const, too.\n\nIf you are marking a public function with `const`, removing it again will break API compatibility.\n### Example\n```rust\nfn new() -> Self {\n Self { random_number: 42 }\n}\n```\n\nCould be a const fn:\n\n```rust\nconst fn new() -> Self {\n Self { random_number: 42 }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.34.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_docs_in_private_items",
|
||
"id_span": {
|
||
"path": "src/missing_doc.rs",
|
||
"line": 31
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if there is missing doc for any private documentable item\n\n### Why is this bad?\nDoc is good. *rustc* has a `MISSING_DOCS`\nallowed-by-default lint for\npublic members, but has no way to enforce documentation of private items.\nThis lint fixes that.\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `missing-docs-in-crate-items`: Whether to **only** check for missing documentation in items visible within the current\n crate. For example, `pub(crate)` items. (default: `false`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_enforced_import_renames",
|
||
"id_span": {
|
||
"path": "src/missing_enforced_import_rename.rs",
|
||
"line": 43
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for imports that do not rename the item as specified\nin the `enforced-import-renames` config option.\n\nNote: Even though this lint is warn-by-default, it will only trigger if\nimport renames are defined in the `clippy.toml` file.\n\n### Why is this bad?\nConsistency is important; if a project has defined import renames, then they should be\nfollowed. More practically, some item names are too vague outside of their defining scope,\nin which case this can enforce a more meaningful naming.\n\n### Example\nAn example clippy.toml configuration:\n```toml\n# clippy.toml\nenforced-import-renames = [\n { path = \"serde_json::Value\", rename = \"JsonValue\" },\n]\n```\n\n```rust\nuse serde_json::Value;\n```\nUse instead:\n```rust\nuse serde_json::Value as JsonValue;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `enforced-import-renames`: The list of imports to always rename, a fully qualified path followed by the rename. (default: `[]`)",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_errors_doc",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 137
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks the doc comments of publicly visible functions that\nreturn a `Result` type and warns if there is no `# Errors` section.\n\n### Why is this bad?\nDocumenting the type of errors that can be returned from a\nfunction can help callers write code to handle the errors appropriately.\n\n### Examples\nSince the following function returns a `Result` it has an `# Errors` section in\nits doc comment:\n\n```rust\n/// # Errors\n///\n/// Will return `Err` if `filename` does not exist or the user does not have\n/// permission to read it.\npub fn read(filename: String) -> io::Result<String> {\n unimplemented!();\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `check-private-items`: Whether to also run the listed lints on private items. (default: `false`)",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_fields_in_debug",
|
||
"id_span": {
|
||
"path": "src/missing_fields_in_debug.rs",
|
||
"line": 77
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields.\n\n### Why is this bad?\nA common mistake is to forget to update manual `Debug` implementations when adding a new field\nto a struct or a new variant to an enum.\n\nAt the same time, it also acts as a style lint to suggest using [`core::fmt::DebugStruct::finish_non_exhaustive`](https://doc.rust-lang.org/core/fmt/struct.DebugStruct.html#method.finish_non_exhaustive)\nfor the times when the user intentionally wants to leave out certain fields (e.g. to hide implementation details).\n\n### Known problems\nThis lint works based on the `DebugStruct` helper types provided by the `Formatter`,\nso this won't detect `Debug` impls that use the `write!` macro.\nOftentimes there is more logic to a `Debug` impl if it uses `write!` macro, so it tries\nto be on the conservative side and not lint in those cases in an attempt to prevent false positives.\n\nThis lint also does not look through function calls, so calling a function does not consider fields\nused inside of that function as used by the `Debug` impl.\n\nLastly, it also ignores tuple structs as their `DebugTuple` formatter does not have a `finish_non_exhaustive`\nmethod, as well as enums because their exhaustiveness is already checked by the compiler when matching on the enum,\nmaking it much less likely to accidentally forget to update the `Debug` impl when adding a new variant.\n\n### Example\n```rust\nuse std::fmt;\nstruct Foo {\n data: String,\n // implementation detail\n hidden_data: i32\n}\nimpl fmt::Debug for Foo {\n fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n formatter\n .debug_struct(\"Foo\")\n .field(\"data\", &self.data)\n .finish()\n }\n}\n```\nUse instead:\n```rust\nuse std::fmt;\nstruct Foo {\n data: String,\n // implementation detail\n hidden_data: i32\n}\nimpl fmt::Debug for Foo {\n fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n formatter\n .debug_struct(\"Foo\")\n .field(\"data\", &self.data)\n .finish_non_exhaustive()\n }\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_inline_in_public_items",
|
||
"id_span": {
|
||
"path": "src/missing_inline.rs",
|
||
"line": 55
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nIt lints if an exported function, method, trait method with default impl,\nor trait method impl is not `#[inline]`.\n\n### Why is this bad?\nIn general, it is not. Functions can be inlined across\ncrates when that's profitable as long as any form of LTO is used. When LTO is disabled,\nfunctions that are not `#[inline]` cannot be inlined across crates. Certain types of crates\nmight intend for most of the methods in their public API to be able to be inlined across\ncrates even when LTO is disabled. For these types of crates, enabling this lint might make\nsense. It allows the crate to require all exported methods to be `#[inline]` by default, and\nthen opt out for specific methods where this might not make sense.\n\n### Example\n```rust\npub fn foo() {} // missing #[inline]\nfn ok() {} // ok\n#[inline] pub fn bar() {} // ok\n#[inline(always)] pub fn baz() {} // ok\n\npub trait Bar {\n fn bar(); // ok\n fn def_bar() {} // missing #[inline]\n}\n\nstruct Baz;\nimpl Baz {\n fn private() {} // ok\n}\n\nimpl Bar for Baz {\n fn bar() {} // ok - Baz is not exported\n}\n\npub struct PubBaz;\nimpl PubBaz {\n fn private() {} // ok\n pub fn not_private() {} // missing #[inline]\n}\n\nimpl Bar for PubBaz {\n fn bar() {} // missing #[inline]\n fn def_bar() {} // missing #[inline]\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_panics_doc",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 168
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks the doc comments of publicly visible functions that\nmay panic and warns if there is no `# Panics` section.\n\n### Why is this bad?\nDocumenting the scenarios in which panicking occurs\ncan help callers who do not want to panic to avoid those situations.\n\n### Examples\nSince the following function may panic it has a `# Panics` section in\nits doc comment:\n\n```rust\n/// # Panics\n///\n/// Will panic if y is 0\npub fn divide_by(x: i32, y: i32) -> i32 {\n if y == 0 {\n panic!(\"Cannot divide by 0\")\n } else {\n x / y\n }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `check-private-items`: Whether to also run the listed lints on private items. (default: `false`)",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_safety_doc",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 108
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the doc comments of publicly visible\nunsafe functions and warns if there is no `# Safety` section.\n\n### Why is this bad?\nUnsafe functions should document their safety\npreconditions, so that users can be sure they are using them safely.\n\n### Examples\n```rust\n/// This function should really be documented\npub unsafe fn start_apocalypse(u: &mut Universe) {\n unimplemented!();\n}\n```\n\nAt least write a line about safety:\n\n```rust\n/// # Safety\n///\n/// This function should not be called before the horsemen are ready.\npub unsafe fn start_apocalypse(u: &mut Universe) {\n unimplemented!();\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `check-private-items`: Whether to also run the listed lints on private items. (default: `false`)",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_spin_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 546
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for empty spin loops\n\n### Why is this bad?\nThe loop body should have something like `thread::park()` or at least\n`std::hint::spin_loop()` to avoid needlessly burning cycles and conserve\nenergy. Perhaps even better use an actual lock, if possible.\n\n### Known problems\nThis lint doesn't currently trigger on `while let` or\n`loop { match .. { .. } }` loops, which would be considered idiomatic in\ncombination with e.g. `AtomicBool::compare_exchange_weak`.\n\n### Example\n\n```rust\nuse core::sync::atomic::{AtomicBool, Ordering};\nlet b = AtomicBool::new(true);\n// give a ref to `b` to another thread,wait for it to become false\nwhile b.load(Ordering::Acquire) {};\n```\nUse instead:\n```rust\nwhile b.load(Ordering::Acquire) {\n std::hint::spin_loop()\n}\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_trait_methods",
|
||
"id_span": {
|
||
"path": "src/missing_trait_methods.rs",
|
||
"line": 54
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks if a provided method is used implicitly by a trait\nimplementation. A usage example would be a wrapper where every method\nshould perform some operation before delegating to the inner type's\nimplementation.\n\nThis lint should typically be enabled on a specific trait `impl` item\nrather than globally.\n\n### Why is this bad?\nIndicates that a method is missing.\n\n### Example\n```rust\ntrait Trait {\n fn required();\n\n fn provided() {}\n}\n\n#[warn(clippy::missing_trait_methods)]\nimpl Trait for Type {\n fn required() { /* ... */ }\n}\n```\nUse instead:\n```rust\ntrait Trait {\n fn required();\n\n fn provided() {}\n}\n\n#[warn(clippy::missing_trait_methods)]\nimpl Trait for Type {\n fn required() { /* ... */ }\n\n fn provided() { /* ... */ }\n}\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "missing_transmute_annotations",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 550
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks if transmute calls have all generics specified.\n\n### Why is this bad?\nIf not set, some unexpected output type could be retrieved instead of the expected one,\npotentially leading to invalid code.\n\nThis is particularly dangerous in case a seemingly innocent/unrelated change can cause type\ninference to start inferring a different type. E.g. the transmute is the tail expression of\nan `if` branch, and a different branches type changes, causing the transmute to silently\nhave a different type, instead of a proper error.\n\n### Example\n```rust\nlet x: i32 = std::mem::transmute([1u16, 2u16]);\n```\nUse instead:\n```rust\nlet x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "mistyped_literal_suffixes",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 60
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nWarns for mistyped suffix in literals\n\n### Why is this bad?\nThis is most probably a typo\n\n### Known problems\n- Does not match on integers too large to fit in the corresponding unsigned type\n- Does not match on `_127` since that is a valid grouping for decimal and octal numbers\n\n### Example\n```rust\n`2_32` => `2_i32`\n`250_8 => `250_u8`\n```",
|
||
"version": "1.30.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "mixed_attributes_style",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 498
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for items that have the same kind of attributes with mixed styles (inner/outer).\n\n### Why is this bad?\nHaving both style of said attributes makes it more complicated to read code.\n\n### Known problems\nThis lint currently has false-negatives when mixing same attributes\nbut they have different path symbols, for example:\n```rust\n#[custom_attribute]\npub fn foo() {\n #![my_crate::custom_attribute]\n}\n```\n\n### Example\n```rust\n#[cfg(linux)]\npub fn foo() {\n #![cfg(windows)]\n}\n```\nUse instead:\n```rust\n#[cfg(linux)]\n#[cfg(windows)]\npub fn foo() {\n}\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mixed_case_hex_literals",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 129
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns on hexadecimal literals with mixed-case letter\ndigits.\n\n### Why is this bad?\nIt looks confusing.\n\n### Example\n```rust\n0x1a9BAcD\n```\n\nUse instead:\n```rust\n0x1A9BACD\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mixed_read_write_in_expression",
|
||
"id_span": {
|
||
"path": "src/mixed_read_write_in_expression.rs",
|
||
"line": 44
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for a read and a write to the same variable where\nwhether the read occurs before or after the write depends on the evaluation\norder of sub-expressions.\n\n### Why is this bad?\nIt is often confusing to read. As described [here](https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands),\nthe operands of these expressions are evaluated before applying the effects of the expression.\n\n### Known problems\nCode which intentionally depends on the evaluation\norder, or which is correct for any evaluation order.\n\n### Example\n```rust\nlet mut x = 0;\n\nlet a = {\n x = 1;\n 1\n} + x;\n// Unclear whether a is 1 or 2.\n```\n\nUse instead:\n```rust\nlet tmp = {\n x = 1;\n 1\n};\nlet a = tmp + x;\n```\n### Past names\n\n* `eval_order_dependence`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"eval_order_dependence"
|
||
]
|
||
},
|
||
{
|
||
"id": "mod_module_files",
|
||
"id_span": {
|
||
"path": "src/module_style.rs",
|
||
"line": 35
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks that module layout uses only self named module files, bans `mod.rs` files.\n\n### Why is this bad?\nHaving multiple module layout styles in a project can be confusing.\n\n### Example\n```text\nsrc/\n stuff/\n stuff_files.rs\n mod.rs\n lib.rs\n```\nUse instead:\n```text\nsrc/\n stuff/\n stuff_files.rs\n stuff.rs\n lib.rs\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "module_inception",
|
||
"id_span": {
|
||
"path": "src/item_name_repetitions.rs",
|
||
"line": 105
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for modules that have the same name as their\nparent module\n\n### Why is this bad?\nA typical beginner mistake is to have `mod foo;` and\nagain `mod foo { ..\n}` in `foo.rs`.\nThe expectation is that items inside the inner `mod foo { .. }` are then\navailable\nthrough `foo::x`, but they are only available through\n`foo::foo::x`.\nIf this is done on purpose, it would be better to choose a more\nrepresentative module name.\n\n### Example\n```rust\n// lib.rs\nmod foo;\n// foo.rs\nmod foo {\n ...\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-private-module-inception`: Whether to allow module inception if it's not public. (default: `false`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "module_name_repetitions",
|
||
"id_span": {
|
||
"path": "src/item_name_repetitions.rs",
|
||
"line": 74
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects type names that are prefixed or suffixed by the\ncontaining module's name.\n\n### Why is this bad?\nIt requires the user to type the module name twice.\n\n### Example\n```rust\nmod cake {\n struct BlackForestCake;\n}\n```\n\nUse instead:\n```rust\nmod cake {\n struct BlackForest;\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-prefixes`: List of prefixes to allow when determining whether an item's name ends with the module's name.\n If the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`),\n then don't emit a warning.\n\n #### Example\n\n```toml\n allowed-prefixes = [ \"to\", \"from\" ]\n ```\n\n #### Noteworthy\n\n - By default, the following prefixes are allowed: `to`, `as`, `into`, `from`, `try_into` and `try_from`\n - PascalCase variant is included automatically for each snake_case variant (e.g. if `try_into` is included,\n `TryInto` will also be included)\n - Use `\"..\"` as part of the list to indicate that the configured values should be appended to the\n default configuration of Clippy. By default, any configuration will replace the default value (default: `[\"to\", \"as\", \"into\", \"from\", \"try_into\", \"try_from\"]`)\n### Past names\n\n* `stutter`\n\n",
|
||
"version": "1.33.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"stutter"
|
||
]
|
||
},
|
||
{
|
||
"id": "modulo_arithmetic",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 669
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for modulo arithmetic.\n\n### Why is this bad?\nThe results of modulo (%) operation might differ\ndepending on the language, when negative numbers are involved.\nIf you interop with different languages it might be beneficial\nto double check all places that use modulo arithmetic.\n\nFor example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.\n\n### Example\n```rust\nlet x = -17 % 3;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-comparison-to-zero`: Don't lint when comparing the result of a modulo operation to zero. (default: `true`)",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "modulo_one",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 647
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for getting the remainder of a division by one or minus\none.\n\n### Why is this bad?\nThe result for a divisor of one can only ever be zero; for\nminus one it can cause panic/overflow (if the left operand is the minimal value of\nthe respective integer type) or results in zero. No one will write such code\ndeliberately, unless trying to win an Underhanded Rust Contest. Even for that\ncontest, it's probably a bad idea. Use something more underhanded.\n\n### Example\n```rust\nlet a = x % 1;\nlet a = x % -1;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "multi_assignments",
|
||
"id_span": {
|
||
"path": "src/multi_assignments.rs",
|
||
"line": 27
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for nested assignments.\n\n### Why is this bad?\nWhile this is in most cases already a type mismatch,\nthe result of an assignment being `()` can throw off people coming from languages like python or C,\nwhere such assignments return a copy of the assigned value.\n\n### Example\n```rust\na = b = 42;\n```\nUse instead:\n```rust\nb = 42;\na = b;\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "multiple_bound_locations",
|
||
"id_span": {
|
||
"path": "src/multiple_bound_locations.rs",
|
||
"line": 33
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nCheck if a generic is defined both in the bound predicate and in the `where` clause.\n\n### Why is this bad?\nIt can be confusing for developers when seeing bounds for a generic in multiple places.\n\n### Example\n```rust\nfn ty<F: std::fmt::Debug>(a: F)\nwhere\n F: Sized,\n{}\n```\nUse instead:\n```rust\nfn ty<F>(a: F)\nwhere\n F: Sized + std::fmt::Debug,\n{}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "multiple_crate_versions",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 144
|
||
},
|
||
"group": "cargo",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks to see if multiple versions of a crate are being\nused.\n\n### Why is this bad?\nThis bloats the size of targets, and can lead to\nconfusing error messages when structs or traits are used interchangeably\nbetween different versions of a crate.\n\n### Known problems\nBecause this can be caused purely by the dependencies\nthemselves, it's not always possible to fix this issue.\nIn those cases, you can allow that specific crate using\nthe `allowed_duplicate_crates` configuration option.\n\n### Example\n```toml\n# This will pull in both winapi v0.3.x and v0.2.x, triggering a warning.\n[dependencies]\nctrlc = \"=3.1.0\"\nansi_term = \"=0.11.0\"\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-duplicate-crates`: A list of crate names to allow duplicates of (default: `[]`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "multiple_inherent_impl",
|
||
"id_span": {
|
||
"path": "src/inherent_impl.rs",
|
||
"line": 41
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for multiple inherent implementations of a struct\n\n### Why is this bad?\nSplitting the implementation of a type makes the code harder to navigate.\n\n### Example\n```rust\nstruct X;\nimpl X {\n fn one() {}\n}\nimpl X {\n fn other() {}\n}\n```\n\nCould be written:\n\n```rust\nstruct X;\nimpl X {\n fn one() {}\n fn other() {}\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "multiple_unsafe_ops_per_block",
|
||
"id_span": {
|
||
"path": "src/multiple_unsafe_ops_per_block.rs",
|
||
"line": 59
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `unsafe` blocks that contain more than one unsafe operation.\n\n### Why is this bad?\nCombined with `undocumented_unsafe_blocks`,\nthis lint ensures that each unsafe operation must be independently justified.\nCombined with `unused_unsafe`, this lint also ensures\nelimination of unnecessary unsafe blocks through refactoring.\n\n### Example\n```rust\n/// Reads a `char` from the given pointer.\n///\n/// # Safety\n///\n/// `ptr` must point to four consecutive, initialized bytes which\n/// form a valid `char` when interpreted in the native byte order.\nfn read_char(ptr: *const u8) -> char {\n // SAFETY: The caller has guaranteed that the value pointed\n // to by `bytes` is a valid `char`.\n unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n}\n```\nUse instead:\n```rust\n/// Reads a `char` from the given pointer.\n///\n/// # Safety\n///\n/// - `ptr` must be 4-byte aligned, point to four consecutive\n/// initialized bytes, and be valid for reads of 4 bytes.\n/// - The bytes pointed to by `ptr` must represent a valid\n/// `char` when interpreted in the native byte order.\nfn read_char(ptr: *const u8) -> char {\n // SAFETY: `ptr` is 4-byte aligned, points to four consecutive\n // initialized bytes, and is valid for reads of 4 bytes.\n let int_value = unsafe { *ptr.cast::<u32>() };\n\n // SAFETY: The caller has guaranteed that the four bytes\n // pointed to by `bytes` represent a valid `char`.\n unsafe { char::from_u32_unchecked(int_value) }\n}\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "must_use_candidate",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 191
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for public functions that have no\n`#[must_use]` attribute, but return something not already marked\nmust-use, have no mutable arg and mutate no statics.\n\n### Why is this bad?\nNot bad at all, this lint just shows places where\nyou could add the attribute.\n\n### Known problems\nThe lint only checks the arguments for mutable\ntypes without looking if they are actually changed. On the other hand,\nit also ignores a broad range of potentially interesting side effects,\nbecause we cannot decide whether the programmer intends the function to\nbe called for the side effect or the result. Expect many false\npositives. At least we don't lint if the result type is unit or already\n`#[must_use]`.\n\n### Examples\n```rust\n// this could be annotated with `#[must_use]`.\npub fn id<T>(t: T) -> T { t }\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "must_use_unit",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 137
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for a `#[must_use]` attribute on\nunit-returning functions and methods.\n\n### Why is this bad?\nUnit values are useless. The attribute is likely\na remnant of a refactoring that removed the return type.\n\n### Examples\n```rust\n#[must_use]\nfn useless() { }\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "mut_from_ref",
|
||
"id_span": {
|
||
"path": "src/ptr.rs",
|
||
"line": 127
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nThis lint checks for functions that take immutable references and return\nmutable ones. This will not trigger if no unsafe code exists as there\nare multiple safe functions which will do this transformation\n\nTo be on the conservative side, if there's at least one mutable\nreference with the output lifetime, this lint will not trigger.\n\n### Why is this bad?\nCreating a mutable reference which can be repeatably derived from an\nimmutable reference is unsound as it allows creating multiple live\nmutable references to the same object.\n\nThis [error](https://github.com/rust-lang/rust/issues/39465) actually\nlead to an interim Rust release 1.15.1.\n\n### Known problems\nThis pattern is used by memory allocators to allow allocating multiple\nobjects while returning mutable references to each one. So long as\ndifferent mutable references are returned each time such a function may\nbe safe.\n\n### Example\n```rust\nfn foo(&Foo) -> &mut Bar { .. }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mut_mut",
|
||
"id_span": {
|
||
"path": "src/mut_mut.rs",
|
||
"line": 25
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for instances of `mut mut` references.\n\n### Why is this bad?\nMultiple `mut`s don't add anything meaningful to the\nsource. This is either a copy'n'paste error, or it shows a fundamental\nmisunderstanding of references.\n\n### Example\n```rust\nlet x = &mut &mut y;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mut_mutex_lock",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2812
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `&mut Mutex::lock` calls\n\n### Why is this bad?\n`Mutex::lock` is less efficient than\ncalling `Mutex::get_mut`. In addition you also have a statically\nguarantee that the mutex isn't locked, instead of just a runtime\nguarantee.\n\n### Example\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet mut value_rc = Arc::new(Mutex::new(42_u8));\nlet value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n\nlet mut value = value_mutex.lock().unwrap();\n*value += 1;\n```\nUse instead:\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet mut value_rc = Arc::new(Mutex::new(42_u8));\nlet value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n\nlet value = value_mutex.get_mut().unwrap();\n*value += 1;\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "mut_range_bound",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 387
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for loops which have a range bound that is a mutable variable\n\n### Why is this bad?\nOne might think that modifying the mutable variable changes the loop bounds\n\n### Known problems\nFalse positive when mutation is followed by a `break`, but the `break` is not immediately\nafter the mutation:\n\n```rust\nlet mut x = 5;\nfor _ in 0..x {\n x += 1; // x is a range bound that is mutated\n ..; // some other expression\n break; // leaves the loop, so mutation is not an issue\n}\n```\n\nFalse positive on nested loops ([#6072](https://github.com/rust-lang/rust-clippy/issues/6072))\n\n### Example\n```rust\nlet mut foo = 42;\nfor i in 0..foo {\n foo -= 1;\n println!(\"{}\", i); // prints numbers from 0 to 42, not 0 to 21\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mutable_key_type",
|
||
"id_span": {
|
||
"path": "src/mut_key.rs",
|
||
"line": 78
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for sets/maps with mutable key types.\n\n### Why is this bad?\nAll of `HashMap`, `HashSet`, `BTreeMap` and\n`BtreeSet` rely on either the hash or the order of keys be unchanging,\nso having types with interior mutability is a bad idea.\n\n### Known problems\n\n#### False Positives\nIt's correct to use a struct that contains interior mutability as a key, when its\nimplementation of `Hash` or `Ord` doesn't access any of the interior mutable types.\nHowever, this lint is unable to recognize this, so it will often cause false positives in\ntheses cases. The `bytes` crate is a great example of this.\n\n#### False Negatives\nFor custom `struct`s/`enum`s, this lint is unable to check for interior mutability behind\nindirection. For example, `struct BadKey<'a>(&'a Cell<usize>)` will be seen as immutable\nand cause a false negative if its implementation of `Hash`/`Ord` accesses the `Cell`.\n\nThis lint does check a few cases for indirection. Firstly, using some standard library\ntypes (`Option`, `Result`, `Box`, `Rc`, `Arc`, `Vec`, `VecDeque`, `BTreeMap` and\n`BTreeSet`) directly as keys (e.g. in `HashMap<Box<Cell<usize>>, ()>`) **will** trigger the\nlint, because the impls of `Hash`/`Ord` for these types directly call `Hash`/`Ord` on their\ncontained type.\n\nSecondly, the implementations of `Hash` and `Ord` for raw pointers (`*const T` or `*mut T`)\napply only to the **address** of the contained value. Therefore, interior mutability\nbehind raw pointers (e.g. in `HashSet<*mut Cell<usize>>`) can't impact the value of `Hash`\nor `Ord`, and therefore will not trigger this link. For more info, see issue\n[#6745](https://github.com/rust-lang/rust-clippy/issues/6745).\n\n### Example\n```rust\nuse std::cmp::{PartialEq, Eq};\nuse std::collections::HashSet;\nuse std::hash::{Hash, Hasher};\nuse std::sync::atomic::AtomicUsize;\n\nstruct Bad(AtomicUsize);\nimpl PartialEq for Bad {\n fn eq(&self, rhs: &Self) -> bool {\n ..\n; unimplemented!();\n }\n}\n\nimpl Eq for Bad {}\n\nimpl Hash for Bad {\n fn hash<H: Hasher>(&self, h: &mut H) {\n ..\n; unimplemented!();\n }\n}\n\nfn main() {\n let _: HashSet<Bad> = HashSet::new();\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `ignore-interior-mutability`: A list of paths to types that should be treated like `Arc`, i.e. ignored but\n for the generic parameters for determining interior mutability (default: `[\"bytes::Bytes\"]`)",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mutex_atomic",
|
||
"id_span": {
|
||
"path": "src/mutex_atomic.rs",
|
||
"line": 45
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Mutex<X>` where an atomic will do.\n\n### Why is this bad?\nUsing a mutex just to make access to a plain bool or\nreference sequential is shooting flies with cannons.\n`std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and\nfaster.\n\nOn the other hand, `Mutex`es are, in general, easier to\nverify correctness. An atomic does not behave the same as\nan equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s commentary for more details.\n\n### Known problems\nThis lint cannot detect if the mutex is actually used\nfor waiting before a critical section.\n\n### Example\n```rust\nlet x = Mutex::new(&y);\n```\n\nUse instead:\n```rust\nlet x = AtomicBool::new(y);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "mutex_integer",
|
||
"id_span": {
|
||
"path": "src/mutex_atomic.rs",
|
||
"line": 76
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Mutex<X>` where `X` is an integral\ntype.\n\n### Why is this bad?\nUsing a mutex just to make access to a plain integer\nsequential is\nshooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.\n\n### Known problems\nThis lint cannot detect if the mutex is actually used\nfor waiting before a critical section.\n\n### Example\n```rust\nlet x = Mutex::new(0usize);\n```\n\nUse instead:\n```rust\nlet x = AtomicUsize::new(0usize);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "naive_bytecount",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2542
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for naive byte counts\n\n### Why is this bad?\nThe [`bytecount`](https://crates.io/crates/bytecount)\ncrate has methods to count your bytes faster, especially for large slices.\n\n### Known problems\nIf you have predominantly small slices, the\n`bytecount::count(..)` method may actually be slower. However, if you can\nensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be\nfaster in those cases.\n\n### Example\n```rust\nlet count = vec.iter().filter(|x| **x == 0u8).count();\n```\n\nUse instead:\n```rust\nlet count = bytecount::count(&vec, 0u8);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_arbitrary_self_type",
|
||
"id_span": {
|
||
"path": "src/needless_arbitrary_self_type.rs",
|
||
"line": 55
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThe lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly\n### Why is this bad?\nIncreases the amount and decreases the readability of code\n\n### Example\n```rust\nenum ValType {\n I32,\n I64,\n F32,\n F64,\n}\n\nimpl ValType {\n pub fn bytes(self: Self) -> usize {\n match self {\n Self::I32 | Self::F32 => 4,\n Self::I64 | Self::F64 => 8,\n }\n }\n}\n```\n\nCould be rewritten as\n\n```rust\nenum ValType {\n I32,\n I64,\n F32,\n F64,\n}\n\nimpl ValType {\n pub fn bytes(self) -> usize {\n match self {\n Self::I32 | Self::F32 => 4,\n Self::I64 | Self::F64 => 8,\n }\n }\n}\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_bitwise_bool",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 698
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of bitwise and/or operators between booleans, where performance may be improved by using\na lazy and.\n\n### Why is this bad?\nThe bitwise operators do not support short-circuiting, so it may hinder code performance.\nAdditionally, boolean logic \"masked\" as bitwise logic is not caught by lints like `unnecessary_fold`\n\n### Known problems\nThis lint evaluates only when the right side is determined to have no side effects. At this time, that\ndetermination is quite conservative.\n\n### Example\n```rust\nlet (x,y) = (true, false);\nif x & !y {} // where both x and y are booleans\n```\nUse instead:\n```rust\nlet (x,y) = (true, false);\nif x && !y {}\n```",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_bool",
|
||
"id_span": {
|
||
"path": "src/needless_bool.rs",
|
||
"line": 52
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions of the form `if c { true } else {\nfalse }` (or vice versa) and suggests using the condition directly.\n\n### Why is this bad?\nRedundant code.\n\n### Known problems\nMaybe false positives: Sometimes, the two branches are\npainstakingly documented (which we, of course, do not detect), so they *may*\nhave some value. Even then, the documentation can be rewritten to match the\nshorter code.\n\n### Example\n```rust\nif x {\n false\n} else {\n true\n}\n```\n\nUse instead:\n```rust\n!x\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_bool_assign",
|
||
"id_span": {
|
||
"path": "src/needless_bool.rs",
|
||
"line": 110
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions of the form `if c { x = true } else { x = false }`\n(or vice versa) and suggest assigning the variable directly from the\ncondition.\n\n### Why is this bad?\nRedundant code.\n\n### Example\n```rust\nif must_keep(x, y) {\n skip = false;\n} else {\n skip = true;\n}\n```\nUse instead:\n```rust\nskip = !must_keep(x, y);\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_borrow",
|
||
"id_span": {
|
||
"path": "src/dereference.rs",
|
||
"line": 84
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for address of operations (`&`) that are going to\nbe dereferenced immediately by the compiler.\n\n### Why is this bad?\nSuggests that the receiver of the expression borrows\nthe expression.\n\n### Known problems\nThe lint cannot tell when the implementation of a trait\nfor `&T` and `T` do different things. Removing a borrow\nin such a case can change the semantics of the code.\n\n### Example\n```rust\nfn fun(_a: &i32) {}\n\nlet x: &i32 = &&&&&&5;\nfun(&x);\n```\n\nUse instead:\n```rust\nlet x: &i32 = &5;\nfun(x);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n### Past names\n\n* `ref_in_deref`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"ref_in_deref"
|
||
]
|
||
},
|
||
{
|
||
"id": "needless_borrowed_reference",
|
||
"id_span": {
|
||
"path": "src/needless_borrowed_ref.rs",
|
||
"line": 31
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for bindings that needlessly destructure a reference and borrow the inner\nvalue with `&ref`.\n\n### Why is this bad?\nThis pattern has no effect in almost all cases.\n\n### Example\n```rust\nlet mut v = Vec::<String>::new();\nv.iter_mut().filter(|&ref a| a.is_empty());\n\nif let &[ref first, ref second] = v.as_slice() {}\n```\n\nUse instead:\n```rust\nlet mut v = Vec::<String>::new();\nv.iter_mut().filter(|a| a.is_empty());\n\nif let [first, second] = v.as_slice() {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_borrows_for_generic_args",
|
||
"id_span": {
|
||
"path": "src/needless_borrows_for_generic_args.rs",
|
||
"line": 54
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for borrow operations (`&`) that are used as a generic argument to a\nfunction when the borrowed value could be used.\n\n### Why is this bad?\nSuggests that the receiver of the expression borrows\nthe expression.\n\n### Known problems\nThe lint cannot tell when the implementation of a trait\nfor `&T` and `T` do different things. Removing a borrow\nin such a case can change the semantics of the code.\n\n### Example\n```rust\nfn f(_: impl AsRef<str>) {}\n\nlet x = \"foo\";\nf(&x);\n```\n\nUse instead:\n```rust\nfn f(_: impl AsRef<str>) {}\n\nlet x = \"foo\";\nf(x);\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_collect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3290
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions collecting an iterator when collect\nis not needed.\n\n### Why is this bad?\n`collect` causes the allocation of a new data structure,\nwhen this allocation may not be needed.\n\n### Example\n```rust\nlet len = iterator.collect::<Vec<_>>().len();\n```\nUse instead:\n```rust\nlet len = iterator.count();\n```",
|
||
"version": "1.30.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_continue",
|
||
"id_span": {
|
||
"path": "src/needless_continue.rs",
|
||
"line": 114
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThe lint checks for `if`-statements appearing in loops\nthat contain a `continue` statement in either their main blocks or their\n`else`-blocks, when omitting the `else`-block possibly with some\nrearrangement of code can make the code easier to understand.\n\n### Why is this bad?\nHaving explicit `else` blocks for `if` statements\ncontaining `continue` in their THEN branch adds unnecessary branching and\nnesting to the code. Having an else block containing just `continue` can\nalso be better written by grouping the statements following the whole `if`\nstatement within the THEN block and omitting the else block completely.\n\n### Example\n```rust\nwhile condition() {\n update_condition();\n if x {\n // ...\n } else {\n continue;\n }\n println!(\"Hello, world\");\n}\n```\n\nCould be rewritten as\n\n```rust\nwhile condition() {\n update_condition();\n if x {\n // ...\n println!(\"Hello, world\");\n }\n}\n```\n\nAs another example, the following code\n\n```rust\nloop {\n if waiting() {\n continue;\n } else {\n // Do something useful\n }\n}\n```\nCould be rewritten as\n\n```rust\nloop {\n if waiting() {\n continue;\n }\n // Do something useful\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_doctest_main",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 197
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `fn main() { .. }` in doctests\n\n### Why is this bad?\nThe test can be shorter (and likely more readable)\nif the `fn main()` is left implicit.\n\n### Examples\n```rust\n/// An example of a doctest with a `main()` function\n///\n/// # Examples\n///\n/// ```\n/// fn main() {\n/// // this needs not be in an `fn`\n/// }\n/// ```\nfn needless_main() {\n unimplemented!();\n}\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_else",
|
||
"id_span": {
|
||
"path": "src/needless_else.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for empty `else` branches.\n\n### Why is this bad?\nAn empty else branch does nothing and can be removed.\n\n### Example\n```rust\nif check() {\n println!(\"Check successful!\");\n} else {\n}\n```\nUse instead:\n```rust\nif check() {\n println!(\"Check successful!\");\n}\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_for_each",
|
||
"id_span": {
|
||
"path": "src/needless_for_each.rs",
|
||
"line": 39
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `for_each` that would be more simply written as a\n`for` loop.\n\n### Why is this bad?\n`for_each` may be used after applying iterator transformers like\n`filter` for better readability and performance. It may also be used to fit a simple\noperation on one line.\nBut when none of these apply, a simple `for` loop is more idiomatic.\n\n### Example\n```rust\nlet v = vec![0, 1, 2];\nv.iter().for_each(|elem| {\n println!(\"{}\", elem);\n})\n```\nUse instead:\n```rust\nlet v = vec![0, 1, 2];\nfor elem in v.iter() {\n println!(\"{}\", elem);\n}\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_if",
|
||
"id_span": {
|
||
"path": "src/needless_if.rs",
|
||
"line": 33
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for empty `if` branches with no else branch.\n\n### Why is this bad?\nIt can be entirely omitted, and often the condition too.\n\n### Known issues\nThis will usually only suggest to remove the `if` statement, not the condition. Other lints\nsuch as `no_effect` will take care of removing the condition if it's unnecessary.\n\n### Example\n```rust\nif really_expensive_condition(&i) {}\nif really_expensive_condition_with_side_effects(&mut i) {}\n```\nUse instead:\n```rust\n// <omitted>\nreally_expensive_condition_with_side_effects(&mut i);\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_late_init",
|
||
"id_span": {
|
||
"path": "src/needless_late_init.rs",
|
||
"line": 60
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for late initializations that can be replaced by a `let` statement\nwith an initializer.\n\n### Why is this bad?\nAssigning in the `let` statement is less repetitive.\n\n### Example\n```rust\nlet a;\na = 1;\n\nlet b;\nmatch 3 {\n 0 => b = \"zero\",\n 1 => b = \"one\",\n _ => b = \"many\",\n}\n\nlet c;\nif true {\n c = 1;\n} else {\n c = -1;\n}\n```\nUse instead:\n```rust\nlet a = 1;\n\nlet b = match 3 {\n 0 => \"zero\",\n 1 => \"one\",\n _ => \"many\",\n};\n\nlet c = if true {\n 1\n} else {\n -1\n};\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_lifetimes",
|
||
"id_span": {
|
||
"path": "src/lifetimes.rs",
|
||
"line": 55
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for lifetime annotations which can be removed by\nrelying on lifetime elision.\n\n### Why is this bad?\nThe additional lifetimes make the code look more\ncomplicated, while there is nothing out of the ordinary going on. Removing\nthem leads to more readable code.\n\n### Known problems\n- We bail out if the function has a `where` clause where lifetimes\nare mentioned due to potential false positives.\n\n### Example\n```rust\n// Unnecessary lifetime annotations\nfn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {\n x\n}\n```\n\nUse instead:\n```rust\nfn elided(x: &u8, y: u8) -> &u8 {\n x\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_match",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 657
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`\nwhen function signatures are the same.\n\n### Why is this bad?\nThis `match` block does nothing and might not be what the coder intended.\n\n### Example\n```rust\nfn foo() -> Result<(), i32> {\n match result {\n Ok(val) => Ok(val),\n Err(err) => Err(err),\n }\n}\n\nfn bar() -> Option<i32> {\n if let Some(val) = option {\n Some(val)\n } else {\n None\n }\n}\n```\n\nCould be replaced as\n\n```rust\nfn foo() -> Result<(), i32> {\n result\n}\n\nfn bar() -> Option<i32> {\n option\n}\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_option_as_deref",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2350
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for no-op uses of `Option::{as_deref, as_deref_mut}`,\nfor example, `Option<&T>::as_deref()` returns the same type.\n\n### Why is this bad?\nRedundant code and improving readability.\n\n### Example\n```rust\nlet a = Some(&1);\nlet b = a.as_deref(); // goes from Option<&i32> to Option<&i32>\n```\n\nUse instead:\n```rust\nlet a = Some(&1);\nlet b = a;\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_option_take",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2401
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calling `take` function after `as_ref`.\n\n### Why is this bad?\nRedundant code. `take` writes `None` to its argument.\nIn this case the modification is useless as it's a temporary that cannot be read from afterwards.\n\n### Example\n```rust\nlet x = Some(3);\nx.as_ref().take();\n```\nUse instead:\n```rust\nlet x = Some(3);\nx.as_ref();\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_parens_on_range_literals",
|
||
"id_span": {
|
||
"path": "src/needless_parens_on_range_literals.rs",
|
||
"line": 37
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThe lint checks for parenthesis on literals in range statements that are\nsuperfluous.\n\n### Why is this bad?\nHaving superfluous parenthesis makes the code less readable\noverhead when reading.\n\n### Example\n\n```rust\nfor i in (0)..10 {\n println!(\"{i}\");\n}\n```\n\nUse instead:\n\n```rust\nfor i in 0..10 {\n println!(\"{i}\");\n}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_pass_by_ref_mut",
|
||
"id_span": {
|
||
"path": "src/needless_pass_by_ref_mut.rs",
|
||
"line": 50
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nCheck if a `&mut` function argument is actually used mutably.\n\nBe careful if the function is publicly reexported as it would break compatibility with\nusers of this function.\n\n### Why is this bad?\nLess `mut` means less fights with the borrow checker. It can also lead to more\nopportunities for parallelization.\n\n### Example\n```rust\nfn foo(y: &mut i32) -> i32 {\n 12 + *y\n}\n```\nUse instead:\n```rust\nfn foo(y: &i32) -> i32 {\n 12 + *y\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_pass_by_value",
|
||
"id_span": {
|
||
"path": "src/needless_pass_by_value.rs",
|
||
"line": 57
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions taking arguments by value, but not\nconsuming them in its\nbody.\n\n### Why is this bad?\nTaking arguments by reference is more flexible and can\nsometimes avoid\nunnecessary allocations.\n\n### Known problems\n* This lint suggests taking an argument by reference,\nhowever sometimes it is better to let users decide the argument type\n(by using `Borrow` trait, for example), depending on how the function is used.\n\n### Example\n```rust\nfn foo(v: Vec<i32>) {\n assert_eq!(v.len(), 42);\n}\n```\nshould be\n```rust\nfn foo(v: &[i32]) {\n assert_eq!(v.len(), 42);\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_pub_self",
|
||
"id_span": {
|
||
"path": "src/visibility.rs",
|
||
"line": 27
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `pub(self)` and `pub(in self)`.\n\n### Why is this bad?\nIt's unnecessary, omitting the `pub` entirely will give the same results.\n\n### Example\n```rust\npub(self) type OptBox<T> = Option<Box<T>>;\n```\nUse instead:\n```rust\ntype OptBox<T> = Option<Box<T>>;\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_question_mark",
|
||
"id_span": {
|
||
"path": "src/needless_question_mark.rs",
|
||
"line": 55
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSuggests alternatives for useless applications of `?` in terminating expressions\n\n### Why is this bad?\nThere's no reason to use `?` to short-circuit when execution of the body will end there anyway.\n\n### Example\n```rust\nstruct TO {\n magic: Option<usize>,\n}\n\nfn f(to: TO) -> Option<usize> {\n Some(to.magic?)\n}\n\nstruct TR {\n magic: Result<usize, bool>,\n}\n\nfn g(tr: Result<TR, bool>) -> Result<usize, bool> {\n tr.and_then(|t| Ok(t.magic?))\n}\n\n```\nUse instead:\n```rust\nstruct TO {\n magic: Option<usize>,\n}\n\nfn f(to: TO) -> Option<usize> {\n to.magic\n}\n\nstruct TR {\n magic: Result<usize, bool>,\n}\n\nfn g(tr: Result<TR, bool>) -> Result<usize, bool> {\n tr.and_then(|t| t.magic)\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_range_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 87
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for looping over the range of `0..len` of some\ncollection just to get the values by index.\n\n### Why is this bad?\nJust iterating the collection itself makes the intent\nmore clear and is probably faster because it eliminates\nthe bounds check that is done when indexing.\n\n### Example\n```rust\nlet vec = vec!['a', 'b', 'c'];\nfor i in 0..vec.len() {\n println!(\"{}\", vec[i]);\n}\n```\n\nUse instead:\n```rust\nlet vec = vec!['a', 'b', 'c'];\nfor i in vec {\n println!(\"{}\", i);\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_raw_string_hashes",
|
||
"id_span": {
|
||
"path": "src/raw_strings.rs",
|
||
"line": 52
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for raw string literals with an unnecessary amount of hashes around them.\n\n### Why is this bad?\nIt's just unnecessary, and makes it look like there's more escaping needed than is actually\nnecessary.\n\n### Example\n```rust\nlet r = r###\"Hello, \"world\"!\"###;\n```\nUse instead:\n```rust\nlet r = r#\"Hello, \"world\"!\"#;\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_raw_strings",
|
||
"id_span": {
|
||
"path": "src/raw_strings.rs",
|
||
"line": 31
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for raw string literals where a string literal can be used instead.\n\n### Why is this bad?\nIt's just unnecessary, but there are many cases where using a raw string literal is more\nidiomatic than a string literal, so it's opt-in.\n\n### Example\n```rust\nlet r = r\"Hello, world!\";\n```\nUse instead:\n```rust\nlet r = \"Hello, world!\";\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_return",
|
||
"id_span": {
|
||
"path": "src/returns.rs",
|
||
"line": 82
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for return statements at the end of a block.\n\n### Why is this bad?\nRemoving the `return` and semicolon will make the code\nmore rusty.\n\n### Example\n```rust\nfn foo(x: usize) -> usize {\n return x;\n}\n```\nsimplify to\n```rust\nfn foo(x: usize) -> usize {\n x\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_return_with_question_mark",
|
||
"id_span": {
|
||
"path": "src/returns.rs",
|
||
"line": 122
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for return statements on `Err` paired with the `?` operator.\n\n### Why is this bad?\nThe `return` is unnecessary.\n\n### Example\n```rust\nfn foo(x: usize) -> Result<(), Box<dyn Error>> {\n if x == 0 {\n return Err(...)?;\n }\n Ok(())\n}\n```\nsimplify to\n```rust\nfn foo(x: usize) -> Result<(), Box<dyn Error>> {\n if x == 0 {\n Err(...)?;\n }\n Ok(())\n}\n```\nif paired with `try_err`, use instead:\n```rust\nfn foo(x: usize) -> Result<(), Box<dyn Error>> {\n if x == 0 {\n return Err(...);\n }\n Ok(())\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_splitn",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2262
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.\n### Why is this bad?\nThe function `split` is simpler and there is no performance difference in these cases, considering\nthat both functions return a lazy iterator.\n### Example\n```rust\nlet str = \"key=value=add\";\nlet _ = str.splitn(3, '=').next().unwrap();\n```\n\nUse instead:\n```rust\nlet str = \"key=value=add\";\nlet _ = str.split('=').next().unwrap();\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "needless_update",
|
||
"id_span": {
|
||
"path": "src/needless_update.rs",
|
||
"line": 45
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for needlessly including a base struct on update\nwhen all fields are changed anyway.\n\nThis lint is not applied to structs marked with\n[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).\n\n### Why is this bad?\nThis will cost resources (because the base has to be\nsomewhere), and make the code less readable.\n\n### Example\n```rust\nPoint {\n x: 1,\n y: 1,\n z: 1,\n ..zero_point\n};\n```\n\nUse instead:\n```rust\n// Missing field `z`\nPoint {\n x: 1,\n y: 1,\n ..zero_point\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "neg_cmp_op_on_partial_ord",
|
||
"id_span": {
|
||
"path": "src/neg_cmp_op_on_partial_ord.rs",
|
||
"line": 39
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the usage of negated comparison operators on types which only implement\n`PartialOrd` (e.g., `f64`).\n\n### Why is this bad?\nThese operators make it easy to forget that the underlying types actually allow not only three\npotential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is\nespecially easy to miss if the operator based comparison result is negated.\n\n### Example\n```rust\nlet a = 1.0;\nlet b = f64::NAN;\n\nlet not_less_or_equal = !(a <= b);\n```\n\nUse instead:\n```rust\nuse std::cmp::Ordering;\n\nlet _not_less_or_equal = match a.partial_cmp(&b) {\n None | Some(Ordering::Greater) => true,\n _ => false,\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "neg_multiply",
|
||
"id_span": {
|
||
"path": "src/neg_multiply.rs",
|
||
"line": 32
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for multiplication by -1 as a form of negation.\n\n### Why is this bad?\nIt's more readable to just negate.\n\n### Known problems\nThis only catches integers (for now).\n\n### Example\n```rust\nlet a = x * -1;\n```\n\nUse instead:\n```rust\nlet a = -x;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "negative_feature_names",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 115
|
||
},
|
||
"group": "cargo",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for negative feature names with prefix `no-` or `not-`\n\n### Why is this bad?\nFeatures are supposed to be additive, and negatively-named features violate it.\n\n### Example\n```toml\n# The `Cargo.toml` with negative feature names\n[features]\ndefault = []\nno-abc = []\nnot-def = []\n\n```\nUse instead:\n```toml\n[features]\ndefault = [\"abc\", \"def\"]\nabc = []\ndef = []\n\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "never_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 351
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for loops that will always `break`, `return` or\n`continue` an outer loop.\n\n### Why is this bad?\nThis loop never loops, all it does is obfuscating the\ncode.\n\n### Example\n```rust\nloop {\n ..;\n break;\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "new_ret_no_self",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1137
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `new` not returning a type that contains `Self`.\n\n### Why is this bad?\nAs a convention, `new` methods are used to make a new\ninstance of a type.\n\n### Example\nIn an impl block:\n```rust\nimpl Foo {\n fn new() -> NotAFoo {\n }\n}\n```\n\n```rust\nstruct Bar(Foo);\nimpl Foo {\n // Bad. The type name must contain `Self`\n fn new() -> Bar {\n }\n}\n```\n\n```rust\nimpl Foo {\n // Good. Return type contains `Self`\n fn new() -> Result<Foo, FooError> {\n }\n}\n```\n\nOr in a trait definition:\n```rust\npub trait Trait {\n // Bad. The type name must contain `Self`\n fn new();\n}\n```\n\n```rust\npub trait Trait {\n // Good. Return type contains `Self`\n fn new() -> Self;\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "new_without_default",
|
||
"id_span": {
|
||
"path": "src/new_without_default.rs",
|
||
"line": 47
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for public types with a `pub fn new() -> Self` method and no\nimplementation of\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).\n\n### Why is this bad?\nThe user might expect to be able to use\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the\ntype can be constructed without arguments.\n\n### Example\n```rust\npub struct Foo(Bar);\n\nimpl Foo {\n pub fn new() -> Self {\n Foo(Bar::new())\n }\n}\n```\n\nTo fix the lint, add a `Default` implementation that delegates to `new`:\n\n```rust\npub struct Foo(Bar);\n\nimpl Default for Foo {\n fn default() -> Self {\n Foo::new()\n }\n}\n```\n### Past names\n\n* `new_without_default_derive`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"new_without_default_derive"
|
||
]
|
||
},
|
||
{
|
||
"id": "no_effect",
|
||
"id_span": {
|
||
"path": "src/no_effect.rs",
|
||
"line": 32
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for statements which have no effect.\n\n### Why is this bad?\nUnlike dead code, these statements are actually\nexecuted. However, as they have no effect, all they do is make the code less\nreadable.\n\n### Example\n```rust\n0;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "no_effect_replace",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2419
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `replace` statements which have no effect.\n\n### Why is this bad?\nIt's either a mistake or confusing.\n\n### Example\n```rust\n\"1234\".replace(\"12\", \"12\");\n\"1234\".replacen(\"12\", \"12\", 1);\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "no_effect_underscore_binding",
|
||
"id_span": {
|
||
"path": "src/no_effect.rs",
|
||
"line": 51
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for binding to underscore prefixed variable without side-effects.\n\n### Why is this bad?\nUnlike dead code, these bindings are actually\nexecuted. However, as they have no effect and shouldn't be used further on, all they\ndo is make the code less readable.\n\n### Example\n```rust\nlet _i_serve_no_purpose = 1;\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "no_mangle_with_rust_abi",
|
||
"id_span": {
|
||
"path": "src/no_mangle_with_rust_abi.rs",
|
||
"line": 32
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for Rust ABI functions with the `#[no_mangle]` attribute.\n\n### Why is this bad?\nThe Rust ABI is not stable, but in many simple cases matches\nenough with the C ABI that it is possible to forget to add\n`extern \"C\"` to a function called from C. Changes to the\nRust ABI can break this at any point.\n\n### Example\n```rust\n #[no_mangle]\n fn example(arg_one: u32, arg_two: usize) {}\n```\n\nUse instead:\n```rust\n #[no_mangle]\n extern \"C\" fn example(arg_one: u32, arg_two: usize) {}\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "non_ascii_literal",
|
||
"id_span": {
|
||
"path": "src/unicode.rs",
|
||
"line": 51
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for non-ASCII characters in string and char literals.\n\n### Why is this bad?\nYeah, we know, the 90's called and wanted their charset\nback. Even so, there still are editors and other programs out there that\ndon't work well with Unicode. So if the code is meant to be used\ninternationally, on multiple operating systems, or has other portability\nrequirements, activating this lint could be useful.\n\n### Example\n```rust\nlet x = String::from(\"€\");\n```\n\nUse instead:\n```rust\nlet x = String::from(\"\\u{20ac}\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "non_canonical_clone_impl",
|
||
"id_span": {
|
||
"path": "src/non_canonical_impls.rs",
|
||
"line": 49
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for non-canonical implementations of `Clone` when `Copy` is already implemented.\n\n### Why is this bad?\nIf both `Clone` and `Copy` are implemented, they must agree. This can done by dereferencing\n`self` in `Clone`'s implementation, which will avoid any possibility of the implementations\nbecoming out of sync.\n\n### Example\n```rust\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Clone for A {\n fn clone(&self) -> Self {\n Self(self.0)\n }\n}\n\nimpl Copy for A {}\n```\nUse instead:\n```rust\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Clone for A {\n fn clone(&self) -> Self {\n *self\n }\n}\n\nimpl Copy for A {}\n```\n### Past names\n\n* `incorrect_clone_impl_on_copy_type`\n\n",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
},
|
||
"former_ids": [
|
||
"incorrect_clone_impl_on_copy_type"
|
||
]
|
||
},
|
||
{
|
||
"id": "non_canonical_partial_ord_impl",
|
||
"id_span": {
|
||
"path": "src/non_canonical_impls.rs",
|
||
"line": 106
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented.\n\n### Why is this bad?\nIf both `PartialOrd` and `Ord` are implemented, they must agree. This is commonly done by\nwrapping the result of `cmp` in `Some` for `partial_cmp`. Not doing this may silently\nintroduce an error upon refactoring.\n\n### Known issues\nCode that calls the `.into()` method instead will be flagged, despite `.into()` wrapping it\nin `Some`.\n\n### Example\n```rust\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Ord for A {\n fn cmp(&self, other: &Self) -> Ordering {\n // ...\n }\n}\n\nimpl PartialOrd for A {\n fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n // ...\n }\n}\n```\nUse instead:\n```rust\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Ord for A {\n fn cmp(&self, other: &Self) -> Ordering {\n // ...\n }\n}\n\nimpl PartialOrd for A {\n fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n Some(self.cmp(other))\n }\n}\n```\n### Past names\n\n* `incorrect_partial_ord_impl_on_ord_type`\n\n",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
},
|
||
"former_ids": [
|
||
"incorrect_partial_ord_impl_on_ord_type"
|
||
]
|
||
},
|
||
{
|
||
"id": "non_minimal_cfg",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 379
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `any` and `all` combinators in `cfg` with only one condition.\n\n### Why is this bad?\nIf there is only one condition, no need to wrap it into `any` or `all` combinators.\n\n### Example\n```rust\n#[cfg(any(unix))]\npub struct Bar;\n```\n\nUse instead:\n```rust\n#[cfg(unix)]\npub struct Bar;\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "non_octal_unix_permissions",
|
||
"id_span": {
|
||
"path": "src/non_octal_unix_permissions.rs",
|
||
"line": 35
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for non-octal values used to set Unix file permissions.\n\n### Why is this bad?\nThey will be converted into octal, creating potentially\nunintended file permissions.\n\n### Example\n```rust\nuse std::fs::OpenOptions;\nuse std::os::unix::fs::OpenOptionsExt;\n\nlet mut options = OpenOptions::new();\noptions.mode(644);\n```\nUse instead:\n```rust\nuse std::fs::OpenOptions;\nuse std::os::unix::fs::OpenOptionsExt;\n\nlet mut options = OpenOptions::new();\noptions.mode(0o644);\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "non_send_fields_in_send_ty",
|
||
"id_span": {
|
||
"path": "src/non_send_fields_in_send_ty.rs",
|
||
"line": 52
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint warns about a `Send` implementation for a type that\ncontains fields that are not safe to be sent across threads.\nIt tries to detect fields that can cause a soundness issue\nwhen sent to another thread (e.g., `Rc`) while allowing `!Send` fields\nthat are expected to exist in a `Send` type, such as raw pointers.\n\n### Why is this bad?\nSending the struct to another thread effectively sends all of its fields,\nand the fields that do not implement `Send` can lead to soundness bugs\nsuch as data races when accessed in a thread\nthat is different from the thread that created it.\n\nSee:\n* [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html)\n* [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html)\n\n### Known Problems\nThis lint relies on heuristics to distinguish types that are actually\nunsafe to be sent across threads and `!Send` types that are expected to\nexist in `Send` type. Its rule can filter out basic cases such as\n`Vec<*const T>`, but it's not perfect. Feel free to create an issue if\nyou have a suggestion on how this heuristic can be improved.\n\n### Example\n```rust\nstruct ExampleStruct<T> {\n rc_is_not_send: Rc<String>,\n unbounded_generic_field: T,\n}\n\n// This impl is unsound because it allows sending `!Send` types through `ExampleStruct`\nunsafe impl<T> Send for ExampleStruct<T> {}\n```\nUse thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)\nor specify correct bounds on generic type parameters (`T: Send`).\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `enable-raw-pointer-heuristic-for-send`: Whether to apply the raw pointer heuristic to determine if a type is `Send`. (default: `true`)",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "nonminimal_bool",
|
||
"id_span": {
|
||
"path": "src/booleans.rs",
|
||
"line": 39
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for boolean expressions that can be written more\nconcisely.\n\n### Why is this bad?\nReadability of boolean expressions suffers from\nunnecessary duplication.\n\n### Known problems\nIgnores short circuiting behavior of `||` and\n`&&`. Ignores `|`, `&` and `^`.\n\n### Example\n```rust\nif a && true {}\nif !(a == b) {}\n```\n\nUse instead:\n```rust\nif a {}\nif a != b {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "nonsensical_open_options",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2833
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for duplicate open options as well as combinations\nthat make no sense.\n\n### Why is this bad?\nIn the best case, the code will be harder to read than\nnecessary. I don't know the worst case.\n\n### Example\n```rust\nuse std::fs::OpenOptions;\n\nOpenOptions::new().read(true).truncate(true);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "nonstandard_macro_braces",
|
||
"id_span": {
|
||
"path": "src/nonstandard_macro_braces.rs",
|
||
"line": 30
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks that common macros are used with consistent bracing.\n\n### Why is this bad?\nThis is mostly a consistency lint although using () or []\ndoesn't give you a semicolon in item position, which can be unexpected.\n\n### Example\n```rust\nvec!{1, 2, 3};\n```\nUse instead:\n```rust\nvec![1, 2, 3];\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `standard-macro-braces`: Enforce the named macros always use the braces specified.\n\n A `MacroMatcher` can be added like so `{ name = \"macro_name\", brace = \"(\" }`. If the macro\n could be used with a full path two `MacroMatcher`s have to be added one with the full path\n `crate_name::macro_name` and one with just the macro name. (default: `[]`)",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "not_unsafe_ptr_arg_deref",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 117
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for public functions that dereference raw pointer\narguments but are not marked `unsafe`.\n\n### Why is this bad?\nThe function should almost definitely be marked `unsafe`, since for an\narbitrary raw pointer, there is no way of telling for sure if it is valid.\n\nIn general, this lint should **never be disabled** unless it is definitely a\nfalse positive (please submit an issue if so) since it breaks Rust's\nsoundness guarantees, directly exposing API users to potentially dangerous\nprogram behavior. This is also true for internal APIs, as it is easy to leak\nunsoundness.\n\n### Context\nIn Rust, an `unsafe {...}` block is used to indicate that the code in that\nsection has been verified in some way that the compiler can not. For a\nfunction that accepts a raw pointer then accesses the pointer's data, this is\ngenerally impossible as the incoming pointer could point anywhere, valid or\nnot. So, the signature should be marked `unsafe fn`: this indicates that the\nfunction's caller must provide some verification that the arguments it sends\nare valid (and then call the function within an `unsafe` block).\n\n### Known problems\n* It does not check functions recursively so if the pointer is passed to a\nprivate non-`unsafe` function which does the dereferencing, the lint won't\ntrigger (false negative).\n* It only checks for arguments whose type are raw pointers, not raw pointers\ngot from an argument in some other way (`fn foo(bar: &[*const u8])` or\n`some_argument.get_raw_ptr()`) (false negative).\n\n### Example\n```rust\npub fn foo(x: *const u8) {\n println!(\"{}\", unsafe { *x });\n}\n\n// this call \"looks\" safe but will segfault or worse!\n// foo(invalid_ptr);\n```\n\nUse instead:\n```rust\npub unsafe fn foo(x: *const u8) {\n println!(\"{}\", unsafe { *x });\n}\n\n// this would cause a compiler error for calling without `unsafe`\n// foo(invalid_ptr);\n\n// sound call if the caller knows the pointer is valid\nunsafe { foo(valid_ptr); }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "obfuscated_if_else",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2447
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.then_some(..).unwrap_or(..)`\n\n### Why is this bad?\nThis can be written more clearly with `if .. else ..`\n\n### Limitations\nThis lint currently only looks for usages of\n`.then_some(..).unwrap_or(..)`, but will be expanded\nto account for similar patterns.\n\n### Example\n```rust\nlet x = true;\nx.then_some(\"a\").unwrap_or(\"b\");\n```\nUse instead:\n```rust\nlet x = true;\nif x { \"a\" } else { \"b\" };\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "octal_escapes",
|
||
"id_span": {
|
||
"path": "src/octal_escapes.rs",
|
||
"line": 46
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `\\0` escapes in string and byte literals that look like octal\ncharacter escapes in C.\n\n### Why is this bad?\n\nC and other languages support octal character escapes in strings, where\na backslash is followed by up to three octal digits. For example, `\\033`\nstands for the ASCII character 27 (ESC). Rust does not support this\nnotation, but has the escape code `\\0` which stands for a null\nbyte/character, and any following digits do not form part of the escape\nsequence. Therefore, `\\033` is not a compiler error but the result may\nbe surprising.\n\n### Known problems\nThe actual meaning can be the intended one. `\\x00` can be used in these\ncases to be unambiguous.\n\nThe lint does not trigger for format strings in `print!()`, `write!()`\nand friends since the string is already preprocessed when Clippy lints\ncan see it.\n\n### Example\n```rust\nlet one = \"\\033[1m Bold? \\033[0m\"; // \\033 intended as escape\nlet two = \"\\033\\0\"; // \\033 intended as null-3-3\n```\n\nUse instead:\n```rust\nlet one = \"\\x1b[1mWill this be bold?\\x1b[0m\";\nlet two = \"\\x0033\\x00\";\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "ok_expect",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 470
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `ok().expect(..)`.\n\n### Why is this bad?\nBecause you usually call `expect()` on the `Result`\ndirectly to get a better error message.\n\n### Known problems\nThe error type needs to implement `Debug`\n\n### Example\n```rust\nx.ok().expect(\"why did I do this again?\");\n```\n\nUse instead:\n```rust\nx.expect(\"why did I do this again?\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "only_used_in_recursion",
|
||
"id_span": {
|
||
"path": "src/only_used_in_recursion.rs",
|
||
"line": 82
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for arguments that are only used in recursion with no side-effects.\n\n### Why is this bad?\nIt could contain a useless calculation and can make function simpler.\n\nThe arguments can be involved in calculations and assignments but as long as\nthe calculations have no side-effects (function calls or mutating dereference)\nand the assigned variables are also only in recursion, it is useless.\n\n### Known problems\nToo many code paths in the linting code are currently untested and prone to produce false\npositives or are prone to have performance implications.\n\nIn some cases, this would not catch all useless arguments.\n\n```rust\nfn foo(a: usize, b: usize) -> usize {\n let f = |x| x + 1;\n\n if a == 0 {\n 1\n } else {\n foo(a - 1, f(b))\n }\n}\n```\n\nFor example, the argument `b` is only used in recursion, but the lint would not catch it.\n\nList of some examples that can not be caught:\n- binary operation of non-primitive types\n- closure usage\n- some `break` relative operations\n- struct pattern binding\n\nAlso, when you recurse the function name with path segments, it is not possible to detect.\n\n### Example\n```rust\nfn f(a: usize, b: usize) -> usize {\n if a == 0 {\n 1\n } else {\n f(a - 1, b + 1)\n }\n}\n```\nUse instead:\n```rust\nfn f(a: usize) -> usize {\n if a == 0 {\n 1\n } else {\n f(a - 1)\n }\n}\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "op_ref",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 422
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for arguments to `==` which have their address\ntaken to satisfy a bound\nand suggests to dereference the other argument instead\n\n### Why is this bad?\nIt is more idiomatic to dereference the other argument.\n\n### Example\n```rust\n&x == y\n```\n\nUse instead:\n```rust\nx == *y\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_as_ref_cloned",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3967
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.as_ref().cloned()` and `.as_mut().cloned()` on `Option`s\n\n### Why is this bad?\nThis can be written more concisely by cloning the `Option` directly.\n\n### Example\n```rust\nfn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {\n bar.as_ref().cloned()\n}\n```\nUse instead:\n```rust\nfn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {\n bar.clone()\n}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_as_ref_deref",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1799
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str).\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.as_deref()`.\n\n### Example\n```rust\nopt.as_ref().map(String::as_str)\n```\nCan be written as\n```rust\nopt.as_deref()\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_env_unwrap",
|
||
"id_span": {
|
||
"path": "src/option_env_unwrap.rs",
|
||
"line": 29
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro.\n\n### Why is this bad?\nUnwrapping the result of `option_env!` will panic\nat run-time if the environment variable doesn't exist, whereas `env!`\ncatches it at compile-time.\n\n### Example\n```rust\nlet _ = option_env!(\"HOME\").unwrap();\n```\n\nIs better expressed as:\n\n```rust\nlet _ = env!(\"HOME\");\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_filter_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1207
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for iterators of `Option`s using `.filter(Option::is_some).map(Option::unwrap)` that may\nbe replaced with a `.flatten()` call.\n\n### Why is this bad?\n`Option` is like a collection of 0-1 things, so `flatten`\nautomatically does this without suspicious-looking `unwrap` calls.\n\n### Example\n```rust\nlet _ = std::iter::empty::<Option<i32>>().filter(Option::is_some).map(Option::unwrap);\n```\nUse instead:\n```rust\nlet _ = std::iter::empty::<Option<i32>>().flatten();\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_if_let_else",
|
||
"id_span": {
|
||
"path": "src/option_if_let_else.rs",
|
||
"line": 69
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLints usage of `if let Some(v) = ... { y } else { x }` and\n`match .. { Some(v) => y, None/_ => x }` which are more\nidiomatically done with `Option::map_or` (if the else bit is a pure\nexpression) or `Option::map_or_else` (if the else bit is an impure\nexpression).\n\n### Why is this bad?\nUsing the dedicated functions of the `Option` type is clearer and\nmore concise than an `if let` expression.\n\n### Notes\nThis lint uses a deliberately conservative metric for checking if the\ninside of either body contains loop control expressions `break` or\n`continue` (which cannot be used within closures). If these are found,\nthis lint will not be raised.\n\n### Example\n```rust\nlet _ = if let Some(foo) = optional {\n foo\n} else {\n 5\n};\nlet _ = match optional {\n Some(val) => val + 1,\n None => 5\n};\nlet _ = if let Some(foo) = optional {\n foo\n} else {\n let y = do_complicated_function();\n y*y\n};\n```\n\nshould be\n\n```rust\nlet _ = optional.map_or(5, |foo| foo);\nlet _ = optional.map_or(5, |val| val + 1);\nlet _ = optional.map_or_else(||{\n let y = do_complicated_function();\n y*y\n}, |foo| foo);\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_map_or_err_ok",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3811
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.map_or(Err(_), Ok)`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.ok_or(_)`.\n\n### Example\n```rust\nopt.map_or(Err(\"error\"), Ok);\n```\n\nUse instead:\n```rust\nopt.ok_or(\"error\");\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_map_or_none",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 596
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.map_or(None, _)`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.and_then(_)`.\n\n### Known problems\nThe order of the arguments is not in execution order.\n\n### Example\n```rust\nopt.map_or(None, |a| Some(a + 1));\n```\n\nUse instead:\n```rust\nopt.and_then(|a| Some(a + 1));\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_map_unit_fn",
|
||
"id_span": {
|
||
"path": "src/map_unit_fn.rs",
|
||
"line": 49
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `option.map(f)` where f is a function\nor closure that returns the unit type `()`.\n\n### Why is this bad?\nReadability, this can be written more clearly with\nan if let statement\n\n### Example\n```rust\nlet x: Option<String> = do_stuff();\nx.map(log_err_msg);\nx.map(|msg| log_err_msg(format_msg(msg)));\n```\n\nThe correct use would be:\n\n```rust\nlet x: Option<String> = do_stuff();\nif let Some(msg) = x {\n log_err_msg(msg);\n}\n\nif let Some(msg) = x {\n log_err_msg(format_msg(msg));\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "option_option",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 120
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Option<Option<_>>` in function signatures and type\ndefinitions\n\n### Why is this bad?\n`Option<_>` represents an optional value. `Option<Option<_>>`\nrepresents an optional value which itself wraps an optional. This is logically the\nsame thing as an optional value but has an unneeded extra level of wrapping.\n\nIf you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases,\nconsider a custom `enum` instead, with clear names for each case.\n\n### Example\n```rust\nfn get_data() -> Option<Option<u32>> {\n None\n}\n```\n\nBetter:\n\n```rust\npub enum Contents {\n Data(Vec<u8>), // Was Some(Some(Vec<u8>))\n NotYetFetched, // Was Some(None)\n None, // Was None\n}\n\nfn get_data() -> Contents {\n Contents::None\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "or_fun_call",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 928
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,\n`.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,\n`.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`\netc. instead.\n\n### Why is this bad?\nThe function will always be called. This is only bad if it allocates or\ndoes some non-trivial amount of work.\n\n### Known problems\nIf the function has side-effects, not calling it will change the\nsemantic of the program, but you shouldn't rely on that.\n\nThe lint also cannot figure out whether the function you call is\nactually expensive to call or not.\n\n### Example\n```rust\nfoo.unwrap_or(String::from(\"empty\"));\n```\n\nUse instead:\n```rust\nfoo.unwrap_or_else(|| String::from(\"empty\"));\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "or_then_unwrap",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 964
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.or(…).unwrap()` calls to Options and Results.\n\n### Why is this bad?\nYou should use `.unwrap_or(…)` instead for clarity.\n\n### Example\n```rust\n// Result\nlet value = result.or::<Error>(Ok(fallback)).unwrap();\n\n// Option\nlet value = option.or(Some(fallback)).unwrap();\n```\nUse instead:\n```rust\n// Result\nlet value = result.unwrap_or(fallback);\n\n// Option\nlet value = option.unwrap_or(fallback);\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "out_of_bounds_indexing",
|
||
"id_span": {
|
||
"path": "src/indexing_slicing.rs",
|
||
"line": 37
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for out of bounds array indexing with a constant\nindex.\n\n### Why is this bad?\nThis will always panic at runtime.\n\n### Example\n```rust\nlet x = [1, 2, 3, 4];\n\nx[9];\n&x[2..9];\n```\n\nUse instead:\n```rust\n// Index within bounds\n\nx[0];\nx[3];\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "overflow_check_conditional",
|
||
"id_span": {
|
||
"path": "src/overflow_check_conditional.rs",
|
||
"line": 22
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects classic underflow/overflow checks.\n\n### Why is this bad?\nMost classic C underflow/overflow checks will fail in\nRust. Users can use functions like `overflowing_*` and `wrapping_*` instead.\n\n### Example\n```rust\na + b < a;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "overly_complex_bool_expr",
|
||
"id_span": {
|
||
"path": "src/booleans.rs",
|
||
"line": 66
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for boolean expressions that contain terminals that\ncan be eliminated.\n\n### Why is this bad?\nThis is most likely a logic bug.\n\n### Known problems\nIgnores short circuiting behavior.\n\n### Example\n```rust\n// The `b` is unnecessary, the expression is equivalent to `if a`.\nif a && b || a { ... }\n```\n\nUse instead:\n```rust\nif a {}\n```\n### Past names\n\n* `logic_bug`\n\n",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
},
|
||
"former_ids": [
|
||
"logic_bug"
|
||
]
|
||
},
|
||
{
|
||
"id": "panic",
|
||
"id_span": {
|
||
"path": "src/panic_unimplemented.rs",
|
||
"line": 19
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `panic!`.\n\n### Why is this bad?\n`panic!` will stop the execution of the executable.\n\n### Example\n```rust\npanic!(\"even with a good reason\");\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "panic_in_result_fn",
|
||
"id_span": {
|
||
"path": "src/panic_in_result_fn.rs",
|
||
"line": 38
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `panic!` or assertions in a function of type result.\n\n### Why is this bad?\nFor some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided.\n\n### Known problems\nFunctions called from a function returning a `Result` may invoke a panicking macro. This is not checked.\n\n### Example\n```rust\nfn result_with_panic() -> Result<bool, String>\n{\n panic!(\"error\");\n}\n```\nUse instead:\n```rust\nfn result_without_panic() -> Result<bool, String> {\n Err(String::from(\"error\"))\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "panicking_unwrap",
|
||
"id_span": {
|
||
"path": "src/unwrap.rs",
|
||
"line": 72
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for calls of `unwrap[_err]()` that will always fail.\n\n### Why is this bad?\nIf panicking is desired, an explicit `panic!()` should be used.\n\n### Known problems\nThis lint only checks `if` conditions not assignments.\nSo something like `let x: Option<()> = None; x.unwrap();` will not be recognized.\n\n### Example\n```rust\nif option.is_none() {\n do_something_with(option.unwrap())\n}\n```\n\nThis code will always panic. The if condition should probably be inverted.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "partial_pub_fields",
|
||
"id_span": {
|
||
"path": "src/partial_pub_fields.rs",
|
||
"line": 35
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks whether partial fields of a struct are public.\n\nEither make all fields of a type public, or make none of them public\n\n### Why is this bad?\nMost types should either be:\n* Abstract data types: complex objects with opaque implementation which guard\ninterior invariants and expose intentionally limited API to the outside world.\n* Data: relatively simple objects which group a bunch of related attributes together.\n\n### Example\n```rust\npub struct Color {\n pub r: u8,\n pub g: u8,\n b: u8,\n}\n```\nUse instead:\n```rust\npub struct Color {\n pub r: u8,\n pub g: u8,\n pub b: u8,\n}\n```",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "partialeq_ne_impl",
|
||
"id_span": {
|
||
"path": "src/partialeq_ne_impl.rs",
|
||
"line": 27
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for manual re-implementations of `PartialEq::ne`.\n\n### Why is this bad?\n`PartialEq::ne` is required to always return the\nnegated result of `PartialEq::eq`, which is exactly what the default\nimplementation does. Therefore, there should never be any need to\nre-implement it.\n\n### Example\n```rust\nstruct Foo;\n\nimpl PartialEq for Foo {\n fn eq(&self, other: &Foo) -> bool { true }\n fn ne(&self, other: &Foo) -> bool { !(self == other) }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "partialeq_to_none",
|
||
"id_span": {
|
||
"path": "src/partialeq_to_none.rs",
|
||
"line": 36
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for binary comparisons to a literal `Option::None`.\n\n### Why is this bad?\n\nA programmer checking if some `foo` is `None` via a comparison `foo == None`\nis usually inspired from other programming languages (e.g. `foo is None`\nin Python).\nChecking if a value of type `Option<T>` is (not) equal to `None` in that\nway relies on `T: PartialEq` to do the comparison, which is unneeded.\n\n### Example\n```rust\nfn foo(f: Option<u32>) -> &'static str {\n if f != None { \"yay\" } else { \"nay\" }\n}\n```\nUse instead:\n```rust\nfn foo(f: Option<u32>) -> &'static str {\n if f.is_some() { \"yay\" } else { \"nay\" }\n}\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "path_buf_push_overwrite",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2903
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)\ncalls on `PathBuf` that can cause overwrites.\n\n### Why is this bad?\nCalling `push` with a root path at the start can overwrite the\nprevious defined path.\n\n### Example\n```rust\nuse std::path::PathBuf;\n\nlet mut x = PathBuf::from(\"/foo\");\nx.push(\"/bar\");\nassert_eq!(x, PathBuf::from(\"/bar\"));\n```\nCould be written:\n\n```rust\nuse std::path::PathBuf;\n\nlet mut x = PathBuf::from(\"/foo\");\nx.push(\"bar\");\nassert_eq!(x, PathBuf::from(\"/foo/bar\"));\n```",
|
||
"version": "1.36.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "path_ends_with_ext",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3669
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for calls to `Path::ends_with` calls where the argument looks like a file extension.\n\nBy default, Clippy has a short list of known filenames that start with a dot\nbut aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.\nThe `allowed-dotfiles` configuration can be used to allow additional\nfile extensions that Clippy should not lint.\n\n### Why is this bad?\nThis doesn't actually compare file extensions. Rather, `ends_with` compares the given argument\nto the last **component** of the path and checks if it matches exactly.\n\n### Known issues\nFile extensions are often at most three characters long, so this only lints in those cases\nin an attempt to avoid false positives.\nAny extension names longer than that are assumed to likely be real path components and are\ntherefore ignored.\n\n### Example\n```rust\nfn is_markdown(path: &Path) -> bool {\n path.ends_with(\".md\")\n}\n```\nUse instead:\n```rust\nfn is_markdown(path: &Path) -> bool {\n path.extension().is_some_and(|ext| ext == \"md\")\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-dotfiles`: Additional dotfiles (files or directories starting with a dot) to allow (default: `[]`)",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "pattern_type_mismatch",
|
||
"id_span": {
|
||
"path": "src/pattern_type_mismatch.rs",
|
||
"line": 78
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for patterns that aren't exact representations of the types\nthey are applied to.\n\nTo satisfy this lint, you will have to adjust either the expression that is matched\nagainst or the pattern itself, as well as the bindings that are introduced by the\nadjusted patterns. For matching you will have to either dereference the expression\nwith the `*` operator, or amend the patterns to explicitly match against `&<pattern>`\nor `&mut <pattern>` depending on the reference mutability. For the bindings you need\nto use the inverse. You can leave them as plain bindings if you wish for the value\nto be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct\na reference into the matched structure.\n\nIf you are looking for a way to learn about ownership semantics in more detail, it\nis recommended to look at IDE options available to you to highlight types, lifetimes\nand reference semantics in your code. The available tooling would expose these things\nin a general way even outside of the various pattern matching mechanics. Of course\nthis lint can still be used to highlight areas of interest and ensure a good understanding\nof ownership semantics.\n\n### Why is this bad?\nIt isn't bad in general. But in some contexts it can be desirable\nbecause it increases ownership hints in the code, and will guard against some changes\nin ownership.\n\n### Example\nThis example shows the basic adjustments necessary to satisfy the lint. Note how\nthe matched expression is explicitly dereferenced with `*` and the `inner` variable\nis bound to a shared borrow via `ref inner`.\n\n```rust\n// Bad\nlet value = &Some(Box::new(23));\nmatch value {\n Some(inner) => println!(\"{}\", inner),\n None => println!(\"none\"),\n}\n\n// Good\nlet value = &Some(Box::new(23));\nmatch *value {\n Some(ref inner) => println!(\"{}\", inner),\n None => println!(\"none\"),\n}\n```\n\nThe following example demonstrates one of the advantages of the more verbose style.\nNote how the second version uses `ref mut a` to explicitly declare `a` a shared mutable\nborrow, while `b` is simply taken by value. This ensures that the loop body cannot\naccidentally modify the wrong part of the structure.\n\n```rust\n// Bad\nlet mut values = vec![(2, 3), (3, 4)];\nfor (a, b) in &mut values {\n *a += *b;\n}\n\n// Good\nlet mut values = vec![(2, 3), (3, 4)];\nfor &mut (ref mut a, b) in &mut values {\n *a += b;\n}\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "permissions_set_readonly_false",
|
||
"id_span": {
|
||
"path": "src/permissions_set_readonly_false.rs",
|
||
"line": 25
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `std::fs::Permissions.set_readonly` with argument `false`.\n\n### Why is this bad?\nOn Unix platforms this results in the file being world writable,\nequivalent to `chmod a+w <file>`.\n### Example\n```rust\nuse std::fs::File;\nlet f = File::create(\"foo.txt\").unwrap();\nlet metadata = f.metadata().unwrap();\nlet mut permissions = metadata.permissions();\npermissions.set_readonly(false);\n```",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "possible_missing_comma",
|
||
"id_span": {
|
||
"path": "src/formatting.rs",
|
||
"line": 111
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for possible missing comma in an array. It lints if\nan array element is a binary operator expression and it lies on two lines.\n\n### Why is this bad?\nThis could lead to unexpected results.\n\n### Example\n```rust\nlet a = &[\n -1, -2, -3 // <= no comma here\n -4, -5, -6\n];\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "precedence",
|
||
"id_span": {
|
||
"path": "src/precedence.rs",
|
||
"line": 46
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for operations where precedence may be unclear\nand suggests to add parentheses. Currently it catches the following:\n* mixed usage of arithmetic and bit shifting/combining operators without\nparentheses\n* a \"negative\" numeric literal (which is really a unary `-` followed by a\nnumeric literal)\n followed by a method call\n\n### Why is this bad?\nNot everyone knows the precedence of those operators by\nheart, so expressions like these may trip others trying to reason about the\ncode.\n\n### Example\n* `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7\n* `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "print_in_format_impl",
|
||
"id_span": {
|
||
"path": "src/format_impl.rs",
|
||
"line": 87
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `println`, `print`, `eprintln` or `eprint` in an\nimplementation of a formatting trait.\n\n### Why is this bad?\nUsing a print macro is likely unintentional since formatting traits\nshould write to the `Formatter`, not stdout/stderr.\n\n### Example\n```rust\nuse std::fmt::{Display, Error, Formatter};\n\nstruct S;\nimpl Display for S {\n fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n println!(\"S\");\n\n Ok(())\n }\n}\n```\nUse instead:\n```rust\nuse std::fmt::{Display, Error, Formatter};\n\nstruct S;\nimpl Display for S {\n fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n writeln!(f, \"S\");\n\n Ok(())\n }\n}\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "print_literal",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 146
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns about the use of literals as `print!`/`println!` args.\n\n### Why is this bad?\nUsing literals as `println!` args is inefficient\n(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary\n(i.e., just put the literal in the format string)\n\n### Example\n```rust\nprintln!(\"{}\", \"foo\");\n```\nuse the literal without formatting:\n```rust\nprintln!(\"foo\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "print_stderr",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 103
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for printing on *stderr*. The purpose of this lint\nis to catch debugging remnants.\n\n### Why is this bad?\nPeople often print on *stderr* while debugging an\napplication and might forget to remove those prints afterward.\n\n### Known problems\nOnly catches `eprint!` and `eprintln!` calls.\n\n### Example\n```rust\neprintln!(\"Hello world!\");\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-print-in-tests`: Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` (default: `false`)",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "print_stdout",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 81
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for printing on *stdout*. The purpose of this lint\nis to catch debugging remnants.\n\n### Why is this bad?\nPeople often print on *stdout* while debugging an\napplication and might forget to remove those prints afterward.\n\n### Known problems\nOnly catches `print!` and `println!` calls.\n\n### Example\n```rust\nprintln!(\"Hello world!\");\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-print-in-tests`: Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` (default: `false`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "print_with_newline",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 59
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns when you use `print!()` with a format\nstring that ends in a newline.\n\n### Why is this bad?\nYou should use `println!()` instead, which appends the\nnewline.\n\n### Example\n```rust\nprint!(\"Hello {}!\\n\", name);\n```\nuse println!() instead\n```rust\nprintln!(\"Hello {}!\", name);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "println_empty_string",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 34
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns when you use `println!(\"\")` to\nprint a newline.\n\n### Why is this bad?\nYou should use `println!()`, which is simpler.\n\n### Example\n```rust\nprintln!(\"\");\n```\n\nUse instead:\n```rust\nprintln!();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "ptr_arg",
|
||
"id_span": {
|
||
"path": "src/ptr.rs",
|
||
"line": 64
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint checks for function arguments of type `&String`, `&Vec`,\n`&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls\nwith the appropriate `.to_owned()`/`to_string()` calls.\n\n### Why is this bad?\nRequiring the argument to be of the specific size\nmakes the function less useful for no benefit; slices in the form of `&[T]`\nor `&str` usually suffice and can be obtained from other types, too.\n\n### Known problems\nThere may be `fn(&Vec)`-typed references pointing to your function.\nIf you have them, you will get a compiler error after applying this lint's\nsuggestions. You then have the choice to undo your changes or change the\ntype of the reference.\n\nNote that if the function is part of your public interface, there may be\nother crates referencing it, of which you may not be aware. Carefully\ndeprecate the function before applying the lint suggestions in this case.\n\n### Example\n```rust\nfn foo(&Vec<u32>) { .. }\n```\n\nUse instead:\n```rust\nfn foo(&[u32]) { .. }\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "ptr_as_ptr",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 396
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `as` casts between raw pointers without changing its mutability,\nnamely `*const T` to `*const U` and `*mut T` to `*mut U`.\n\n### Why is this bad?\nThough `as` casts between raw pointers are not terrible, `pointer::cast` is safer because\nit cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.\n\n### Example\n```rust\nlet ptr: *const u32 = &42_u32;\nlet mut_ptr: *mut u32 = &mut 42_u32;\nlet _ = ptr as *const i32;\nlet _ = mut_ptr as *mut i32;\n```\nUse instead:\n```rust\nlet ptr: *const u32 = &42_u32;\nlet mut_ptr: *mut u32 = &mut 42_u32;\nlet _ = ptr.cast::<i32>();\nlet _ = mut_ptr.cast::<i32>();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "ptr_cast_constness",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 424
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `as` casts between raw pointers which change its constness, namely `*const T` to\n`*mut T` and `*mut T` to `*const T`.\n\n### Why is this bad?\nThough `as` casts between raw pointers are not terrible, `pointer::cast_mut` and\n`pointer::cast_const` are safer because they cannot accidentally cast the pointer to another\ntype.\n\n### Example\n```rust\nlet ptr: *const u32 = &42_u32;\nlet mut_ptr = ptr as *mut u32;\nlet ptr = mut_ptr as *const u32;\n```\nUse instead:\n```rust\nlet ptr: *const u32 = &42_u32;\nlet mut_ptr = ptr.cast_mut();\nlet ptr = mut_ptr.cast_const();\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "ptr_eq",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 727
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nUse `std::ptr::eq` when applicable\n\n### Why is this bad?\n`ptr::eq` can be used to compare `&T` references\n(which coerce to `*const T` implicitly) by their address rather than\ncomparing the values they point to.\n\n### Example\n```rust\nlet a = &[1, 2, 3];\nlet b = &[1, 2, 3];\n\nassert!(a as *const _ as usize == b as *const _ as usize);\n```\nUse instead:\n```rust\nlet a = &[1, 2, 3];\nlet b = &[1, 2, 3];\n\nassert!(std::ptr::eq(a, b));\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "ptr_offset_with_cast",
|
||
"id_span": {
|
||
"path": "src/ptr_offset_with_cast.rs",
|
||
"line": 42
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of the `offset` pointer method with a `usize` casted to an\n`isize`.\n\n### Why is this bad?\nIf we’re always increasing the pointer address, we can avoid the numeric\ncast by using the `add` method instead.\n\n### Example\n```rust\nlet vec = vec![b'a', b'b', b'c'];\nlet ptr = vec.as_ptr();\nlet offset = 1_usize;\n\nunsafe {\n ptr.offset(offset as isize);\n}\n```\n\nCould be written:\n\n```rust\nlet vec = vec![b'a', b'b', b'c'];\nlet ptr = vec.as_ptr();\nlet offset = 1_usize;\n\nunsafe {\n ptr.add(offset);\n}\n```",
|
||
"version": "1.30.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "pub_enum_variant_names",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 203
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThe `avoid_breaking_exported_api` config option was added, which\nenables the `enum_variant_names` lint for public items.",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "pub_underscore_fields",
|
||
"id_span": {
|
||
"path": "src/pub_underscore_fields.rs",
|
||
"line": 39
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks whether any field of the struct is prefixed with an `_` (underscore) and also marked\n`pub` (public)\n\n### Why is this bad?\nFields prefixed with an `_` are inferred as unused, which suggests it should not be marked\nas `pub`, because marking it as `pub` infers it will be used.\n\n### Example\n```rust\nstruct FileHandle {\n pub _descriptor: usize,\n}\n```\nUse instead:\n```rust\nstruct FileHandle {\n _descriptor: usize,\n}\n```\n\nOR\n\n```rust\nstruct FileHandle {\n pub descriptor: usize,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `pub-underscore-fields-behavior`: Lint \"public\" fields in a struct that are prefixed with an underscore based on their\n exported visibility, or whether they are marked as \"pub\". (default: `\"PubliclyExported\"`)",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "pub_use",
|
||
"id_span": {
|
||
"path": "src/pub_use.rs",
|
||
"line": 36
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nRestricts the usage of `pub use ...`\n\n### Why is this bad?\n\n`pub use` is usually fine, but a project may wish to limit `pub use` instances to prevent\nunintentional exports or to encourage placing exported items directly in public modules\n\n### Example\n```rust\npub mod outer {\n mod inner {\n pub struct Test {}\n }\n pub use inner::Test;\n}\n\nuse outer::Test;\n```\nUse instead:\n```rust\npub mod outer {\n pub struct Test {}\n}\n\nuse outer::Test;\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "pub_with_shorthand",
|
||
"id_span": {
|
||
"path": "src/visibility.rs",
|
||
"line": 49
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `pub(<loc>)` with `in`.\n\n### Why is this bad?\nConsistency. Use it or don't, just be consistent about it.\n\nAlso see the `pub_without_shorthand` lint for an alternative.\n\n### Example\n```rust\npub(super) type OptBox<T> = Option<Box<T>>;\n```\nUse instead:\n```rust\npub(in super) type OptBox<T> = Option<Box<T>>;\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "pub_without_shorthand",
|
||
"id_span": {
|
||
"path": "src/visibility.rs",
|
||
"line": 74
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `pub(<loc>)` without `in`.\n\nNote: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on\n`pub(super)` and the like.\n\n### Why is this bad?\nConsistency. Use it or don't, just be consistent about it.\n\nAlso see the `pub_with_shorthand` lint for an alternative.\n\n### Example\n```rust\npub(in super) type OptBox<T> = Option<Box<T>>;\n```\nUse instead:\n```rust\npub(super) type OptBox<T> = Option<Box<T>>;\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "question_mark",
|
||
"id_span": {
|
||
"path": "src/question_mark.rs",
|
||
"line": 46
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expressions that could be replaced by the question mark operator.\n\n### Why is this bad?\nQuestion mark usage is more idiomatic.\n\n### Example\n```rust\nif option.is_none() {\n return None;\n}\n```\n\nCould be written:\n\n```rust\noption?;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "question_mark_used",
|
||
"id_span": {
|
||
"path": "src/question_mark_used.rs",
|
||
"line": 28
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for expressions that use the question mark operator and rejects them.\n\n### Why is this bad?\nSometimes code wants to avoid the question mark operator because for instance a local\nblock requires a macro to re-throw errors to attach additional information to the\nerror.\n\n### Example\n```rust\nlet result = expr?;\n```\n\nCould be written:\n\n```rust\nutility_macro!(expr);\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "range_minus_one",
|
||
"id_span": {
|
||
"path": "src/ranges.rs",
|
||
"line": 97
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for inclusive ranges where 1 is subtracted from\nthe upper bound, e.g., `x..=(y-1)`.\n\n### Why is this bad?\nThe code is more readable with an exclusive range\nlike `x..y`.\n\n### Known problems\nThis will cause a warning that cannot be fixed if\nthe consumer of the range only accepts a specific range type, instead of\nthe generic `RangeBounds` trait\n([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).\n\n### Example\n```rust\nfor i in x..=(y-1) {\n // ..\n}\n```\n\nUse instead:\n```rust\nfor i in x..y {\n // ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "range_plus_one",
|
||
"id_span": {
|
||
"path": "src/ranges.rs",
|
||
"line": 59
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for exclusive ranges where 1 is added to the\nupper bound, e.g., `x..(y+1)`.\n\n### Why is this bad?\nThe code is more readable with an inclusive range\nlike `x..=y`.\n\n### Known problems\nWill add unnecessary pair of parentheses when the\nexpression is not wrapped in a pair but starts with an opening parenthesis\nand ends with a closing one.\nI.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.\n\nAlso in many cases, inclusive ranges are still slower to run than\nexclusive ranges, because they essentially add an extra branch that\nLLVM may fail to hoist out of the loop.\n\nThis will cause a warning that cannot be fixed if the consumer of the\nrange only accepts a specific range type, instead of the generic\n`RangeBounds` trait\n([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).\n\n### Example\n```rust\nfor i in x..(y+1) {\n // ..\n}\n```\n\nUse instead:\n```rust\nfor i in x..=y {\n // ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "range_step_by_zero",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 56
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\n`Range::step_by(0)` used to be linted since it's\nan infinite iterator, which is better expressed by `iter::repeat`,\nbut the method has been removed for `Iterator::step_by` which panics\nif given a zero",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "range_zip_with_len",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2928
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for zipping a collection with the range of\n`0.._.len()`.\n\n### Why is this bad?\nThe code is better expressed with `.enumerate()`.\n\n### Example\n```rust\nlet _ = x.iter().zip(0..x.len());\n```\n\nUse instead:\n```rust\nlet _ = x.iter().enumerate();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "rc_buffer",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 246
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`.\n\n### Why is this bad?\nExpressions such as `Rc<String>` usually have no advantage over `Rc<str>`, since\nit is larger and involves an extra level of indirection, and doesn't implement `Borrow<str>`.\n\nWhile mutating a buffer type would still be possible with `Rc::get_mut()`, it only\nworks if there are no additional references yet, which usually defeats the purpose of\nenclosing it in a shared ownership type. Instead, additionally wrapping the inner\ntype with an interior mutable container (such as `RefCell` or `Mutex`) would normally\nbe used.\n\n### Known problems\nThis pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for\ncases where mutation only happens before there are any additional references.\n\n### Example\n```rust\nfn foo(interned: Rc<String>) { ... }\n```\n\nBetter:\n\n```rust\nfn foo(interned: Rc<str>) { ... }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "rc_clone_in_vec_init",
|
||
"id_span": {
|
||
"path": "src/rc_clone_in_vec_init.rs",
|
||
"line": 44
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`)\nin `vec![elem; len]`\n\n### Why is this bad?\nThis will create `elem` once and clone it `len` times - doing so with `Arc`/`Rc`/`Weak`\nis a bit misleading, as it will create references to the same pointer, rather\nthan different instances.\n\n### Example\n```rust\nlet v = vec![std::sync::Arc::new(\"some data\".to_string()); 100];\n// or\nlet v = vec![std::rc::Rc::new(\"some data\".to_string()); 100];\n```\nUse instead:\n```rust\n// Initialize each value separately:\nlet mut data = Vec::with_capacity(100);\nfor _ in 0..100 {\n data.push(std::rc::Rc::new(\"some data\".to_string()));\n}\n\n// Or if you want clones of the same reference,\n// Create the reference beforehand to clarify that\n// it should be cloned for each value\nlet data = std::rc::Rc::new(\"some data\".to_string());\nlet v = vec![data; 100];\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "rc_mutex",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 301
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `Rc<Mutex<T>>`.\n\n### Why is this bad?\n`Rc` is used in single thread and `Mutex` is used in multi thread.\nConsider using `Rc<RefCell<T>>` in single thread or `Arc<Mutex<T>>` in multi thread.\n\n### Known problems\nSometimes combining generic types can lead to the requirement that a\ntype use Rc in conjunction with Mutex. We must consider those cases false positives, but\nalas they are quite hard to rule out. Luckily they are also rare.\n\n### Example\n```rust\nuse std::rc::Rc;\nuse std::sync::Mutex;\nfn foo(interned: Rc<Mutex<i32>>) { ... }\n```\n\nBetter:\n\n```rust\nuse std::rc::Rc;\nuse std::cell::RefCell\nfn foo(interned: Rc<RefCell<i32>>) { ... }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "read_line_without_trim",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3460
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nLooks for calls to [`Stdin::read_line`] to read a line from the standard input\ninto a string, then later attempting to use that string for an operation that will never\nwork for strings with a trailing newline character in it (e.g. parsing into a `i32`).\n\n### Why is this bad?\nThe operation will always fail at runtime no matter what the user enters, thus\nmaking it a useless operation.\n\n### Example\n```rust\nlet mut input = String::new();\nstd::io::stdin().read_line(&mut input).expect(\"Failed to read a line\");\nlet num: i32 = input.parse().expect(\"Not a number!\");\nassert_eq!(num, 42); // we never even get here!\n```\nUse instead:\n```rust\nlet mut input = String::new();\nstd::io::stdin().read_line(&mut input).expect(\"Failed to read a line\");\nlet num: i32 = input.trim_end().parse().expect(\"Not a number!\");\n// ^^^^^^^^^^^ remove the trailing newline\nassert_eq!(num, 42);\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "read_zero_byte_vec",
|
||
"id_span": {
|
||
"path": "src/read_zero_byte_vec.rs",
|
||
"line": 46
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint catches reads into a zero-length `Vec`.\nEspecially in the case of a call to `with_capacity`, this lint warns that read\ngets the number of bytes from the `Vec`'s length, not its capacity.\n\n### Why is this bad?\nReading zero bytes is almost certainly not the intended behavior.\n\n### Known problems\nIn theory, a very unusual read implementation could assign some semantic meaning\nto zero-byte reads. But it seems exceptionally unlikely that code intending to do\na zero-byte read would allocate a `Vec` for it.\n\n### Example\n```rust\nuse std::io;\nfn foo<F: io::Read>(mut f: F) {\n let mut data = Vec::with_capacity(100);\n f.read(&mut data).unwrap();\n}\n```\nUse instead:\n```rust\nuse std::io;\nfn foo<F: io::Read>(mut f: F) {\n let mut data = Vec::with_capacity(100);\n data.resize(100, 0);\n f.read(&mut data).unwrap();\n}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "readonly_write_lock",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3606
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for calls to `RwLock::write` where the lock is only used for reading.\n\n### Why is this bad?\nThe write portion of `RwLock` is exclusive, meaning that no other thread\ncan access the lock while this writer is active.\n\n### Example\n```rust\nuse std::sync::RwLock;\nfn assert_is_zero(lock: &RwLock<i32>) {\n let num = lock.write().unwrap();\n assert_eq!(*num, 0);\n}\n```\n\nUse instead:\n```rust\nuse std::sync::RwLock;\nfn assert_is_zero(lock: &RwLock<i32>) {\n let num = lock.read().unwrap();\n assert_eq!(*num, 0);\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "recursive_format_impl",
|
||
"id_span": {
|
||
"path": "src/format_impl.rs",
|
||
"line": 46
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for format trait implementations (e.g. `Display`) with a recursive call to itself\nwhich uses `self` as a parameter.\nThis is typically done indirectly with the `write!` macro or with `to_string()`.\n\n### Why is this bad?\nThis will lead to infinite recursion and a stack overflow.\n\n### Example\n\n```rust\nuse std::fmt;\n\nstruct Structure(i32);\nimpl fmt::Display for Structure {\n fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n write!(f, \"{}\", self.to_string())\n }\n}\n\n```\nUse instead:\n```rust\nuse std::fmt;\n\nstruct Structure(i32);\nimpl fmt::Display for Structure {\n fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n write!(f, \"{}\", self.0)\n }\n}\n```\n### Past names\n\n* `to_string_in_display`\n\n",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"to_string_in_display"
|
||
]
|
||
},
|
||
{
|
||
"id": "redundant_allocation",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 211
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of redundant allocations anywhere in the code.\n\n### Why is this bad?\nExpressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`,\n`Arc<Arc<T>>`, `Arc<Box<T>>`, `Box<&T>`, `Box<Rc<T>>`, `Box<Arc<T>>`, `Box<Box<T>>`, add an unnecessary level of indirection.\n\n### Example\n```rust\nfn foo(bar: Rc<&usize>) {}\n```\n\nBetter:\n\n```rust\nfn foo(bar: &usize) {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_as_str",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3697
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `as_str()` on a `String` chained with a method available on the `String` itself.\n\n### Why is this bad?\nThe `as_str()` conversion is pointless and can be removed for simplicity and cleanliness.\n\n### Example\n```rust\nlet owned_string = \"This is a string\".to_owned();\nowned_string.as_str().as_bytes()\n```\n\nUse instead:\n```rust\nlet owned_string = \"This is a string\".to_owned();\nowned_string.as_bytes()\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_async_block",
|
||
"id_span": {
|
||
"path": "src/redundant_async_block.rs",
|
||
"line": 41
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `async` block that only returns `await` on a future.\n\n### Why is this bad?\nIt is simpler and more efficient to use the future directly.\n\n### Example\n```rust\nlet f = async {\n 1 + 2\n};\nlet fut = async {\n f.await\n};\n```\nUse instead:\n```rust\nlet f = async {\n 1 + 2\n};\nlet fut = f;\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_at_rest_pattern",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 347
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `[all @ ..]` patterns.\n\n### Why is this bad?\nIn all cases, `all` works fine and can often make code simpler, as you possibly won't need\nto convert from say a `Vec` to a slice by dereferencing.\n\n### Example\n```rust\nif let [all @ ..] = &*v {\n // NOTE: Type is a slice here\n println!(\"all elements: {all:#?}\");\n}\n```\nUse instead:\n```rust\nif let all = v {\n // NOTE: Type is a `Vec` here\n println!(\"all elements: {all:#?}\");\n}\n// or\nprintln!(\"all elements: {v:#?}\");\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_clone",
|
||
"id_span": {
|
||
"path": "src/redundant_clone.rs",
|
||
"line": 57
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for a redundant `clone()` (and its relatives) which clones an owned\nvalue that is going to be dropped without further use.\n\n### Why is this bad?\nIt is not always possible for the compiler to eliminate useless\nallocations and deallocations generated by redundant `clone()`s.\n\n### Known problems\nFalse-negatives: analysis performed by this lint is conservative and limited.\n\n### Example\n```rust\n{\n let x = Foo::new();\n call(x.clone());\n call(x.clone()); // this can just pass `x`\n}\n\n[\"lorem\", \"ipsum\"].join(\" \").to_string();\n\nPath::new(\"/a/b\").join(\"c\").to_path_buf();\n```",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_closure",
|
||
"id_span": {
|
||
"path": "src/eta_reduction.rs",
|
||
"line": 47
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for closures which just call another function where\nthe function can be called directly. `unsafe` functions, calls where types\nget adjusted or where the callee is marked `#[track_caller]` are ignored.\n\n### Why is this bad?\nNeedlessly creating a closure adds code for no benefit\nand gives the optimizer more work.\n\n### Known problems\nIf creating the closure inside the closure has a side-\neffect then moving the closure creation out will change when that side-\neffect runs.\nSee [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.\n\n### Example\n```rust\nxs.map(|x| foo(x))\n```\n\nUse instead:\n```rust\n// where `foo(_)` is a plain function that takes the exact argument type of `x`.\nxs.map(foo)\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_closure_call",
|
||
"id_span": {
|
||
"path": "src/redundant_closure_call.rs",
|
||
"line": 38
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects closures called in the same expression where they\nare defined.\n\n### Why is this bad?\nIt is unnecessarily adding to the expression's\ncomplexity.\n\n### Example\n```rust\nlet a = (|| 42)();\n```\n\nUse instead:\n```rust\nlet a = 42;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_closure_for_method_calls",
|
||
"id_span": {
|
||
"path": "src/eta_reduction.rs",
|
||
"line": 69
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for closures which only invoke a method on the closure\nargument and can be replaced by referencing the method directly.\n\n### Why is this bad?\nIt's unnecessary to create the closure.\n\n### Example\n```rust\nSome('a').map(|s| s.to_uppercase());\n```\nmay be rewritten as\n```rust\nSome('a').map(char::to_uppercase);\n```",
|
||
"version": "1.35.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_comparisons",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 336
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for ineffective double comparisons against constants.\n\n### Why is this bad?\nOnly one of the comparisons has any effect on the result, the programmer\nprobably intended to flip one of the comparison operators, or compare a\ndifferent value entirely.\n\n### Example\n```rust\nif status_code <= 400 && status_code < 500 {}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_else",
|
||
"id_span": {
|
||
"path": "src/redundant_else.rs",
|
||
"line": 40
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `else` blocks that can be removed without changing semantics.\n\n### Why is this bad?\nThe `else` block adds unnecessary indentation and verbosity.\n\n### Known problems\nSome may prefer to keep the `else` block for clarity.\n\n### Example\n```rust\nfn my_func(count: u32) {\n if count == 0 {\n print!(\"Nothing to do\");\n return;\n } else {\n print!(\"Moving on...\");\n }\n}\n```\nUse instead:\n```rust\nfn my_func(count: u32) {\n if count == 0 {\n print!(\"Nothing to do\");\n return;\n }\n print!(\"Moving on...\");\n}\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_feature_names",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 85
|
||
},
|
||
"group": "cargo",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for feature names with prefix `use-`, `with-` or suffix `-support`\n\n### Why is this bad?\nThese prefixes and suffixes have no significant meaning.\n\n### Example\n```toml\n# The `Cargo.toml` with feature name redundancy\n[features]\ndefault = [\"use-abc\", \"with-def\", \"ghi-support\"]\nuse-abc = [] // redundant\nwith-def = [] // redundant\nghi-support = [] // redundant\n```\n\nUse instead:\n```toml\n[features]\ndefault = [\"abc\", \"def\", \"ghi\"]\nabc = []\ndef = []\nghi = []\n```\n",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_field_names",
|
||
"id_span": {
|
||
"path": "src/redundant_field_names.rs",
|
||
"line": 33
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for fields in struct literals where shorthands\ncould be used.\n\n### Why is this bad?\nIf the field and variable names are the same,\nthe field name is redundant.\n\n### Example\n```rust\nlet bar: u8 = 123;\n\nstruct Foo {\n bar: u8,\n}\n\nlet foo = Foo { bar: bar };\n```\nthe last line can be simplified to\n```rust\nlet foo = Foo { bar };\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_guards",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 972
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary guards in match expressions.\n\n### Why is this bad?\nIt's more complex and much less readable. Making it part of the pattern can improve\nexhaustiveness checking as well.\n\n### Example\n```rust\nmatch x {\n Some(x) if matches!(x, Some(1)) => ..,\n Some(x) if x == Some(2) => ..,\n _ => todo!(),\n}\n```\nUse instead:\n```rust\nmatch x {\n Some(Some(1)) => ..,\n Some(Some(2)) => ..,\n _ => todo!(),\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_locals",
|
||
"id_span": {
|
||
"path": "src/redundant_locals.rs",
|
||
"line": 43
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for redundant redefinitions of local bindings.\n\n### Why is this bad?\nRedundant redefinitions of local bindings do not change behavior and are likely to be unintended.\n\nNote that although these bindings do not affect your code's meaning, they _may_ affect `rustc`'s stack allocation.\n\n### Example\n```rust\nlet a = 0;\nlet a = a;\n\nfn foo(b: i32) {\n let b = b;\n}\n```\nUse instead:\n```rust\nlet a = 0;\n// no redefinition with the same name\n\nfn foo(b: i32) {\n // no redefinition with the same name\n}\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_pattern",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 278
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for patterns in the form `name @ _`.\n\n### Why is this bad?\nIt's almost always more readable to just use direct\nbindings.\n\n### Example\n```rust\nmatch v {\n Some(x) => (),\n y @ _ => (),\n}\n```\n\nUse instead:\n```rust\nmatch v {\n Some(x) => (),\n y => (),\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_pattern_matching",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 527
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLint for redundant pattern matching over `Result`, `Option`,\n`std::task::Poll`, `std::net::IpAddr` or `bool`s\n\n### Why is this bad?\nIt's more concise and clear to just use the proper\nutility function or using the condition directly\n\n### Known problems\nFor suggestions involving bindings in patterns, this will change the drop order for the matched type.\nBoth `if let` and `while let` will drop the value at the end of the block, both `if` and `while` will drop the\nvalue before entering the block. For most types this change will not matter, but for a few\ntypes this will not be an acceptable change (e.g. locks). See the\n[reference](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) for more about\ndrop order.\n\n### Example\n```rust\nif let Ok(_) = Ok::<i32, i32>(42) {}\nif let Err(_) = Err::<i32, i32>(42) {}\nif let None = None::<()> {}\nif let Some(_) = Some(42) {}\nif let Poll::Pending = Poll::Pending::<()> {}\nif let Poll::Ready(_) = Poll::Ready(42) {}\nif let IpAddr::V4(_) = IpAddr::V4(Ipv4Addr::LOCALHOST) {}\nif let IpAddr::V6(_) = IpAddr::V6(Ipv6Addr::LOCALHOST) {}\nmatch Ok::<i32, i32>(42) {\n Ok(_) => true,\n Err(_) => false,\n};\n\nlet cond = true;\nif let true = cond {}\nmatches!(cond, true);\n```\n\nThe more idiomatic use would be:\n\n```rust\nif Ok::<i32, i32>(42).is_ok() {}\nif Err::<i32, i32>(42).is_err() {}\nif None::<()>.is_none() {}\nif Some(42).is_some() {}\nif Poll::Pending::<()>.is_pending() {}\nif Poll::Ready(42).is_ready() {}\nif IpAddr::V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\nif IpAddr::V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\nOk::<i32, i32>(42).is_ok();\n\nlet cond = true;\nif cond {}\ncond;\n```",
|
||
"version": "1.31.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_pub_crate",
|
||
"id_span": {
|
||
"path": "src/redundant_pub_crate.rs",
|
||
"line": 34
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for items declared `pub(crate)` that are not crate visible because they\nare inside a private module.\n\n### Why is this bad?\nWriting `pub(crate)` is misleading when it's redundant due to the parent\nmodule's visibility.\n\n### Example\n```rust\nmod internal {\n pub(crate) fn internal_fn() { }\n}\n```\nThis function is not visible outside the module and it can be declared with `pub` or\nprivate visibility\n```rust\nmod internal {\n pub fn internal_fn() { }\n}\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_slicing",
|
||
"id_span": {
|
||
"path": "src/redundant_slicing.rs",
|
||
"line": 39
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for redundant slicing expressions which use the full range, and\ndo not change the type.\n\n### Why is this bad?\nIt unnecessarily adds complexity to the expression.\n\n### Known problems\nIf the type being sliced has an implementation of `Index<RangeFull>`\nthat actually changes anything then it can't be removed. However, this would be surprising\nto people reading the code and should have a note with it.\n\n### Example\n```rust\nfn get_slice(x: &[u32]) -> &[u32] {\n &x[..]\n}\n```\nUse instead:\n```rust\nfn get_slice(x: &[u32]) -> &[u32] {\n x\n}\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "redundant_static_lifetimes",
|
||
"id_span": {
|
||
"path": "src/redundant_static_lifetimes.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for constants and statics with an explicit `'static` lifetime.\n\n### Why is this bad?\nAdding `'static` to every reference can create very\ncomplicated types.\n\n### Example\n```rust\nconst FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =\n&[...]\nstatic FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =\n&[...]\n```\nThis code can be rewritten as\n```rust\n const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]\n static FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n### Past names\n\n* `const_static_lifetime`\n\n",
|
||
"version": "1.37.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"const_static_lifetime"
|
||
]
|
||
},
|
||
{
|
||
"id": "redundant_type_annotations",
|
||
"id_span": {
|
||
"path": "src/redundant_type_annotations.rs",
|
||
"line": 35
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns about needless / redundant type annotations.\n\n### Why is this bad?\nCode without type annotations is shorter and in most cases\nmore idiomatic and easier to modify.\n\n### Limitations\nThis lint doesn't support:\n\n- Generics\n- Refs returned from anything else than a `MethodCall`\n- Complex types (tuples, arrays, etc...)\n- `Path` to anything else than a primitive type.\n\n### Example\n```rust\nlet foo: String = String::new();\n```\nUse instead:\n```rust\nlet foo = String::new();\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ref_as_ptr",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 712
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for casts of references to pointer using `as`\nand suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead.\n\n### Why is this bad?\nUsing `as` casts may result in silently changing mutability or type.\n\n### Example\n```rust\nlet a_ref = &1;\nlet a_ptr = a_ref as *const _;\n```\nUse instead:\n```rust\nlet a_ref = &1;\nlet a_ptr = std::ptr::from_ref(a_ref);\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "ref_binding_to_reference",
|
||
"id_span": {
|
||
"path": "src/dereference.rs",
|
||
"line": 112
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `ref` bindings which create a reference to a reference.\n\n### Why is this bad?\nThe address-of operator at the use site is clearer about the need for a reference.\n\n### Example\n```rust\nlet x = Some(\"\");\nif let Some(ref x) = x {\n // use `x` here\n}\n```\n\nUse instead:\n```rust\nlet x = Some(\"\");\nif let Some(x) = x {\n // use `&x` here\n}\n```",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "ref_option_ref",
|
||
"id_span": {
|
||
"path": "src/ref_option_ref.rs",
|
||
"line": 31
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `&Option<&T>`.\n\n### Why is this bad?\nSince `&` is Copy, it's useless to have a\nreference on `Option<&T>`.\n\n### Known problems\nIt may be irrelevant to use this lint on\npublic API code as it will make a breaking change to apply it.\n\n### Example\n```rust\nlet x: &Option<&u32> = &Some(&0u32);\n```\nUse instead:\n```rust\nlet x: Option<&u32> = Some(&0u32);\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "ref_patterns",
|
||
"id_span": {
|
||
"path": "src/ref_patterns.rs",
|
||
"line": 23
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usages of the `ref` keyword.\n### Why is this bad?\nThe `ref` keyword can be confusing for people unfamiliar with it, and often\nit is more concise to use `&` instead.\n### Example\n```rust\nlet opt = Some(5);\nif let Some(ref foo) = opt {}\n```\nUse instead:\n```rust\nlet opt = Some(5);\nif let Some(foo) = &opt {}\n```",
|
||
"version": "1.71.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "regex_macro",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 167
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThe regex! macro does not exist anymore.",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "repeat_once",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2960
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.repeat(1)` and suggest the following method for each types.\n- `.to_string()` for `str`\n- `.clone()` for `String`\n- `.to_vec()` for `slice`\n\nThe lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if\nthey are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))\n\n### Why is this bad?\nFor example, `String.repeat(1)` is equivalent to `.clone()`. If cloning\nthe string is the intention behind this, `clone()` should be used.\n\n### Example\n```rust\nfn main() {\n let x = String::from(\"hello world\").repeat(1);\n}\n```\nUse instead:\n```rust\nfn main() {\n let x = String::from(\"hello world\").clone();\n}\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "repeat_vec_with_capacity",
|
||
"id_span": {
|
||
"path": "src/repeat_vec_with_capacity.rs",
|
||
"line": 46
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`.\n\n### Why is this bad?\nThese constructs work by cloning the element, but cloning a `Vec<_>` does not\nrespect the old vector's capacity and effectively discards it.\n\nThis makes `iter::repeat(Vec::with_capacity(x))` especially suspicious because the user most certainly\nexpected that the yielded `Vec<_>` will have the requested capacity, otherwise one can simply write\n`iter::repeat(Vec::new())` instead and it will have the same effect.\n\nSimilarly for `vec![x; n]`, the element `x` is cloned to fill the vec.\nUnlike `iter::repeat` however, the vec repeat macro does not have to clone the value `n` times\nbut just `n - 1` times, because it can reuse the passed value for the last slot.\nThat means that the last `Vec<_>` gets the requested capacity but all other ones do not.\n\n### Example\n```rust\n\nlet _: Vec<Vec<u8>> = vec![Vec::with_capacity(42); 123];\nlet _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();\n```\nUse instead:\n```rust\n\nlet _: Vec<Vec<u8>> = iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();\n// ^^^ this closure executes 123 times\n// and the vecs will have the expected capacity\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "replace_consts",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 156
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nAssociated-constants are now preferred.",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "reserve_after_initialization",
|
||
"id_span": {
|
||
"path": "src/reserve_after_initialization.rs",
|
||
"line": 30
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nInforms the user about a more concise way to create a vector with a known capacity.\n\n### Why is this bad?\nThe `Vec::with_capacity` constructor is less complex.\n\n### Example\n```rust\nlet mut v: Vec<usize> = vec![];\nv.reserve(10);\n```\nUse instead:\n```rust\nlet mut v: Vec<usize> = Vec::with_capacity(10);\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "rest_pat_in_fully_bound_structs",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 463
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for unnecessary '..' pattern binding on struct when all fields are explicitly matched.\n\n### Why is this bad?\nCorrectness and readability. It's like having a wildcard pattern after\nmatching all enum variants explicitly.\n\n### Example\n```rust\nlet a = A { a: 5 };\n\nmatch a {\n A { a: 5, .. } => {},\n _ => {},\n}\n```\n\nUse instead:\n```rust\nmatch a {\n A { a: 5 } => {},\n _ => {},\n}\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "result_filter_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3834
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may\nbe replaced with a `.flatten()` call.\n\n### Why is this bad?\n`Result` implements `IntoIterator<Item = T>`. This means that `Result` can be flattened\nautomatically without suspicious-looking `unwrap` calls.\n\n### Example\n```rust\nlet _ = std::iter::empty::<Result<i32, ()>>().filter(Result::is_ok).map(Result::unwrap);\n```\nUse instead:\n```rust\nlet _ = std::iter::empty::<Result<i32, ()>>().flatten();\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "result_large_err",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 289
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for functions that return `Result` with an unusually large\n`Err`-variant.\n\n### Why is this bad?\nA `Result` is at least as large as the `Err`-variant. While we\nexpect that variant to be seldom used, the compiler needs to reserve\nand move that much memory every single time.\nFurthermore, errors are often simply passed up the call-stack, making\nuse of the `?`-operator and its type-conversion mechanics. If the\n`Err`-variant further up the call-stack stores the `Err`-variant in\nquestion (as library code often does), it itself needs to be at least\nas large, propagating the problem.\n\n### Known problems\nThe size determined by Clippy is platform-dependent.\n\n### Examples\n```rust\npub enum ParseError {\n UnparsedBytes([u8; 512]),\n UnexpectedEof,\n}\n\n// The `Result` has at least 512 bytes, even in the `Ok`-case\npub fn parse() -> Result<(), ParseError> {\n Ok(())\n}\n```\nshould be\n```rust\npub enum ParseError {\n UnparsedBytes(Box<[u8; 512]>),\n UnexpectedEof,\n}\n\n// The `Result` is slightly larger than a pointer\npub fn parse() -> Result<(), ParseError> {\n Ok(())\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `large-error-threshold`: The maximum size of the `Err`-variant in a `Result` returned from a function (default: `128`)",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "result_map_or_into_option",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 621
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.map_or(None, Some)`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.ok()`.\n\n### Example\n```rust\nassert_eq!(Some(1), r.map_or(None, Some));\n```\n\nUse instead:\n```rust\nassert_eq!(Some(1), r.ok());\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "result_map_unit_fn",
|
||
"id_span": {
|
||
"path": "src/map_unit_fn.rs",
|
||
"line": 90
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `result.map(f)` where f is a function\nor closure that returns the unit type `()`.\n\n### Why is this bad?\nReadability, this can be written more clearly with\nan if let statement\n\n### Example\n```rust\nlet x: Result<String, String> = do_stuff();\nx.map(log_err_msg);\nx.map(|msg| log_err_msg(format_msg(msg)));\n```\n\nThe correct use would be:\n\n```rust\nlet x: Result<String, String> = do_stuff();\nif let Ok(msg) = x {\n log_err_msg(msg);\n};\nif let Ok(msg) = x {\n log_err_msg(format_msg(msg));\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "result_unit_err",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 241
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for public functions that return a `Result`\nwith an `Err` type of `()`. It suggests using a custom type that\nimplements `std::error::Error`.\n\n### Why is this bad?\nUnit does not implement `Error` and carries no\nfurther information about what went wrong.\n\n### Known problems\nOf course, this lint assumes that `Result` is used\nfor a fallible operation (which is after all the intended use). However\ncode may opt to (mis)use it as a basic two-variant-enum. In that case,\nthe suggestion is misguided, and the code should use a custom enum\ninstead.\n\n### Examples\n```rust\npub fn read_u8() -> Result<u8, ()> { Err(()) }\n```\nshould become\n```rust\nuse std::fmt;\n\n#[derive(Debug)]\npub struct EndOfStream;\n\nimpl fmt::Display for EndOfStream {\n fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n write!(f, \"End of Stream\")\n }\n}\n\nimpl std::error::Error for EndOfStream { }\n\npub fn read_u8() -> Result<u8, EndOfStream> { Err(EndOfStream) }\n```\n\nNote that there are crates that simplify creating the error type, e.g.\n[`thiserror`](https://docs.rs/thiserror).",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "return_self_not_must_use",
|
||
"id_span": {
|
||
"path": "src/return_self_not_must_use.rs",
|
||
"line": 64
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.\n\n### Why is this bad?\nMethods returning `Self` often create new values, having the `#[must_use]` attribute\nprevents users from \"forgetting\" to use the newly created value.\n\nThe `#[must_use]` attribute can be added to the type itself to ensure that instances\nare never forgotten. Functions returning a type marked with `#[must_use]` will not be\nlinted, as the usage is already enforced by the type attribute.\n\n### Limitations\nThis lint is only applied on methods taking a `self` argument. It would be mostly noise\nif it was added on constructors for example.\n\n### Example\n```rust\npub struct Bar;\nimpl Bar {\n // Missing attribute\n pub fn bar(&self) -> Self {\n Self\n }\n}\n```\n\nUse instead:\n```rust\n// It's better to have the `#[must_use]` attribute on the method like this:\npub struct Bar;\nimpl Bar {\n #[must_use]\n pub fn bar(&self) -> Self {\n Self\n }\n}\n\n// Or on the type definition like this:\n#[must_use]\npub struct Bar;\nimpl Bar {\n pub fn bar(&self) -> Self {\n Self\n }\n}\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "reversed_empty_ranges",
|
||
"id_span": {
|
||
"path": "src/ranges.rs",
|
||
"line": 130
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for range expressions `x..y` where both `x` and `y`\nare constant and `x` is greater to `y`. Also triggers if `x` is equal to `y` when they are conditions to a `for` loop.\n\n### Why is this bad?\nEmpty ranges yield no values so iterating them is a no-op.\nMoreover, trying to use a reversed range to index a slice will panic at run-time.\n\n### Example\n```rust\nfn main() {\n (10..=0).for_each(|x| println!(\"{}\", x));\n\n let arr = [1, 2, 3, 4, 5];\n let sub = &arr[3..1];\n}\n```\nUse instead:\n```rust\nfn main() {\n (0..=10).rev().for_each(|x| println!(\"{}\", x));\n\n let arr = [1, 2, 3, 4, 5];\n let sub = &arr[1..3];\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "same_functions_in_if_condition",
|
||
"id_span": {
|
||
"path": "src/copies.rs",
|
||
"line": 96
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for consecutive `if`s with the same function call.\n\n### Why is this bad?\nThis is probably a copy & paste error.\nDespite the fact that function can have side effects and `if` works as\nintended, such an approach is implicit and can be considered a \"code smell\".\n\n### Example\n```rust\nif foo() == bar {\n …\n} else if foo() == bar {\n …\n}\n```\n\nThis probably should be:\n```rust\nif foo() == bar {\n …\n} else if foo() == baz {\n …\n}\n```\n\nor if the original code was not a typo and called function mutates a state,\nconsider move the mutation out of the `if` condition to avoid similarity to\na copy & paste error:\n\n```rust\nlet first = foo();\nif first == bar {\n …\n} else {\n let second = foo();\n if second == bar {\n …\n }\n}\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "same_item_push",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 450
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks whether a for loop is being used to push a constant\nvalue into a Vec.\n\n### Why is this bad?\nThis kind of operation can be expressed more succinctly with\n`vec![item; SIZE]` or `vec.resize(NEW_SIZE, item)` and using these alternatives may also\nhave better performance.\n\n### Example\n```rust\nlet item1 = 2;\nlet item2 = 3;\nlet mut vec: Vec<u8> = Vec::new();\nfor _ in 0..20 {\n vec.push(item1);\n}\nfor _ in 0..30 {\n vec.push(item2);\n}\n```\n\nUse instead:\n```rust\nlet item1 = 2;\nlet item2 = 3;\nlet mut vec: Vec<u8> = vec![item1; 20];\nvec.resize(20 + 30, item2);\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "same_name_method",
|
||
"id_span": {
|
||
"path": "src/same_name_method.rs",
|
||
"line": 37
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nIt lints if a struct has two methods with the same name:\none from a trait, another not from trait.\n\n### Why is this bad?\nConfusing.\n\n### Example\n```rust\ntrait T {\n fn foo(&self) {}\n}\n\nstruct S;\n\nimpl T for S {\n fn foo(&self) {}\n}\n\nimpl S {\n fn foo(&self) {}\n}\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "search_is_some",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 867
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for an iterator or string search (such as `find()`,\n`position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`.\n\n### Why is this bad?\nReadability, this can be written more concisely as:\n* `_.any(_)`, or `_.contains(_)` for `is_some()`,\n* `!_.any(_)`, or `!_.contains(_)` for `is_none()`.\n\n### Example\n```rust\nlet vec = vec![1];\nvec.iter().find(|x| **x == 0).is_some();\n\n\"hello world\".find(\"world\").is_none();\n```\n\nUse instead:\n```rust\nlet vec = vec![1];\nvec.iter().any(|x| *x == 0);\n\n!\"hello world\".contains(\"world\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "seek_from_current",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3234
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks if the `seek` method of the `Seek` trait is called with `SeekFrom::Current(0)`,\nand if it is, suggests using `stream_position` instead.\n\n### Why is this bad?\n\nReadability. Use dedicated method.\n\n### Example\n\n```rust\nuse std::fs::File;\nuse std::io::{self, Write, Seek, SeekFrom};\n\nfn main() -> io::Result<()> {\n let mut f = File::create(\"foo.txt\")?;\n f.write_all(b\"Hello\")?;\n eprintln!(\"Written {} bytes\", f.seek(SeekFrom::Current(0))?);\n\n Ok(())\n}\n```\nUse instead:\n```rust\nuse std::fs::File;\nuse std::io::{self, Write, Seek, SeekFrom};\n\nfn main() -> io::Result<()> {\n let mut f = File::create(\"foo.txt\")?;\n f.write_all(b\"Hello\")?;\n eprintln!(\"Written {} bytes\", f.stream_position()?);\n\n Ok(())\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "seek_to_start_instead_of_rewind",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3265
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for jumps to the start of a stream that implements `Seek`\nand uses the `seek` method providing `Start` as parameter.\n\n### Why is this bad?\n\nReadability. There is a specific method that was implemented for\nthis exact scenario.\n\n### Example\n```rust\nfn foo<T: io::Seek>(t: &mut T) {\n t.seek(io::SeekFrom::Start(0));\n}\n```\nUse instead:\n```rust\nfn foo<T: io::Seek>(t: &mut T) {\n t.rewind();\n}\n```",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "self_assignment",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 766
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for explicit self-assignments.\n\n### Why is this bad?\nSelf-assignments are redundant and unlikely to be\nintentional.\n\n### Known problems\nIf expression contains any deref coercions or\nindexing operations they are assumed not to have any side effects.\n\n### Example\n```rust\nstruct Event {\n x: i32,\n}\n\nfn copy_position(a: &mut Event, b: &Event) {\n a.x = a.x;\n}\n```\n\nShould be:\n```rust\nstruct Event {\n x: i32,\n}\n\nfn copy_position(a: &mut Event, b: &Event) {\n a.x = b.x;\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "self_named_constructors",
|
||
"id_span": {
|
||
"path": "src/self_named_constructors.rs",
|
||
"line": 36
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns when constructors have the same name as their types.\n\n### Why is this bad?\nRepeating the name of the type is redundant.\n\n### Example\n```rust\nstruct Foo {}\n\nimpl Foo {\n pub fn foo() -> Foo {\n Foo {}\n }\n}\n```\nUse instead:\n```rust\nstruct Foo {}\n\nimpl Foo {\n pub fn new() -> Foo {\n Foo {}\n }\n}\n```",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "self_named_module_files",
|
||
"id_span": {
|
||
"path": "src/module_style.rs",
|
||
"line": 65
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks that module layout uses only `mod.rs` files.\n\n### Why is this bad?\nHaving multiple module layout styles in a project can be confusing.\n\n### Example\n```text\nsrc/\n stuff/\n stuff_files.rs\n stuff.rs\n lib.rs\n```\nUse instead:\n```text\nsrc/\n stuff/\n stuff_files.rs\n mod.rs\n lib.rs\n```",
|
||
"version": "1.57.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "semicolon_if_nothing_returned",
|
||
"id_span": {
|
||
"path": "src/semicolon_if_nothing_returned.rs",
|
||
"line": 32
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLooks for blocks of expressions and fires if the last expression returns\n`()` but is not followed by a semicolon.\n\n### Why is this bad?\nThe semicolon might be optional but when extending the block with new\ncode, it doesn't require a change in previous last line.\n\n### Example\n```rust\nfn main() {\n println!(\"Hello world\")\n}\n```\nUse instead:\n```rust\nfn main() {\n println!(\"Hello world\");\n}\n```",
|
||
"version": "1.52.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "semicolon_inside_block",
|
||
"id_span": {
|
||
"path": "src/semicolon_block.rs",
|
||
"line": 34
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nSuggests moving the semicolon after a block to the inside of the block, after its last\nexpression.\n\n### Why is this bad?\n\nFor consistency it's best to have the semicolon inside/outside the block. Either way is fine\nand this lint suggests inside the block.\nTake a look at `semicolon_outside_block` for the other alternative.\n\n### Example\n\n```rust\nunsafe { f(x) };\n```\nUse instead:\n```rust\nunsafe { f(x); }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `semicolon-inside-block-ignore-singleline`: Whether to lint only if it's multiline. (default: `false`)",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "semicolon_outside_block",
|
||
"id_span": {
|
||
"path": "src/semicolon_block.rs",
|
||
"line": 63
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nSuggests moving the semicolon from a block's final expression outside of the block.\n\n### Why is this bad?\n\nFor consistency it's best to have the semicolon inside/outside the block. Either way is fine\nand this lint suggests outside the block.\nTake a look at `semicolon_inside_block` for the other alternative.\n\n### Example\n\n```rust\nunsafe { f(x); }\n```\nUse instead:\n```rust\nunsafe { f(x) };\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `semicolon-outside-block-ignore-multiline`: Whether to lint only if it's singleline. (default: `false`)",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "separated_literal_suffix",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 186
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if literal suffixes are separated by an underscore.\nTo enforce separated literal suffix style,\nsee the `unseparated_literal_suffix` lint.\n\n### Why is this bad?\nSuffix style should be consistent.\n\n### Example\n```rust\n123832_i32\n```\n\nUse instead:\n```rust\n123832i32\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "serde_api_misuse",
|
||
"id_span": {
|
||
"path": "src/serde_api.rs",
|
||
"line": 19
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for misuses of the serde API.\n\n### Why is this bad?\nSerde is very finicky about how its API should be\nused, but the type system can't be used to enforce it (yet?).\n\n### Example\nImplementing `Visitor::visit_string` but not\n`Visitor::visit_str`.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "shadow_reuse",
|
||
"id_span": {
|
||
"path": "src/shadow.rs",
|
||
"line": 62
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for bindings that shadow other bindings already in\nscope, while reusing the original value.\n\n### Why is this bad?\nNot too much, in fact it's a common pattern in Rust\ncode. Still, some argue that name shadowing like this hurts readability,\nbecause a value may be bound to different things depending on position in\nthe code.\n\n### Example\n```rust\nlet x = 2;\nlet x = x + 1;\n```\nuse different variable name:\n```rust\nlet x = 2;\nlet y = x + 1;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "shadow_same",
|
||
"id_span": {
|
||
"path": "src/shadow.rs",
|
||
"line": 35
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for bindings that shadow other bindings already in\nscope, while just changing reference level or mutability.\n\n### Why is this bad?\nNot much, in fact it's a very common pattern in Rust\ncode. Still, some may opt to avoid it in their code base, they can set this\nlint to `Warn`.\n\n### Example\n```rust\nlet x = &x;\n```\n\nUse instead:\n```rust\nlet y = &x; // use different variable name\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "shadow_unrelated",
|
||
"id_span": {
|
||
"path": "src/shadow.rs",
|
||
"line": 95
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for bindings that shadow other bindings already in\nscope, either without an initialization or with one that does not even use\nthe original value.\n\n### Why is this bad?\nName shadowing can hurt readability, especially in\nlarge code bases, because it is easy to lose track of the active binding at\nany place in the code. This can be alleviated by either giving more specific\nnames to bindings or introducing more scopes to contain the bindings.\n\n### Example\n```rust\nlet x = y;\nlet x = z; // shadows the earlier binding\n```\n\nUse instead:\n```rust\nlet x = y;\nlet w = z; // use different variable name\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "short_circuit_statement",
|
||
"id_span": {
|
||
"path": "src/misc.rs",
|
||
"line": 99
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of short circuit boolean conditions as\na\nstatement.\n\n### Why is this bad?\nUsing a short circuit boolean condition as a statement\nmay hide the fact that the second part is executed or not depending on the\noutcome of the first part.\n\n### Example\n```rust\nf() && g(); // We should write `if f() { g(); }`.\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "should_assert_eq",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 30
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis used to check for `assert!(a == b)` and recommend\nreplacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "should_implement_trait",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 393
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for methods that should live in a trait\nimplementation of a `std` trait (see [llogiq's blog\npost](http://llogiq.github.io/2015/07/30/traits.html) for further\ninformation) instead of an inherent implementation.\n\n### Why is this bad?\nImplementing the traits improve ergonomics for users of\nthe code, often with very little cost. Also people seeing a `mul(...)`\nmethod\nmay expect `*` to work equally, so you should have good reason to disappoint\nthem.\n\n### Example\n```rust\nstruct X;\nimpl X {\n fn add(&self, other: &X) -> X {\n // ..\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "should_panic_without_expect",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 355
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `#[should_panic]` attributes without specifying the expected panic message.\n\n### Why is this bad?\nThe expected panic message should be specified to ensure that the test is actually\npanicking with the expected message, and not another unrelated panic.\n\n### Example\n```rust\nfn random() -> i32 { 0 }\n\n#[should_panic]\n#[test]\nfn my_test() {\n let _ = 1 / random();\n}\n```\n\nUse instead:\n```rust\nfn random() -> i32 { 0 }\n\n#[should_panic = \"attempt to divide by zero\"]\n#[test]\nfn my_test() {\n let _ = 1 / random();\n}\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "significant_drop_in_scrutinee",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 855
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for temporaries returned from function calls in a match scrutinee that have the\n`clippy::has_significant_drop` attribute.\n\n### Why is this bad?\nThe `clippy::has_significant_drop` attribute can be added to types whose Drop impls have\nan important side-effect, such as unlocking a mutex, making it important for users to be\nable to accurately understand their lifetimes. When a temporary is returned in a function\ncall in a match scrutinee, its lifetime lasts until the end of the match block, which may\nbe surprising.\n\nFor `Mutex`es this can lead to a deadlock. This happens when the match scrutinee uses a\nfunction call that returns a `MutexGuard` and then tries to lock again in one of the match\narms. In that case the `MutexGuard` in the scrutinee will not be dropped until the end of\nthe match block and thus will not unlock.\n\n### Example\n```rust\nlet mutex = Mutex::new(State {});\n\nmatch mutex.lock().unwrap().foo() {\n true => {\n mutex.lock().unwrap().bar(); // Deadlock!\n }\n false => {}\n};\n\nprintln!(\"All done!\");\n```\nUse instead:\n```rust\nlet mutex = Mutex::new(State {});\n\nlet is_foo = mutex.lock().unwrap().foo();\nmatch is_foo {\n true => {\n mutex.lock().unwrap().bar();\n }\n false => {}\n};\n\nprintln!(\"All done!\");\n```",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "significant_drop_tightening",
|
||
"id_span": {
|
||
"path": "src/significant_drop_tightening.rs",
|
||
"line": 49
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nSearches for elements marked with `#[clippy::has_significant_drop]` that could be early\ndropped but are in fact dropped at the end of their scopes. In other words, enforces the\n\"tightening\" of their possible lifetimes.\n\n### Why is this bad?\n\nElements marked with `#[clippy::has_significant_drop]` are generally synchronizing\nprimitives that manage shared resources, as such, it is desired to release them as soon as\npossible to avoid unnecessary resource contention.\n\n### Example\n\n```rust\nfn main() {\n let lock = some_sync_resource.lock();\n let owned_rslt = lock.do_stuff_with_resource();\n // Only `owned_rslt` is needed but `lock` is still held.\n do_heavy_computation_that_takes_time(owned_rslt);\n}\n```\n\nUse instead:\n\n```rust\nfn main() {\n let owned_rslt = some_sync_resource.lock().do_stuff_with_resource();\n do_heavy_computation_that_takes_time(owned_rslt);\n}\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "similar_names",
|
||
"id_span": {
|
||
"path": "src/non_expressive_names.rs",
|
||
"line": 31
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for names that are very similar and thus confusing.\n\nNote: this lint looks for similar names throughout each\nscope. To allow it, you need to allow it on the scope\nlevel, not on the name that is reported.\n\n### Why is this bad?\nIt's hard to distinguish between names that differ only\nby a single character.\n\n### Example\n```rust\nlet checked_exp = something;\nlet checked_expr = something_else;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_call_fn",
|
||
"id_span": {
|
||
"path": "src/single_call_fn.rs",
|
||
"line": 50
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions that are only used once. Does not lint tests.\n\n### Why is this bad?\nIt's usually not, splitting a function into multiple parts often improves readability and in\nthe case of generics, can prevent the compiler from duplicating the function dozens of\ntime; instead, only duplicating a thunk. But this can prevent segmentation across a\ncodebase, where many small functions are used only once.\n\nNote: If this lint is used, prepare to allow this a lot.\n\n### Example\n```rust\npub fn a<T>(t: &T)\nwhere\n T: AsRef<str>,\n{\n a_inner(t.as_ref())\n}\n\nfn a_inner(t: &str) {\n /* snip */\n}\n\n```\nUse instead:\n```rust\npub fn a<T>(t: &T)\nwhere\n T: AsRef<str>,\n{\n let t = t.as_ref();\n /* snip */\n}\n\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_char_add_str",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1853
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns when using `push_str`/`insert_str` with a single-character string literal\nwhere `push`/`insert` with a `char` would work fine.\n\n### Why is this bad?\nIt's less clear that we are pushing a single character.\n\n### Example\n```rust\nstring.insert_str(0, \"R\");\nstring.push_str(\"R\");\n```\n\nUse instead:\n```rust\nstring.insert(0, 'R');\nstring.push('R');\n```\n### Past names\n\n* `single_char_push_str`\n\n",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"single_char_push_str"
|
||
]
|
||
},
|
||
{
|
||
"id": "single_char_lifetime_names",
|
||
"id_span": {
|
||
"path": "src/single_char_lifetime_names.rs",
|
||
"line": 37
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for lifetimes with names which are one character\nlong.\n\n### Why is this bad?\nA single character is likely not enough to express the\npurpose of a lifetime. Using a longer name can make code\neasier to understand, especially for those who are new to\nRust.\n\n### Known problems\nRust programmers and learning resources tend to use single\ncharacter lifetimes, so this lint is at odds with the\necosystem at large. In addition, the lifetime's purpose may\nbe obvious or, rarely, expressible in one character.\n\n### Example\n```rust\nstruct DiagnosticCtx<'a> {\n source: &'a str,\n}\n```\nUse instead:\n```rust\nstruct DiagnosticCtx<'src> {\n source: &'src str,\n}\n```",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_char_pattern",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1164
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for string methods that receive a single-character\n`str` as an argument, e.g., `_.split(\"x\")`.\n\n### Why is this bad?\nPerforming these methods using a `char` is faster than\nusing a `str`.\n\n### Known problems\nDoes not catch multi-byte unicode characters.\n\n### Example\n```rust\n_.split(\"x\");\n```\n\nUse instead:\n```rust\n_.split('x');\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_component_path_imports",
|
||
"id_span": {
|
||
"path": "src/single_component_path_imports.rs",
|
||
"line": 36
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecking for imports with single component use path.\n\n### Why is this bad?\nImport with single component use path such as `use cratename;`\nis not necessary, and thus should be removed.\n\n### Example\n```rust\nuse regex;\n\nfn main() {\n regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n}\n```\nBetter as\n```rust\nfn main() {\n regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n}\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_element_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 478
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks whether a for loop has a single element.\n\n### Why is this bad?\nThere is no reason to have a loop of a\nsingle element.\n\n### Example\n```rust\nlet item1 = 2;\nfor item in &[item1] {\n println!(\"{}\", item);\n}\n```\n\nUse instead:\n```rust\nlet item1 = 2;\nlet item = &item1;\nprintln!(\"{}\", item);\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_match",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 68
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for matches with a single arm where an `if let`\nwill usually suffice.\n\nThis intentionally does not lint if there are comments\ninside of the other arm, so as to allow the user to document\nwhy having another explicit pattern with an empty body is necessary,\nor because the comments need to be preserved for other reasons.\n\n### Why is this bad?\nJust readability – `if let` nests less than a `match`.\n\n### Example\n```rust\nmatch x {\n Some(ref foo) => bar(foo),\n _ => (),\n}\n```\n\nUse instead:\n```rust\nif let Some(ref foo) = x {\n bar(foo);\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_match_else",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 110
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for matches with two arms where an `if let else` will\nusually suffice.\n\n### Why is this bad?\nJust readability – `if let` nests less than a `match`.\n\n### Known problems\nPersonal style preferences may differ.\n\n### Example\nUsing `match`:\n\n```rust\nmatch x {\n Some(ref foo) => bar(foo),\n _ => bar(&other_ref),\n}\n```\n\nUsing `if let` with `else`:\n\n```rust\nif let Some(ref foo) = x {\n bar(foo);\n} else {\n bar(&other_ref);\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "single_range_in_vec_init",
|
||
"id_span": {
|
||
"path": "src/single_range_in_vec_init.rs",
|
||
"line": 35
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `Vec` or array initializations that contain only one range.\n\n### Why is this bad?\nThis is almost always incorrect, as it will result in a `Vec` that has only one element.\nAlmost always, the programmer intended for it to include all elements in the range or for\nthe end of the range to be the length instead.\n\n### Example\n```rust\nlet x = [0..200];\n```\nUse instead:\n```rust\n// If it was intended to include every element in the range...\nlet x = (0..200).collect::<Vec<i32>>();\n// ...Or if 200 was meant to be the len\nlet x = [0; 200];\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "size_of_in_element_count",
|
||
"id_span": {
|
||
"path": "src/size_of_in_element_count.rs",
|
||
"line": 31
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nDetects expressions where\n`size_of::<T>` or `size_of_val::<T>` is used as a\ncount of elements of type `T`\n\n### Why is this bad?\nThese functions expect a count\nof `T` and not a number of bytes\n\n### Example\n```rust\nconst SIZE: usize = 128;\nlet x = [2u8; SIZE];\nlet mut y = [2u8; SIZE];\nunsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "size_of_ref",
|
||
"id_span": {
|
||
"path": "src/size_of_ref.rs",
|
||
"line": 51
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for calls to `std::mem::size_of_val()` where the argument is\na reference to a reference.\n\n### Why is this bad?\n\nCalling `size_of_val()` with a reference to a reference as the argument\nyields the size of the reference-type, not the size of the value behind\nthe reference.\n\n### Example\n```rust\nstruct Foo {\n buffer: [u8],\n}\n\nimpl Foo {\n fn size(&self) -> usize {\n // Note that `&self` as an argument is a `&&Foo`: Because `self`\n // is already a reference, `&self` is a double-reference.\n // The return value of `size_of_val()` therefor is the\n // size of the reference-type, not the size of `self`.\n std::mem::size_of_val(&self)\n }\n}\n```\nUse instead:\n```rust\nstruct Foo {\n buffer: [u8],\n}\n\nimpl Foo {\n fn size(&self) -> usize {\n // Correct\n std::mem::size_of_val(self)\n }\n}\n```",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "skip_while_next",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 704
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `_.skip_while(condition).next()`.\n\n### Why is this bad?\nReadability, this can be written more concisely as\n`_.find(!condition)`.\n\n### Example\n```rust\nvec.iter().skip_while(|x| **x == 0).next();\n```\n\nUse instead:\n```rust\nvec.iter().find(|x| **x != 0);\n```",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "slow_vector_initialization",
|
||
"id_span": {
|
||
"path": "src/slow_vector_initialization.rs",
|
||
"line": 54
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks slow zero-filled vector initialization\n\n### Why is this bad?\nThese structures are non-idiomatic and less efficient than simply using\n`vec![0; len]`.\n\nSpecifically, for `vec![0; len]`, the compiler can use a specialized type of allocation\nthat also zero-initializes the allocated memory in the same call\n(see: [alloc_zeroed](https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#method.alloc_zeroed)).\n\nWriting `Vec::new()` followed by `vec.resize(len, 0)` is suboptimal because,\nwhile it does do the same number of allocations,\nit involves two operations for allocating and initializing.\nThe `resize` call first allocates memory (since `Vec::new()` did not), and only *then* zero-initializes it.\n\n### Example\n```rust\nlet mut vec1 = Vec::new();\nvec1.resize(len, 0);\n\nlet mut vec2 = Vec::with_capacity(len);\nvec2.resize(len, 0);\n\nlet mut vec3 = Vec::with_capacity(len);\nvec3.extend(repeat(0).take(len));\n```\n\nUse instead:\n```rust\nlet mut vec1 = vec![0; len];\nlet mut vec2 = vec![0; len];\nlet mut vec3 = vec![0; len];\n```",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "stable_sort_primitive",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2998
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWhen sorting primitive values (integers, bools, chars, as well\nas arrays, slices, and tuples of such items), it is typically better to\nuse an unstable sort than a stable sort.\n\n### Why is this bad?\nTypically, using a stable sort consumes more memory and cpu cycles.\nBecause values which compare equal are identical, preserving their\nrelative order (the guarantee that a stable sort provides) means\nnothing, while the extra costs still apply.\n\n### Known problems\n\nAs pointed out in\n[issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),\na stable sort can instead be significantly faster for certain scenarios\n(eg. when a sorted vector is extended with new data and resorted).\n\nFor more information and benchmarking results, please refer to the\nissue linked above.\n\n### Example\n```rust\nlet mut vec = vec![2, 1, 3];\nvec.sort();\n```\nUse instead:\n```rust\nlet mut vec = vec![2, 1, 3];\nvec.sort_unstable();\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "std_instead_of_alloc",
|
||
"id_span": {
|
||
"path": "src/std_instead_of_core.rs",
|
||
"line": 59
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nFinds items imported through `std` when available through `alloc`.\n\n### Why is this bad?\n\nCrates which have `no_std` compatibility and require alloc may wish to ensure types are imported from\nalloc to ensure disabling `std` does not cause the crate to fail to compile. This lint is also useful\nfor crates migrating to become `no_std` compatible.\n\n### Example\n```rust\nuse std::vec::Vec;\n```\nUse instead:\n```rust\nuse alloc::vec::Vec;\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "std_instead_of_core",
|
||
"id_span": {
|
||
"path": "src/std_instead_of_core.rs",
|
||
"line": 33
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nFinds items imported through `std` when available through `core`.\n\n### Why is this bad?\n\nCrates which have `no_std` compatibility may wish to ensure types are imported from core to ensure\ndisabling `std` does not cause the crate to fail to compile. This lint is also useful for crates\nmigrating to become `no_std` compatible.\n\n### Example\n```rust\nuse std::hash::Hasher;\n```\nUse instead:\n```rust\nuse core::hash::Hasher;\n```",
|
||
"version": "1.64.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "str_split_at_newline",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3942
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nChecks for usages of `str.trim().split(\"\\n\")` and `str.trim().split(\"\\r\\n\")`.\n\n### Why is this bad?\n\nHard-coding the line endings makes the code less compatible. `str.lines` should be used instead.\n\n### Example\n```rust\n\"some\\ntext\\nwith\\nnewlines\\n\".trim().split('\\n');\n```\nUse instead:\n```rust\n\"some\\ntext\\nwith\\nnewlines\\n\".lines();\n```\n\n### Known Problems\n\nThis lint cannot detect if the split is intentionally restricted to a single type of newline (`\"\\n\"` or\n`\"\\r\\n\"`), for example during the parsing of a specific file format in which precisely one newline type is\nvalid.",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "str_to_string",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 383
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint checks for `.to_string()` method calls on values of type `&str`.\n\n### Why is this bad?\nThe `to_string` method is also used on other types to convert them to a string.\nWhen called on a `&str` it turns the `&str` into the owned variant `String`, which can be better\nexpressed with `.to_owned()`.\n\n### Example\n```rust\n// example code where clippy issues a warning\nlet _ = \"str\".to_string();\n```\nUse instead:\n```rust\n// example code which does not raise clippy warning\nlet _ = \"str\".to_owned();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_add",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 71
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for all instances of `x + _` where `x` is of type\n`String`, but only if [`string_add_assign`](#string_add_assign) does *not*\nmatch.\n\n### Why is this bad?\nIt's not bad in and of itself. However, this particular\n`Add` implementation is asymmetric (the other operand need not be `String`,\nbut `x` does), while addition as mathematically defined is symmetric, also\nthe `String::push_str(_)` function is a perfectly good replacement.\nTherefore, some dislike it and wish not to have it in their code.\n\nThat said, other people think that string addition, having a long tradition\nin other languages is actually fine, which is why we decided to make this\nparticular lint `allow` by default.\n\n### Example\n```rust\nlet x = \"Hello\".to_owned();\nx + \", World\";\n```\n\nUse instead:\n```rust\nlet mut x = \"Hello\".to_owned();\nx.push_str(\", World\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_add_assign",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for string appends of the form `x = x + y` (without\n`let`!).\n\n### Why is this bad?\nIt's not really bad, but some people think that the\n`.push_str(_)` method is more readable.\n\n### Example\n```rust\nlet mut x = \"Hello\".to_owned();\nx = x + \", World\";\n\n// More readable\nx += \", World\";\nx.push_str(\", World\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_extend_chars",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1441
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `.extend(s.chars())` where s is a\n`&str` or `String`.\n\n### Why is this bad?\n`.push_str(s)` is clearer\n\n### Example\n```rust\nlet abc = \"abc\";\nlet def = String::from(\"def\");\nlet mut s = String::new();\ns.extend(abc.chars());\ns.extend(def.chars());\n```\nThe correct use would be:\n```rust\nlet abc = \"abc\";\nlet def = String::from(\"def\");\nlet mut s = String::new();\ns.push_str(abc);\ns.push_str(&def);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_from_utf8_as_bytes",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 242
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nCheck if the string is transformed to byte array and casted back to string.\n\n### Why is this bad?\nIt's unnecessary, the string can be used directly.\n\n### Example\n```rust\nstd::str::from_utf8(&\"Hello World!\".as_bytes()[6..11]).unwrap();\n```\n\nUse instead:\n```rust\n&\"Hello World!\"[6..11];\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_lit_as_bytes",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 117
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the `as_bytes` method called on string literals\nthat contain only ASCII characters.\n\n### Why is this bad?\nByte string literals (e.g., `b\"foo\"`) can be used\ninstead. They are shorter but less discoverable than `as_bytes()`.\n\n### Known problems\n`\"str\".as_bytes()` and the suggested replacement of `b\"str\"` are not\nequivalent because they have different types. The former is `&[u8]`\nwhile the latter is `&[u8; 3]`. That means in general they will have a\ndifferent set of methods and different trait implementations.\n\n```compile_fail\nfn f(v: Vec<u8>) {}\n\nf(\"...\".as_bytes().to_owned()); // works\nf(b\"...\".to_owned()); // does not work, because arg is [u8; 3] not Vec<u8>\n\nfn g(r: impl std::io::Read) {}\n\ng(\"...\".as_bytes()); // works\ng(b\"...\"); // does not work\n```\n\nThe actual equivalent of `\"str\".as_bytes()` with the same type is not\n`b\"str\"` but `&b\"str\"[..]`, which is a great deal of punctuation and not\nmore readable than a function call.\n\n### Example\n```rust\nlet bstr = \"a byte string\".as_bytes();\n```\n\nUse instead:\n```rust\nlet bstr = b\"a byte string\";\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_lit_chars_any",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3488
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `<string_lit>.chars().any(|i| i == c)`.\n\n### Why is this bad?\nIt's significantly slower than using a pattern instead, like\n`matches!(c, '\\\\' | '.' | '+')`.\n\nDespite this being faster, this is not `perf` as this is pretty common, and is a rather nice\nway to check if a `char` is any in a set. In any case, this `restriction` lint is available\nfor situations where that additional performance is absolutely necessary.\n\n### Example\n```rust\n\"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n```\nUse instead:\n```rust\nmatches!(c, '\\\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_slice",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 141
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for slice operations on strings\n\n### Why is this bad?\nUTF-8 characters span multiple bytes, and it is easy to inadvertently confuse character\ncounts and string indices. This may lead to panics, and should warrant some test cases\ncontaining wide UTF-8 characters. This lint is most useful in code that should avoid\npanics at all costs.\n\n### Known problems\nProbably lots of false positives. If an index comes from a known valid position (e.g.\nobtained via `char_indices` over the same string), it is totally OK.\n\n### Example\n```rust\n&\"Ölkanne\"[1..];\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "string_to_string",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 431
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint checks for `.to_string()` method calls on values of type `String`.\n\n### Why is this bad?\nThe `to_string` method is also used on other types to convert them to a string.\nWhen called on a `String` it only clones the `String`, which can be better expressed with `.clone()`.\n\n### Example\n```rust\n// example code where clippy issues a warning\nlet msg = String::from(\"Hello World\");\nlet _ = msg.to_string();\n```\nUse instead:\n```rust\n// example code which does not raise clippy warning\nlet msg = String::from(\"Hello World\");\nlet _ = msg.clone();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "strlen_on_c_strings",
|
||
"id_span": {
|
||
"path": "src/strlen_on_c_strings.rs",
|
||
"line": 34
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `libc::strlen` on a `CString` or `CStr` value,\nand suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead.\n\n### Why is this bad?\nThis avoids calling an unsafe `libc` function.\nCurrently, it also avoids calculating the length.\n\n### Example\n```rust\nuse std::ffi::CString;\nlet cstring = CString::new(\"foo\").expect(\"CString::new failed\");\nlet len = unsafe { libc::strlen(cstring.as_ptr()) };\n```\nUse instead:\n```rust\nuse std::ffi::CString;\nlet cstring = CString::new(\"foo\").expect(\"CString::new failed\");\nlet len = cstring.as_bytes().len();\n```",
|
||
"version": "1.55.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "struct_excessive_bools",
|
||
"id_span": {
|
||
"path": "src/excessive_bools.rs",
|
||
"line": 42
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for excessive\nuse of bools in structs.\n\n### Why is this bad?\nExcessive bools in a struct\nis often a sign that it's used as a state machine,\nwhich is much better implemented as an enum.\nIf it's not the case, excessive bools usually benefit\nfrom refactoring into two-variant enums for better\nreadability and API.\n\n### Example\n```rust\nstruct S {\n is_pending: bool,\n is_processing: bool,\n is_finished: bool,\n}\n```\n\nUse instead:\n```rust\nenum S {\n Pending,\n Processing,\n Finished,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `max-struct-bools`: The maximum number of bool fields a struct can have (default: `3`)",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "struct_field_names",
|
||
"id_span": {
|
||
"path": "src/item_name_repetitions.rs",
|
||
"line": 140
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetects struct fields that are prefixed or suffixed\nby the same characters or the name of the struct itself.\n\n### Why is this bad?\nInformation common to all struct fields is better represented in the struct name.\n\n### Limitations\nCharacters with no casing will be considered when comparing prefixes/suffixes\nThis applies to numbers and non-ascii characters without casing\ne.g. `foo1` and `foo2` is considered to have different prefixes\n(the prefixes are `foo1` and `foo2` respectively), as also `bar螃`, `bar蟹`\n\n### Example\n```rust\nstruct Cake {\n cake_sugar: u8,\n cake_flour: u8,\n cake_eggs: u8\n}\n```\nUse instead:\n```rust\nstruct Cake {\n sugar: u8,\n flour: u8,\n eggs: u8\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `struct-field-name-threshold`: The minimum number of struct fields for the lints about field names to trigger (default: `3`)",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suboptimal_flops",
|
||
"id_span": {
|
||
"path": "src/floating_point_arithmetic.rs",
|
||
"line": 101
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLooks for floating-point expressions that\ncan be expressed using built-in methods to improve both\naccuracy and performance.\n\n### Why is this bad?\nNegatively impacts accuracy and performance.\n\n### Example\n```rust\nuse std::f32::consts::E;\n\nlet a = 3f32;\nlet _ = (2f32).powf(a);\nlet _ = E.powf(a);\nlet _ = a.powf(1.0 / 2.0);\nlet _ = a.log(2.0);\nlet _ = a.log(10.0);\nlet _ = a.log(E);\nlet _ = a.powf(2.0);\nlet _ = a * 2.0 + 4.0;\nlet _ = if a < 0.0 {\n -a\n} else {\n a\n};\nlet _ = if a < 0.0 {\n a\n} else {\n -a\n};\n```\n\nis better expressed as\n\n```rust\nuse std::f32::consts::E;\n\nlet a = 3f32;\nlet _ = a.exp2();\nlet _ = a.exp();\nlet _ = a.sqrt();\nlet _ = a.log2();\nlet _ = a.log10();\nlet _ = a.ln();\nlet _ = a.powi(2);\nlet _ = a.mul_add(2.0, 4.0);\nlet _ = a.abs();\nlet _ = -a.abs();\n```",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_arithmetic_impl",
|
||
"id_span": {
|
||
"path": "src/suspicious_trait_impl.rs",
|
||
"line": 28
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLints for suspicious operations in impls of arithmetic operators, e.g.\nsubtracting elements in an Add impl.\n\n### Why is this bad?\nThis is probably a typo or copy-and-paste error and not intended.\n\n### Example\n```rust\nimpl Add for Foo {\n type Output = Foo;\n\n fn add(self, other: Foo) -> Foo {\n Foo(self.0 - other.0)\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_assignment_formatting",
|
||
"id_span": {
|
||
"path": "src/formatting.rs",
|
||
"line": 24
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of the non-existent `=*`, `=!` and `=-`\noperators.\n\n### Why is this bad?\nThis is either a typo of `*=`, `!=` or `-=` or\nconfusing.\n\n### Example\n```rust\na =- 42; // confusing, should it be `a -= 42` or `a = -42`?\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_command_arg_space",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3316
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nChecks for `Command::arg()` invocations that look like they\nshould be multiple arguments instead, such as `arg(\"-t ext2\")`.\n\n### Why is this bad?\n\n`Command::arg()` does not split arguments by space. An argument like `arg(\"-t ext2\")`\nwill be passed as a single argument to the command,\nwhich is likely not what was intended.\n\n### Example\n```rust\nstd::process::Command::new(\"echo\").arg(\"-n hello\").spawn().unwrap();\n```\nUse instead:\n```rust\nstd::process::Command::new(\"echo\").args([\"-n\", \"hello\"]).spawn().unwrap();\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_doc_comments",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 336
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`\n\n### Why is this bad?\nTriple-slash comments (known as \"outer doc comments\") apply to items that follow it.\nAn outer doc comment followed by a bang (i.e. `///!`) has no specific meaning.\n\nThe user most likely meant to write an inner doc comment (`//!`, `/*!`), which\napplies to the parent item (i.e. the item that the comment is contained in,\nusually a module or crate).\n\n### Known problems\nInner doc comments can only appear before items, so there are certain cases where the suggestion\nmade by this lint is not valid code. For example:\n```rs\nfn foo() {}\n///!\nfn bar() {}\n```\nThis lint detects the doc comment and suggests changing it to `//!`, but an inner doc comment\nis not valid at that position.\n\n### Example\nIn this example, the doc comment is attached to the *function*, rather than the *module*.\n```rust\npub mod util {\n ///! This module contains utility functions.\n\n pub fn dummy() {}\n}\n```\n\nUse instead:\n```rust\npub mod util {\n //! This module contains utility functions.\n\n pub fn dummy() {}\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_else_formatting",
|
||
"id_span": {
|
||
"path": "src/formatting.rs",
|
||
"line": 90
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for formatting of `else`. It lints if the `else`\nis followed immediately by a newline or the `else` seems to be missing.\n\n### Why is this bad?\nThis is probably some refactoring remnant, even if the\ncode is correct, it might look confusing.\n\n### Example\n```rust\nif foo {\n} { // looks like an `else` is missing here\n}\n\nif foo {\n} if bar { // looks like an `else` is missing here\n}\n\nif foo {\n} else\n\n{ // this is the `else` block of the previous `if`, but should it be?\n}\n\nif foo {\n} else\n\nif bar { // this is the `else` block of the previous `if`, but should it be?\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1649
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `map` followed by a `count`.\n\n### Why is this bad?\nIt looks suspicious. Maybe `map` was confused with `filter`.\nIf the `map` call is intentional, this should be rewritten\nusing `inspect`. Or, if you intend to drive the iterator to\ncompletion, you can just use `for_each` instead.\n\n### Example\n```rust\nlet _ = (0..3).map(|x| x + 2).count();\n```",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_op_assign_impl",
|
||
"id_span": {
|
||
"path": "src/suspicious_trait_impl.rs",
|
||
"line": 50
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLints for suspicious operations in impls of OpAssign, e.g.\nsubtracting elements in an AddAssign impl.\n\n### Why is this bad?\nThis is probably a typo or copy-and-paste error and not intended.\n\n### Example\n```rust\nimpl AddAssign for Foo {\n fn add_assign(&mut self, other: Foo) {\n *self = *self - other;\n }\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_open_options",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2871
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the suspicious use of `OpenOptions::create()`\nwithout an explicit `OpenOptions::truncate()`.\n\n### Why is this bad?\n`create()` alone will either create a new file or open an\nexisting file. If the file already exists, it will be\noverwritten when written to, but the file will not be\ntruncated by default.\nIf less data is written to the file\nthan it already contains, the remainder of the file will\nremain unchanged, and the end of the file will contain old\ndata.\nIn most cases, one should either use `create_new` to ensure\nthe file is created from scratch, or ensure `truncate` is\ncalled so that the truncation behaviour is explicit. `truncate(true)`\nwill ensure the file is entirely overwritten with new data, whereas\n`truncate(false)` will explicitly keep the default behavior.\n\n### Example\n```rust\nuse std::fs::OpenOptions;\n\nOpenOptions::new().create(true);\n```\nUse instead:\n```rust\nuse std::fs::OpenOptions;\n\nOpenOptions::new().create(true).truncate(true);\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_operation_groupings",
|
||
"id_span": {
|
||
"path": "src/suspicious_operation_groupings.rs",
|
||
"line": 62
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for unlikely usages of binary operators that are almost\ncertainly typos and/or copy/paste errors, given the other usages\nof binary operators nearby.\n\n### Why is this bad?\nThey are probably bugs and if they aren't then they look like bugs\nand you should add a comment explaining why you are doing such an\nodd set of operations.\n\n### Known problems\nThere may be some false positives if you are trying to do something\nunusual that happens to look like a typo.\n\n### Example\n```rust\nstruct Vec3 {\n x: f64,\n y: f64,\n z: f64,\n}\n\nimpl Eq for Vec3 {}\n\nimpl PartialEq for Vec3 {\n fn eq(&self, other: &Self) -> bool {\n // This should trigger the lint because `self.x` is compared to `other.y`\n self.x == other.y && self.y == other.y && self.z == other.z\n }\n}\n```\nUse instead:\n```rust\n// same as above except:\nimpl PartialEq for Vec3 {\n fn eq(&self, other: &Self) -> bool {\n // Note we now compare other.x to self.x\n self.x == other.x && self.y == other.y && self.z == other.z\n }\n}\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_splitn",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2181
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for calls to [`splitn`]\n(https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and\nrelated functions with either zero or one splits.\n\n### Why is this bad?\nThese calls don't actually split the value and are\nlikely to be intended as a different number.\n\n### Example\n```rust\nfor x in s.splitn(1, \":\") {\n // ..\n}\n```\n\nUse instead:\n```rust\nfor x in s.splitn(2, \":\") {\n // ..\n}\n```",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_to_owned",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2150
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the usage of `_.to_owned()`, on a `Cow<'_, _>`.\n\n### Why is this bad?\nCalling `to_owned()` on a `Cow` creates a clone of the `Cow`\nitself, without taking ownership of the `Cow` contents (i.e.\nit's equivalent to calling `Cow::clone`).\nThe similarly named `into_owned` method, on the other hand,\nclones the `Cow` contents, effectively turning any `Cow::Borrowed`\ninto a `Cow::Owned`.\n\nGiven the potential ambiguity, consider replacing `to_owned`\nwith `clone` for better readability or, if getting a `Cow::Owned`\nwas the original intent, using `into_owned` instead.\n\n### Example\n```rust\nlet s = \"Hello world!\";\nlet cow = Cow::Borrowed(s);\n\nlet data = cow.to_owned();\nassert!(matches!(data, Cow::Borrowed(_)))\n```\nUse instead:\n```rust\nlet s = \"Hello world!\";\nlet cow = Cow::Borrowed(s);\n\nlet data = cow.clone();\nassert!(matches!(data, Cow::Borrowed(_)))\n```\nor\n```rust\nlet s = \"Hello world!\";\nlet cow = Cow::Borrowed(s);\n\nlet _data: String = cow.into_owned();\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_unary_op_formatting",
|
||
"id_span": {
|
||
"path": "src/formatting.rs",
|
||
"line": 53
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks the formatting of a unary operator on the right hand side\nof a binary operator. It lints if there is no space between the binary and unary operators,\nbut there is a space between the unary and its operand.\n\n### Why is this bad?\nThis is either a typo in the binary operator or confusing.\n\n### Example\n```rust\n// &&! looks like a different operator\nif foo &&! bar {}\n```\n\nUse instead:\n```rust\nif foo && !bar {}\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "suspicious_xor_used_as_pow",
|
||
"id_span": {
|
||
"path": "src/suspicious_xor_used_as_pow.rs",
|
||
"line": 25
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal.\n### Why is this bad?\nIt's most probably a typo and may lead to unexpected behaviours.\n### Example\n```rust\nlet x = 3_i32 ^ 4_i32;\n```\nUse instead:\n```rust\nlet x = 3_i32.pow(4);\n```",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "swap_ptr_to_ref",
|
||
"id_span": {
|
||
"path": "src/swap_ptr_to_ref.rs",
|
||
"line": 35
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `core::mem::swap` where either parameter is derived from a pointer\n\n### Why is this bad?\nWhen at least one parameter to `swap` is derived from a pointer it may overlap with the\nother. This would then lead to undefined behavior.\n\n### Example\n```rust\nunsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {\n for (&x, &y) in x.iter().zip(y) {\n core::mem::swap(&mut *x, &mut *y);\n }\n}\n```\nUse instead:\n```rust\nunsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {\n for (&x, &y) in x.iter().zip(y) {\n core::ptr::swap(x, y);\n }\n}\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "tabs_in_doc_comments",
|
||
"id_span": {
|
||
"path": "src/tabs_in_doc_comments.rs",
|
||
"line": 54
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks doc comments for usage of tab characters.\n\n### Why is this bad?\nThe rust style-guide promotes spaces instead of tabs for indentation.\nTo keep a consistent view on the source, also doc comments should not have tabs.\nAlso, explaining ascii-diagrams containing tabs can get displayed incorrectly when the\ndisplay settings of the author and reader differ.\n\n### Example\n```rust\n///\n/// Struct to hold two strings:\n/// \t- first\t\tone\n/// \t- second\tone\npub struct DoubleString {\n ///\n /// \t- First String:\n /// \t\t- needs to be inside here\n first_string: String,\n ///\n /// \t- Second String:\n /// \t\t- needs to be inside here\n second_string: String,\n}\n```\n\nWill be converted to:\n```rust\n///\n/// Struct to hold two strings:\n/// - first one\n/// - second one\npub struct DoubleString {\n ///\n /// - First String:\n /// - needs to be inside here\n first_string: String,\n ///\n /// - Second String:\n /// - needs to be inside here\n second_string: String,\n}\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "temporary_assignment",
|
||
"id_span": {
|
||
"path": "src/temporary_assignment.rs",
|
||
"line": 21
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for construction of a structure or tuple just to\nassign a value in it.\n\n### Why is this bad?\nReadability. If the structure is only created to be\nupdated, why not write the structure you want in the first place?\n\n### Example\n```rust\n(0, 0).0 = 1\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "test_attr_in_doctest",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 230
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `#[test]` in doctests unless they are marked with\neither `ignore`, `no_run` or `compile_fail`.\n\n### Why is this bad?\nCode in examples marked as `#[test]` will somewhat\nsurprisingly not be run by `cargo test`. If you really want\nto show how to test stuff in an example, mark it `no_run` to\nmake the intent clear.\n\n### Examples\n```rust\n/// An example of a doctest with a `main()` function\n///\n/// # Examples\n///\n/// ```\n/// #[test]\n/// fn equality_works() {\n/// assert_eq!(1_u8, 1);\n/// }\n/// ```\nfn test_attr_in_doctest() {\n unimplemented!();\n}\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "tests_outside_test_module",
|
||
"id_span": {
|
||
"path": "src/tests_outside_test_module.rs",
|
||
"line": 41
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nTriggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module\n(marked with `#[cfg(test)]`).\n### Why is this bad?\nThe idiomatic (and more performant) way of writing tests is inside a testing module (flagged with `#[cfg(test)]`),\nhaving test functions outside of this module is confusing and may lead to them being \"hidden\".\n### Example\n```rust\n#[test]\nfn my_cool_test() {\n // [...]\n}\n\n#[cfg(test)]\nmod tests {\n // [...]\n}\n\n```\nUse instead:\n```rust\n#[cfg(test)]\nmod tests {\n #[test]\n fn my_cool_test() {\n // [...]\n }\n}\n```",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "thread_local_initializer_can_be_made_const",
|
||
"id_span": {
|
||
"path": "src/thread_local_initializer_can_be_made_const.rs",
|
||
"line": 41
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSuggests to use `const` in `thread_local!` macro if possible.\n### Why is this bad?\n\nThe `thread_local!` macro wraps static declarations and makes them thread-local.\nIt supports using a `const` keyword that may be used for declarations that can\nbe evaluated as a constant expression. This can enable a more efficient thread\nlocal implementation that can avoid lazy initialization. For types that do not\nneed to be dropped, this can enable an even more efficient implementation that\ndoes not need to track any additional state.\n\nhttps://doc.rust-lang.org/std/macro.thread_local.html\n\n### Example\n```rust\n// example code where clippy issues a warning\nthread_local! {\n static BUF: String = String::new();\n}\n```\nUse instead:\n```rust\n// example code which does not raise clippy warning\nthread_local! {\n static BUF: String = const { String::new() };\n}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "to_digit_is_some",
|
||
"id_span": {
|
||
"path": "src/to_digit_is_some.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.to_digit(..).is_some()` on `char`s.\n\n### Why is this bad?\nThis is a convoluted way of checking if a `char` is a digit. It's\nmore straight forward to use the dedicated `is_digit` method.\n\n### Example\n```rust\nlet is_digit = c.to_digit(radix).is_some();\n```\ncan be written as:\n```rust\nlet is_digit = c.is_digit(radix);\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "to_string_in_format_args",
|
||
"id_span": {
|
||
"path": "src/format_args.rs",
|
||
"line": 72
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)\napplied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)\nin a macro that does formatting.\n\n### Why is this bad?\nSince the type implements `Display`, the use of `to_string` is\nunnecessary.\n\n### Example\n```rust\nprintln!(\"error: something failed at {}\", Location::caller().to_string());\n```\nUse instead:\n```rust\nprintln!(\"error: something failed at {}\", Location::caller());\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "to_string_trait_impl",
|
||
"id_span": {
|
||
"path": "src/to_string_trait_impl.rs",
|
||
"line": 42
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for direct implementations of `ToString`.\n### Why is this bad?\nThis trait is automatically implemented for any type which implements the `Display` trait.\nAs such, `ToString` shouldn’t be implemented directly: `Display` should be implemented instead,\nand you get the `ToString` implementation for free.\n### Example\n```rust\nstruct Point {\n x: usize,\n y: usize,\n}\n\nimpl ToString for Point {\n fn to_string(&self) -> String {\n format!(\"({}, {})\", self.x, self.y)\n }\n}\n```\nUse instead:\n```rust\nstruct Point {\n x: usize,\n y: usize,\n}\n\nimpl std::fmt::Display for Point {\n fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n write!(f, \"({}, {})\", self.x, self.y)\n }\n}\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "todo",
|
||
"id_span": {
|
||
"path": "src/panic_unimplemented.rs",
|
||
"line": 58
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `todo!`.\n\n### Why is this bad?\nThe `todo!` macro is often used for unfinished code, and it causes\ncode to panic. It should not be present in production code.\n\n### Example\n```rust\ntodo!();\n```\nFinish the implementation, or consider marking it as explicitly unimplemented.\n```rust\nunimplemented!();\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "too_many_arguments",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 33
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for functions with too many parameters.\n\n### Why is this bad?\nFunctions with lots of parameters are considered bad\nstyle and reduce readability (“what does the 5th parameter mean?”). Consider\ngrouping some parameters into a new type.\n\n### Example\n```rust\nfn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {\n // ..\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `too-many-arguments-threshold`: The maximum number of argument a function or method can have (default: `7`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "too_many_lines",
|
||
"id_span": {
|
||
"path": "src/functions/mod.rs",
|
||
"line": 57
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions with a large amount of lines.\n\n### Why is this bad?\nFunctions with a lot of lines are harder to understand\ndue to having to look at a larger amount of code to understand what the\nfunction is doing. Consider splitting the body of the function into\nmultiple functions.\n\n### Example\n```rust\nfn im_too_long() {\n println!(\"\");\n // ... 100 more LoC\n println!(\"\");\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `too-many-lines-threshold`: The maximum number of lines a function or method can have (default: `100`)",
|
||
"version": "1.34.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "toplevel_ref_arg",
|
||
"id_span": {
|
||
"path": "src/misc.rs",
|
||
"line": 52
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for function arguments and let bindings denoted as\n`ref`.\n\n### Why is this bad?\nThe `ref` declaration makes the function take an owned\nvalue, but turns the argument into a reference (which means that the value\nis destroyed when exiting the function). This adds not much value: either\ntake a reference type, or take an owned value and create references in the\nbody.\n\nFor let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The\ntype of `x` is more obvious with the former.\n\n### Known problems\nIf the argument is dereferenced within the function,\nremoving the `ref` will lead to errors. This can be fixed by removing the\ndereferences, e.g., changing `*x` to `x` within the function.\n\n### Example\n```rust\nfn foo(ref _x: u8) {}\n```\n\nUse instead:\n```rust\nfn foo(_x: &u8) {}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "trailing_empty_array",
|
||
"id_span": {
|
||
"path": "src/trailing_empty_array.rs",
|
||
"line": 32
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDisplays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.\n\n### Why is this bad?\nZero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.\n\n### Example\n```rust\nstruct RarelyUseful {\n some_field: u32,\n last: [u32; 0],\n}\n```\n\nUse instead:\n```rust\n#[repr(C)]\nstruct MoreOftenUseful {\n some_field: usize,\n last: [u32; 0],\n}\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "trait_duplication_in_bounds",
|
||
"id_span": {
|
||
"path": "src/trait_bounds.rs",
|
||
"line": 84
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for cases where generics or trait objects are being used and multiple\nsyntax specifications for trait bounds are used simultaneously.\n\n### Why is this bad?\nDuplicate bounds makes the code\nless readable than specifying them only once.\n\n### Example\n```rust\nfn func<T: Clone + Default>(arg: T) where T: Clone + Default {}\n```\n\nUse instead:\n```rust\nfn func<T: Clone + Default>(arg: T) {}\n\n// or\n\nfn func<T>(arg: T) where T: Clone + Default {}\n```\n\n```rust\nfn foo<T: Default + Default>(bar: T) {}\n```\nUse instead:\n```rust\nfn foo<T: Default>(bar: T) {}\n```\n\n```rust\nfn foo<T>(bar: T) where T: Default + Default {}\n```\nUse instead:\n```rust\nfn foo<T>(bar: T) where T: Default {}\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_bytes_to_str",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 207
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from a `&[u8]` to a `&str`.\n\n### Why is this bad?\nNot every byte slice is a valid UTF-8 string.\n\n### Known problems\n- [`from_utf8`] which this lint suggests using is slower than `transmute`\nas it needs to validate the input.\nIf you are certain that the input is always a valid UTF-8,\nuse [`from_utf8_unchecked`] which is as fast as `transmute`\nbut has a semantically meaningful name.\n- You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`.\n\n[`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html\n[`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html\n\n### Example\n```rust\nlet b: &[u8] = &[1_u8, 2_u8];\nunsafe {\n let _: &str = std::mem::transmute(b); // where b: &[u8]\n}\n\n// should be:\nlet _ = std::str::from_utf8(b).unwrap();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_float_to_int",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 301
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from a float to an integer.\n\n### Why is this bad?\nTransmutes are dangerous and error-prone, whereas `to_bits` is intuitive\nand safe.\n\n### Example\n```rust\nunsafe {\n let _: u32 = std::mem::transmute(1f32);\n}\n\n// should be:\nlet _: u32 = 1f32.to_bits();\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_int_to_bool",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 230
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from an integer to a `bool`.\n\n### Why is this bad?\nThis might result in an invalid in-memory representation of a `bool`.\n\n### Example\n```rust\nlet x = 1_u8;\nunsafe {\n let _: bool = std::mem::transmute(x); // where x: u8\n}\n\n// should be:\nlet _: bool = x != 0;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_int_to_char",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 173
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from an integer to a `char`.\n\n### Why is this bad?\nNot every integer is a Unicode scalar value.\n\n### Known problems\n- [`from_u32`] which this lint suggests using is slower than `transmute`\nas it needs to validate the input.\nIf you are certain that the input is always a valid Unicode scalar value,\nuse [`from_u32_unchecked`] which is as fast as `transmute`\nbut has a semantically meaningful name.\n- You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`.\n\n[`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html\n[`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html\n\n### Example\n```rust\nlet x = 1_u32;\nunsafe {\n let _: char = std::mem::transmute(x); // where x: u32\n}\n\n// should be:\nlet _ = std::char::from_u32(x).unwrap();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_int_to_float",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 253
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from an integer to a float.\n\n### Why is this bad?\nTransmutes are dangerous and error-prone, whereas `from_bits` is intuitive\nand safe.\n\n### Example\n```rust\nunsafe {\n let _: f32 = std::mem::transmute(1_u32); // where x: u32\n}\n\n// should be:\nlet _: f32 = f32::from_bits(1_u32);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_int_to_non_zero",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 278
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from integers to `NonZero*` types, and suggests their `new_unchecked`\nmethod instead.\n\n### Why is this bad?\nTransmutes work on any types and thus might cause unsoundness when those types change\nelsewhere. `new_unchecked` only works for the appropriate types instead.\n\n### Example\n```rust\nlet _non_zero: NonZeroU32 = unsafe { std::mem::transmute(123) };\n```\nUse instead:\n```rust\nlet _non_zero = unsafe { NonZeroU32::new_unchecked(123) };\n```",
|
||
"version": "1.69.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_null_to_fn",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 463
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for null function pointer creation through transmute.\n\n### Why is this bad?\nCreating a null function pointer is undefined behavior.\n\nMore info: https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization\n\n### Known problems\nNot all cases can be detected at the moment of this writing.\nFor example, variables which hold a null pointer and are then fed to a `transmute`\ncall, aren't detectable yet.\n\n### Example\n```rust\nlet null_fn: fn() = unsafe { std::mem::transmute( std::ptr::null::<()>() ) };\n```\nUse instead:\n```rust\nlet null_fn: Option<fn()> = None;\n```",
|
||
"version": "1.68.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_num_to_bytes",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 324
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from a number to an array of `u8`\n\n### Why this is bad?\nTransmutes are dangerous and error-prone, whereas `to_ne_bytes`\nis intuitive and safe.\n\n### Example\n```rust\nunsafe {\n let x: [u8; 8] = std::mem::transmute(1i64);\n}\n\n// should be\nlet x: [u8; 8] = 0i64.to_ne_bytes();\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_ptr_to_ptr",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 352
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for transmutes from a pointer to a pointer, or\nfrom a reference to a reference.\n\n### Why is this bad?\nTransmutes are dangerous, and these can instead be\nwritten as casts.\n\n### Example\n```rust\nlet ptr = &1u32 as *const u32;\nunsafe {\n // pointer-to-pointer transmute\n let _: *const f32 = std::mem::transmute(ptr);\n // ref-ref transmute\n let _: &f32 = std::mem::transmute(&1u32);\n}\n// These can be respectively written:\nlet _ = ptr as *const f32;\nlet _ = unsafe{ &*(&1u32 as *const u32 as *const f32) };\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_ptr_to_ref",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 139
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes from a pointer to a reference.\n\n### Why is this bad?\nThis can always be rewritten with `&` and `*`.\n\n### Known problems\n- `mem::transmute` in statics and constants is stable from Rust 1.46.0,\nwhile dereferencing raw pointer is not stable yet.\nIf you need to do this in those places,\nyou would have to use `transmute` instead.\n\n### Example\n```rust\nunsafe {\n let _: &T = std::mem::transmute(p); // where p: *const T\n}\n\n// can be written:\nlet _: &T = &*p;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmute_undefined_repr",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 413
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for transmutes between types which do not have a representation defined relative to\neach other.\n\n### Why is this bad?\nThe results of such a transmute are not defined.\n\n### Known problems\nThis lint has had multiple problems in the past and was moved to `nursery`. See issue\n[#8496](https://github.com/rust-lang/rust-clippy/issues/8496) for more details.\n\n### Example\n```rust\nstruct Foo<T>(u32, T);\nlet _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };\n```\nUse instead:\n```rust\n#[repr(C)]\nstruct Foo<T>(u32, T);\nlet _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };\n```",
|
||
"version": "1.60.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmutes_expressible_as_ptr_casts",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 92
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes that could be a pointer cast.\n\n### Why is this bad?\nReadability. The code tricks people into thinking that\nsomething complex is going on.\n\n### Example\n\n```rust\nunsafe { std::mem::transmute::<*const [i32], *const [u16]>(p) };\n```\nUse instead:\n```rust\np as *const [u16];\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "transmuting_null",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 435
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for transmute calls which would receive a null pointer.\n\n### Why is this bad?\nTransmuting a null pointer is undefined behavior.\n\n### Known problems\nNot all cases can be detected at the moment of this writing.\nFor example, variables which hold a null pointer and are then fed to a `transmute`\ncall, aren't detectable yet.\n\n### Example\n```rust\nlet null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };\n```",
|
||
"version": "1.35.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "trim_split_whitespace",
|
||
"id_span": {
|
||
"path": "src/strings.rs",
|
||
"line": 473
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns about calling `str::trim` (or variants) before `str::split_whitespace`.\n\n### Why is this bad?\n`split_whitespace` already ignores leading and trailing whitespace.\n\n### Example\n```rust\n\" A B C \".trim().split_whitespace();\n```\nUse instead:\n```rust\n\" A B C \".split_whitespace();\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "trivial_regex",
|
||
"id_span": {
|
||
"path": "src/regex.rs",
|
||
"line": 53
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for trivial [regex](https://crates.io/crates/regex)\ncreation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`).\n\n### Why is this bad?\nMatching the regex can likely be replaced by `==` or\n`str::starts_with`, `str::ends_with` or `std::contains` or other `str`\nmethods.\n\n### Known problems\nIf the same regex is going to be applied to multiple\ninputs, the precomputations done by `Regex` construction can give\nsignificantly better performance than any of the `str`-based methods.\n\n### Example\n```rust\nRegex::new(\"^foobar\")\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "trivially_copy_pass_by_ref",
|
||
"id_span": {
|
||
"path": "src/pass_by_ref_or_value.rs",
|
||
"line": 68
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions taking arguments by reference, where\nthe argument type is `Copy` and small enough to be more efficient to always\npass by value.\n\n### Why is this bad?\nIn many calling conventions instances of structs will\nbe passed through registers if they fit into two or less general purpose\nregisters.\n\n### Known problems\nThis lint is target register size dependent, it is\nlimited to 32-bit to try and reduce portability problems between 32 and\n64-bit, but if you are compiling for 8 or 16-bit targets then the limit\nwill be different.\n\nThe configuration option `trivial_copy_size_limit` can be set to override\nthis limit for a project.\n\nThis lint attempts to allow passing arguments by reference if a reference\nto that argument is returned. This is implemented by comparing the lifetime\nof the argument and return value for equality. However, this can cause\nfalse positives in cases involving multiple lifetimes that are bounded by\neach other.\n\nAlso, it does not take account of other similar cases where getting memory addresses\nmatters; namely, returning the pointer to the argument in question,\nand passing the argument, as both references and pointers,\nto a function that needs the memory address. For further details, refer to\n[this issue](https://github.com/rust-lang/rust-clippy/issues/5953)\nthat explains a real case in which this false positive\nled to an **undefined behavior** introduced with unsafe code.\n\n### Example\n\n```rust\nfn foo(v: &u32) {}\n```\n\nUse instead:\n```rust\nfn foo(v: u32) {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `trivial-copy-size-limit`: The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by\n reference. By default there is no limit",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "try_err",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 890
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Err(x)?`.\n\n### Why is this bad?\nThe `?` operator is designed to allow calls that\ncan fail to be easily chained. For example, `foo()?.bar()` or\n`foo(bar()?)`. Because `Err(x)?` can't be used that way (it will\nalways return), it is more clear to write `return Err(x)`.\n\n### Example\n```rust\nfn foo(fail: bool) -> Result<i32, String> {\n if fail {\n Err(\"failed\")?;\n }\n Ok(0)\n}\n```\nCould be written:\n\n```rust\nfn foo(fail: bool) -> Result<i32, String> {\n if fail {\n return Err(\"failed\".into());\n }\n Ok(0)\n}\n```",
|
||
"version": "1.38.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "tuple_array_conversions",
|
||
"id_span": {
|
||
"path": "src/tuple_array_conversions.rs",
|
||
"line": 39
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for tuple<=>array conversions that are not done with `.into()`.\n\n### Why is this bad?\nIt may be unnecessary complexity. `.into()` works for converting tuples<=> arrays of up to\n12 elements and conveys the intent more clearly, while also leaving less room for hard to\nspot bugs!\n\n### Known issues\nThe suggested code may hide potential asymmetry in some cases. See\n[#11085](https://github.com/rust-lang/rust-clippy/issues/11085) for more info.\n\n### Example\n```rust\nlet t1 = &[(1, 2), (3, 4)];\nlet v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n```\nUse instead:\n```rust\nlet t1 = &[(1, 2), (3, 4)];\nlet v1: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "type_complexity",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 268
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for types used in structs, parameters and `let`\ndeclarations above a certain complexity threshold.\n\n### Why is this bad?\nToo complex types make the code less readable. Consider\nusing a `type` definition to simplify them.\n\n### Example\n```rust\nstruct Foo {\n inner: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `type-complexity-threshold`: The maximum complexity a type can have (default: `250`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "type_id_on_box",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3038
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nLooks for calls to `.type_id()` on a `Box<dyn _>`.\n\n### Why is this bad?\nThis almost certainly does not do what the user expects and can lead to subtle bugs.\nCalling `.type_id()` on a `Box<dyn Trait>` returns a fixed `TypeId` of the `Box` itself,\nrather than returning the `TypeId` of the underlying type behind the trait object.\n\nFor `Box<dyn Any>` specifically (and trait objects that have `Any` as its supertrait),\nthis lint will provide a suggestion, which is to dereference the receiver explicitly\nto go from `Box<dyn Any>` to `dyn Any`.\nThis makes sure that `.type_id()` resolves to a dynamic call on the trait object\nand not on the box.\n\nIf the fixed `TypeId` of the `Box` is the intended behavior, it's better to be explicit about it\nand write `TypeId::of::<Box<dyn Trait>>()`:\nthis makes it clear that a fixed `TypeId` is returned and not the `TypeId` of the implementor.\n\n### Example\n```rust\nuse std::any::{Any, TypeId};\n\nlet any_box: Box<dyn Any> = Box::new(42_i32);\nassert_eq!(any_box.type_id(), TypeId::of::<i32>()); // ⚠️ this fails!\n```\nUse instead:\n```rust\nuse std::any::{Any, TypeId};\n\nlet any_box: Box<dyn Any> = Box::new(42_i32);\nassert_eq!((*any_box).type_id(), TypeId::of::<i32>());\n// ^ dereference first, to call `type_id` on `dyn Any`\n```",
|
||
"version": "1.73.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "type_repetition_in_bounds",
|
||
"id_span": {
|
||
"path": "src/trait_bounds.rs",
|
||
"line": 38
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nThis lint warns about unnecessary type repetitions in trait bounds\n\n### Why is this bad?\nRepeating the type for every bound makes the code\nless readable than combining the bounds\n\n### Example\n```rust\npub fn foo<T>(t: T) where T: Copy, T: Clone {}\n```\n\nUse instead:\n```rust\npub fn foo<T>(t: T) where T: Copy + Clone {}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `max-trait-bounds`: The maximum number of bounds a trait can have to be linted (default: `3`)- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.38.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unchecked_duration_subtraction",
|
||
"id_span": {
|
||
"path": "src/instant_subtraction.rs",
|
||
"line": 61
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nLints subtraction between an `Instant` and a `Duration`.\n\n### Why is this bad?\nUnchecked subtraction could cause underflow on certain platforms, leading to\nunintentional panics.\n\n### Example\n```rust\nlet time_passed = Instant::now() - Duration::from_secs(5);\n```\n\nUse instead:\n```rust\nlet time_passed = Instant::now().checked_sub(Duration::from_secs(5));\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unconditional_recursion",
|
||
"id_span": {
|
||
"path": "src/unconditional_recursion.rs",
|
||
"line": 46
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks that there isn't an infinite recursion in trait\nimplementations.\n\n### Why is this bad?\nThis is a hard to find infinite recursion that will crash any code\nusing it.\n\n### Example\n```rust\nenum Foo {\n A,\n B,\n}\n\nimpl PartialEq for Foo {\n fn eq(&self, other: &Self) -> bool {\n self == other // bad!\n }\n}\n```\nUse instead:\n\nIn such cases, either use `#[derive(PartialEq)]` or don't implement it.",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "undocumented_unsafe_blocks",
|
||
"id_span": {
|
||
"path": "src/undocumented_unsafe_blocks.rs",
|
||
"line": 62
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `unsafe` blocks and impls without a `// SAFETY: ` comment\nexplaining why the unsafe operations performed inside\nthe block are safe.\n\nNote the comment must appear on the line(s) preceding the unsafe block\nwith nothing appearing in between. The following is ok:\n```rust\nfoo(\n // SAFETY:\n // This is a valid safety comment\n unsafe { *x }\n)\n```\nBut neither of these are:\n```rust\n// SAFETY:\n// This is not a valid safety comment\nfoo(\n /* SAFETY: Neither is this */ unsafe { *x },\n);\n```\n\n### Why is this bad?\nUndocumented unsafe blocks and impls can make it difficult to\nread and maintain code, as well as uncover unsoundness\nand bugs.\n\n### Example\n```rust\nuse std::ptr::NonNull;\nlet a = &mut 42;\n\nlet ptr = unsafe { NonNull::new_unchecked(a) };\n```\nUse instead:\n```rust\nuse std::ptr::NonNull;\nlet a = &mut 42;\n\n// SAFETY: references are guaranteed to be non-null.\nlet ptr = unsafe { NonNull::new_unchecked(a) };\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `accept-comment-above-attributes`: Whether to accept a safety comment to be placed above the attributes for the `unsafe` block (default: `true`)- `accept-comment-above-statement`: Whether to accept a safety comment to be placed above the statement containing the `unsafe` block (default: `true`)",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unicode_not_nfc",
|
||
"id_span": {
|
||
"path": "src/unicode.rs",
|
||
"line": 70
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for string literals that contain Unicode in a form\nthat is not equal to its\n[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).\n\n### Why is this bad?\nIf such a string is compared to another, the results\nmay be surprising.\n\n### Example\nYou may not see it, but \"à\"\" and \"à\"\" aren't the same string. The\nformer when escaped is actually `\"a\\u{300}\"` while the latter is `\"\\u{e0}\"`.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unimplemented",
|
||
"id_span": {
|
||
"path": "src/panic_unimplemented.rs",
|
||
"line": 36
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `unimplemented!`.\n\n### Why is this bad?\nThis macro should not be present in production code.\n\n### Example\n```rust\nunimplemented!();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "uninhabited_references",
|
||
"id_span": {
|
||
"path": "src/uninhabited_references.rs",
|
||
"line": 34
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nIt detects references to uninhabited types, such as `!` and\nwarns when those are either dereferenced or returned from a function.\n\n### Why is this bad?\nDereferencing a reference to an uninhabited type would create\nan instance of such a type, which cannot exist. This constitutes\nundefined behaviour. Such a reference could have been created\nby `unsafe` code.\n\n### Example\nThe following function can return a reference to an uninhabited type\n(`Infallible`) because it uses `unsafe` code to create it. However,\nthe user of such a function could dereference the return value and\ntrigger an undefined behavior from safe code.\n\n```rust\nfn create_ref() -> &'static std::convert::Infallible {\n unsafe { std::mem::transmute(&()) }\n}\n```",
|
||
"version": "1.76.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "uninit_assumed_init",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1684
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `MaybeUninit::uninit().assume_init()`.\n\n### Why is this bad?\nFor most types, this is undefined behavior.\n\n### Known problems\nFor now, we accept empty tuples and tuples / arrays\nof `MaybeUninit`. There may be other types that allow uninitialized\ndata, but those are not yet rigorously defined.\n\n### Example\n```rust\n// Beware the UB\nuse std::mem::MaybeUninit;\n\nlet _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n```\n\nNote that the following is OK:\n\n```rust\nuse std::mem::MaybeUninit;\n\nlet _: [MaybeUninit<bool>; 5] = unsafe {\n MaybeUninit::uninit().assume_init()\n};\n```",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "uninit_vec",
|
||
"id_span": {
|
||
"path": "src/uninit_vec.rs",
|
||
"line": 56
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `set_len()` call that creates `Vec` with uninitialized elements.\nThis is commonly caused by calling `set_len()` right after allocating or\nreserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`.\n\n### Why is this bad?\nIt creates a `Vec` with uninitialized data, which leads to\nundefined behavior with most safe operations. Notably, uninitialized\n`Vec<u8>` must not be used with generic `Read`.\n\nMoreover, calling `set_len()` on a `Vec` created with `new()` or `default()`\ncreates out-of-bound values that lead to heap memory corruption when used.\n\n### Known Problems\nThis lint only checks directly adjacent statements.\n\n### Example\n```rust\nlet mut vec: Vec<u8> = Vec::with_capacity(1000);\nunsafe { vec.set_len(1000); }\nreader.read(&mut vec); // undefined behavior!\n```\n\n### How to fix?\n1. Use an initialized buffer:\n```rust\n let mut vec: Vec<u8> = vec![0; 1000];\n reader.read(&mut vec);\n ```\n2. Wrap the content in `MaybeUninit`:\n```rust\n let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);\n vec.set_len(1000); // `MaybeUninit` can be uninitialized\n ```\n3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:\n```rust\n let mut vec: Vec<u8> = Vec::with_capacity(1000);\n let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]`\n // perform initialization with `remaining`\n vec.set_len(...); // Safe to call `set_len()` on initialized part\n ```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "uninlined_format_args",
|
||
"id_span": {
|
||
"path": "src/format_args.rs",
|
||
"line": 127
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nDetect when a variable is not inlined in a format string,\nand suggests to inline it.\n\n### Why is this bad?\nNon-inlined code is slightly more difficult to read and understand,\nas it requires arguments to be matched against the format string.\nThe inlined syntax, where allowed, is simpler.\n\n### Example\n```rust\nformat!(\"{}\", var);\nformat!(\"{v:?}\", v = var);\nformat!(\"{0} {0}\", var);\nformat!(\"{0:1$}\", var, width);\nformat!(\"{:.*}\", prec, var);\n```\nUse instead:\n```rust\nformat!(\"{var}\");\nformat!(\"{var:?}\");\nformat!(\"{var} {var}\");\nformat!(\"{var:width$}\");\nformat!(\"{var:.prec$}\");\n```\n\nIf allow-mixed-uninlined-format-args is set to false in clippy.toml,\nthe following code will also trigger the lint:\n```rust\nformat!(\"{} {}\", var, 1+2);\n```\nUse instead:\n```rust\nformat!(\"{var} {}\", 1+2);\n```\n\n### Known Problems\n\nIf a format string contains a numbered argument that cannot be inlined\nnothing will be suggested, e.g. `println!(\"{0}={1}\", var, 1+2)`.\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-mixed-uninlined-format-args`: Whether to allow mixed uninlined format args, e.g. `format!(\"{} {}\", a, foo.bar)` (default: `true`)- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unit_arg",
|
||
"id_span": {
|
||
"path": "src/unit_types/mod.rs",
|
||
"line": 94
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for passing a unit value as an argument to a function without using a\nunit literal (`()`).\n\n### Why is this bad?\nThis is likely the result of an accidental semicolon.\n\n### Example\n```rust\nfoo({\n let a = bar();\n baz(a);\n})\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unit_cmp",
|
||
"id_span": {
|
||
"path": "src/unit_types/mod.rs",
|
||
"line": 73
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for comparisons to unit. This includes all binary\ncomparisons (like `==` and `<`) and asserts.\n\n### Why is this bad?\nUnit is always equal to itself, and thus is just a\nclumsily written constant. Mostly this happens when someone accidentally\nadds semicolons at the end of the operands.\n\n### Example\n```rust\nif {\n foo();\n} == {\n bar();\n} {\n baz();\n}\n```\nis equal to\n```rust\n{\n foo();\n bar();\n baz();\n}\n```\n\nFor asserts:\n```rust\nassert_eq!({ foo(); }, { bar(); });\n```\nwill always succeed",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unit_hash",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3077
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nDetects `().hash(_)`.\n\n### Why is this bad?\nHashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.\n\n### Example\n```rust\nmatch my_enum {\n\tEmpty => ().hash(&mut state),\n\tWithValue(x) => x.hash(&mut state),\n}\n```\nUse instead:\n```rust\nmatch my_enum {\n\tEmpty => 0_u8.hash(&mut state),\n\tWithValue(x) => x.hash(&mut state),\n}\n```",
|
||
"version": "1.58.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unit_return_expecting_ord",
|
||
"id_span": {
|
||
"path": "src/unit_return_expecting_ord.rs",
|
||
"line": 32
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for functions that expect closures of type\nFn(...) -> Ord where the implemented closure returns the unit type.\nThe lint also suggests to remove the semi-colon at the end of the statement if present.\n\n### Why is this bad?\nLikely, returning the unit type is unintentional, and\ncould simply be caused by an extra semi-colon. Since () implements Ord\nit doesn't cause a compilation error.\nThis is the same reasoning behind the unit_cmp lint.\n\n### Known problems\nIf returning unit is intentional, then there is no\nway of specifying this without triggering needless_return lint\n\n### Example\n```rust\nlet mut twins = vec![(1, 1), (2, 2)];\ntwins.sort_by_key(|x| { x.1; });\n```",
|
||
"version": "1.47.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_box_returns",
|
||
"id_span": {
|
||
"path": "src/unnecessary_box_returns.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nChecks for a return type containing a `Box<T>` where `T` implements `Sized`\n\nThe lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`,\nas returning a large `T` directly may be detrimental to performance.\n\n### Why is this bad?\n\nIt's better to just return `T` in these cases. The caller may not need\nthe value to be boxed, and it's expensive to free the memory once the\n`Box<T>` been dropped.\n\n### Example\n```rust\nfn foo() -> Box<String> {\n Box::new(String::from(\"Hello, world!\"))\n}\n```\nUse instead:\n```rust\nfn foo() -> String {\n String::from(\"Hello, world!\")\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `unnecessary-box-size`: The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint (default: `128`)",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_cast",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 207
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for casts to the same type, casts of int literals to integer types, casts of float\nliterals to float types and casts between raw pointers without changing type or constness.\n\n### Why is this bad?\nIt's just unnecessary.\n\n### Known problems\nWhen the expression on the left is a function call, the lint considers the return type to be\na type alias if it's aliased through a `use` statement\n(like `use std::io::Result as IoResult`). It will not lint such cases.\n\nThis check is also rather primitive. It will only work on primitive types without any\nintermediate references, raw pointers and trait objects may or may not work.\n\n### Example\n```rust\nlet _ = 2i32 as i32;\nlet _ = 0.5 as f32;\n```\n\nBetter:\n\n```rust\nlet _ = 2_i32;\nlet _ = 0.5_f32;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_clippy_cfg",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 461
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `#[cfg_attr(clippy, allow(clippy::lint))]`\nand suggests to replace it with `#[allow(clippy::lint)]`.\n\n### Why is this bad?\nThere is no reason to put clippy attributes behind a clippy `cfg` as they are not\nrun by anything else than clippy.\n\n### Example\n```rust\n#![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]\n```\n\nUse instead:\n```rust\n#![allow(clippy::deprecated_cfg_attr)]\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_fallible_conversions",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3746
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts\ncould be used.\n\n### Why is this bad?\nIn those cases, the `TryInto` and `TryFrom` trait implementation is a blanket impl that forwards\nto `Into` or `From`, which always succeeds.\nThe returned `Result<_, Infallible>` requires error handling to get the contained value\neven though the conversion can never fail.\n\n### Example\n```rust\nlet _: Result<i64, _> = 1i32.try_into();\nlet _: Result<i64, _> = <_>::try_from(1i32);\n```\nUse `from`/`into` instead:\n```rust\nlet _: i64 = 1i32.into();\nlet _: i64 = <_>::from(1i32);\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_filter_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1572
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `filter_map` calls that could be replaced by `filter` or `map`.\nMore specifically it checks if the closure provided is only performing one of the\nfilter or map operations and suggests the appropriate option.\n\n### Why is this bad?\nComplexity. The intent is also clearer if only a single\noperation is being performed.\n\n### Example\n```rust\nlet _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None });\n\n// As there is no transformation of the argument this could be written as:\nlet _ = (0..3).filter(|&x| x > 2);\n```\n\n```rust\nlet _ = (0..4).filter_map(|x| Some(x + 1));\n\n// As there is no conditional check on the argument this could be written as:\nlet _ = (0..4).map(|x| x + 1);\n```",
|
||
"version": "1.31.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_find_map",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1602
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `find_map` calls that could be replaced by `find` or `map`. More\nspecifically it checks if the closure provided is only performing one of the\nfind or map operations and suggests the appropriate option.\n\n### Why is this bad?\nComplexity. The intent is also clearer if only a single\noperation is being performed.\n\n### Example\n```rust\nlet _ = (0..3).find_map(|x| if x > 2 { Some(x) } else { None });\n\n// As there is no transformation of the argument this could be written as:\nlet _ = (0..3).find(|&x| x > 2);\n```\n\n```rust\nlet _ = (0..4).find_map(|x| Some(x + 1));\n\n// As there is no conditional check on the argument this could be written as:\nlet _ = (0..4).map(|x| x + 1).next();\n```",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_fold",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1542
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `fold` when a more succinct alternative exists.\nSpecifically, this checks for `fold`s which could be replaced by `any`, `all`,\n`sum` or `product`.\n\n### Why is this bad?\nReadability.\n\n### Example\n```rust\n(0..3).fold(false, |acc, x| acc || x > 2);\n```\n\nUse instead:\n```rust\n(0..3).any(|x| x > 2);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_get_then_check",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 4055
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks the usage of `.get().is_some()` or `.get().is_none()` on std map types.\n\n### Why is this bad?\nIt can be done in one call with `.contains()`/`.contains_keys()`.\n\n### Example\n```rust\nlet s: HashSet<String> = HashSet::new();\nif s.get(\"a\").is_some() {\n // code\n}\n```\nUse instead:\n```rust\nlet s: HashSet<String> = HashSet::new();\nif s.contains(\"a\") {\n // code\n}\n```",
|
||
"version": "1.78.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_join",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2325
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `.collect::<Vec<String>>().join(\"\")` on iterators.\n\n### Why is this bad?\n`.collect::<String>()` is more concise and might be more performant\n\n### Example\n```rust\nlet vector = vec![\"hello\", \"world\"];\nlet output = vector.iter().map(|item| item.to_uppercase()).collect::<Vec<String>>().join(\"\");\nprintln!(\"{}\", output);\n```\nThe correct use would be:\n```rust\nlet vector = vec![\"hello\", \"world\"];\nlet output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();\nprintln!(\"{}\", output);\n```\n### Known problems\nWhile `.collect::<String>()` is sometimes more performant, there are cases where\nusing `.collect::<String>()` over `.collect::<Vec<String>>().join(\"\")`\nwill prevent loop unrolling and will result in a negative performance impact.\n\nAdditionally, differences have been observed between aarch64 and x86_64 assembly output,\nwith aarch64 tending to producing faster assembly in more cases when using `.collect::<String>()`",
|
||
"version": "1.61.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_lazy_evaluations",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1893
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nAs the counterpart to `or_fun_call`, this lint looks for unnecessary\nlazily evaluated closures on `Option` and `Result`.\n\nThis lint suggests changing the following functions, when eager evaluation results in\nsimpler code:\n - `unwrap_or_else` to `unwrap_or`\n - `and_then` to `and`\n - `or_else` to `or`\n - `get_or_insert_with` to `get_or_insert`\n - `ok_or_else` to `ok_or`\n - `then` to `then_some` (for msrv >= 1.62.0)\n\n### Why is this bad?\nUsing eager evaluation is shorter and simpler in some cases.\n\n### Known problems\nIt is possible, but not recommended for `Deref` and `Index` to have\nside effects. Eagerly evaluating them can change the semantics of the program.\n\n### Example\n```rust\n// example code where clippy issues a warning\nlet opt: Option<u32> = None;\n\nopt.unwrap_or_else(|| 42);\n```\nUse instead:\n```rust\nlet opt: Option<u32> = None;\n\nopt.unwrap_or(42);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_literal_unwrap",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 326
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed.\n\n### Why is this bad?\nIt is better to write the value directly without the indirection.\n\n### Examples\n```rust\nlet val1 = Some(1).unwrap();\nlet val2 = Ok::<_, ()>(1).unwrap();\nlet val3 = Err::<(), _>(1).unwrap_err();\n```\n\nUse instead:\n```rust\nlet val1 = 1;\nlet val2 = 1;\nlet val3 = 1;\n```",
|
||
"version": "1.72.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_map_on_constructor",
|
||
"id_span": {
|
||
"path": "src/unnecessary_map_on_constructor.rs",
|
||
"line": 30
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nSuggests removing the use of a `map()` (or `map_err()`) method when an `Option` or `Result`\nis being constructed.\n\n### Why is this bad?\nIt introduces unnecessary complexity. Instead, the function can be called before\nconstructing the `Option` or `Result` from its return value.\n\n### Example\n```rust\nSome(4).map(i32::swap_bytes)\n```\nUse instead:\n```rust\nSome(i32::swap_bytes(4))\n```",
|
||
"version": "1.74.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_mut_passed",
|
||
"id_span": {
|
||
"path": "src/mut_reference.rs",
|
||
"line": 31
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects passing a mutable reference to a function that only\nrequires an immutable reference.\n\n### Why is this bad?\nThe mutable reference rules out all other references to\nthe value. Also the code misleads about the intent of the call site.\n\n### Example\n```rust\nvec.push(&mut value);\n```\n\nUse instead:\n```rust\nvec.push(&value);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_operation",
|
||
"id_span": {
|
||
"path": "src/no_effect.rs",
|
||
"line": 70
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for expression statements that can be reduced to a\nsub-expression.\n\n### Why is this bad?\nExpressions by themselves often have no side-effects.\nHaving such expressions reduces readability.\n\n### Example\n```rust\ncompute_array()[0];\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_owned_empty_strings",
|
||
"id_span": {
|
||
"path": "src/unnecessary_owned_empty_strings.rs",
|
||
"line": 30
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\n\nDetects cases of owned empty strings being passed as an argument to a function expecting `&str`\n\n### Why is this bad?\n\nThis results in longer and less readable code\n\n### Example\n```rust\nvec![\"1\", \"2\", \"3\"].join(&String::new());\n```\nUse instead:\n```rust\nvec![\"1\", \"2\", \"3\"].join(\"\");\n```",
|
||
"version": "1.62.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_result_map_or_else",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3992
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.map_or_else()` \"map closure\" for `Result` type.\n\n### Why is this bad?\nThis can be written more concisely by using `unwrap_or_else()`.\n\n### Example\n```rust\nlet x: Result<u32, ()> = Ok(0);\nlet y = x.map_or_else(|err| handle_error(err), |n| n);\n```\nUse instead:\n```rust\nlet x: Result<u32, ()> = Ok(0);\nlet y = x.unwrap_or_else(|err| handle_error(err));\n```",
|
||
"version": "1.77.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_safety_comment",
|
||
"id_span": {
|
||
"path": "src/undocumented_unsafe_blocks.rs",
|
||
"line": 90
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `// SAFETY: ` comments on safe code.\n\n### Why is this bad?\nSafe code has no safety requirements, so there is no need to\ndescribe safety invariants.\n\n### Example\n```rust\nuse std::ptr::NonNull;\nlet a = &mut 42;\n\n// SAFETY: references are guaranteed to be non-null.\nlet ptr = NonNull::new(a).unwrap();\n```\nUse instead:\n```rust\nuse std::ptr::NonNull;\nlet a = &mut 42;\n\nlet ptr = NonNull::new(a).unwrap();\n```",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_safety_doc",
|
||
"id_span": {
|
||
"path": "src/doc/mod.rs",
|
||
"line": 289
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the doc comments of publicly visible\nsafe functions and traits and warns if there is a `# Safety` section.\n\n### Why is this bad?\nSafe functions and traits are safe to implement and therefore do not\nneed to describe safety preconditions that users are required to uphold.\n\n### Examples\n```rust\n/// # Safety\n///\n/// This function should not be called before the horsemen are ready.\npub fn start_apocalypse_but_safely(u: &mut Universe) {\n unimplemented!();\n}\n```\n\nThe function is safe, so there shouldn't be any preconditions\nthat have to be explained for safety reasons.\n\n```rust\n/// This function should really be documented\npub fn start_apocalypse(u: &mut Universe) {\n unimplemented!();\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `check-private-items`: Whether to also run the listed lints on private items. (default: `false`)",
|
||
"version": "1.67.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_self_imports",
|
||
"id_span": {
|
||
"path": "src/unnecessary_self_imports.rs",
|
||
"line": 29
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for imports ending in `::{self}`.\n\n### Why is this bad?\nIn most cases, this can be written much more cleanly by omitting `::{self}`.\n\n### Known problems\nRemoving `::{self}` will cause any non-module items at the same path to also be imported.\nThis might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt\nto detect this scenario and that is why it is a restriction lint.\n\n### Example\n```rust\nuse std::io::{self};\n```\nUse instead:\n```rust\nuse std::io;\n```",
|
||
"version": "1.53.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_sort_by",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3111
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `Vec::sort_by` passing in a closure\nwhich compares the two arguments, either directly or indirectly.\n\n### Why is this bad?\nIt is more clear to use `Vec::sort_by_key` (or `Vec::sort` if\npossible) than to use `Vec::sort_by` and a more complicated\nclosure.\n\n### Known problems\nIf the suggested `Vec::sort_by_key` uses Reverse and it isn't already\nimported by a use statement, then it will need to be added manually.\n\n### Example\n```rust\nvec.sort_by(|a, b| a.foo().cmp(&b.foo()));\n```\nUse instead:\n```rust\nvec.sort_by_key(|a| a.foo());\n```",
|
||
"version": "1.46.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_struct_initialization",
|
||
"id_span": {
|
||
"path": "src/unnecessary_struct_initialization.rs",
|
||
"line": 36
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for initialization of a `struct` by copying a base without setting\nany field.\n\n### Why is this bad?\nReadability suffers from unnecessary struct building.\n\n### Example\n```rust\nstruct S { s: String }\n\nlet a = S { s: String::from(\"Hello, world!\") };\nlet b = S { ..a };\n```\nUse instead:\n```rust\nstruct S { s: String }\n\nlet a = S { s: String::from(\"Hello, world!\") };\nlet b = a;\n```\n\n### Known Problems\nHas false positives when the base is a place expression that cannot be\nmoved out of, see [#10547](https://github.com/rust-lang/rust-clippy/issues/10547).",
|
||
"version": "1.70.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_to_owned",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 2293
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)\nand other `to_owned`-like functions.\n\n### Why is this bad?\nThe unnecessary calls result in useless allocations.\n\n### Known problems\n`unnecessary_to_owned` can falsely trigger if `IntoIterator::into_iter` is applied to an\nowned copy of a resource and the resource is later used mutably. See\n[#8148](https://github.com/rust-lang/rust-clippy/issues/8148).\n\n### Example\n```rust\nlet path = std::path::Path::new(\"x\");\nfoo(&path.to_string_lossy().to_string());\nfn foo(s: &str) {}\n```\nUse instead:\n```rust\nlet path = std::path::Path::new(\"x\");\nfoo(&path.to_string_lossy());\nfn foo(s: &str) {}\n```",
|
||
"version": "1.59.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_unwrap",
|
||
"id_span": {
|
||
"path": "src/unwrap.rs",
|
||
"line": 45
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls of `unwrap[_err]()` that cannot fail.\n\n### Why is this bad?\nUsing `if let` or `match` is more idiomatic.\n\n### Example\n```rust\nif option.is_some() {\n do_something_with(option.unwrap())\n}\n```\n\nCould be written:\n\n```rust\nif let Some(value) = option {\n do_something_with(value)\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnecessary_wraps",
|
||
"id_span": {
|
||
"path": "src/unnecessary_wraps.rs",
|
||
"line": 54
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for private functions that only return `Ok` or `Some`.\n\n### Why is this bad?\nIt is not meaningful to wrap values when no `None` or `Err` is returned.\n\n### Known problems\nThere can be false positives if the function signature is designed to\nfit some external requirement.\n\n### Example\n```rust\nfn get_cool_number(a: bool, b: bool) -> Option<i32> {\n if a && b {\n return Some(50);\n }\n if a {\n Some(0)\n } else {\n Some(10)\n }\n}\n```\nUse instead:\n```rust\nfn get_cool_number(a: bool, b: bool) -> i32 {\n if a && b {\n return 50;\n }\n if a {\n 0\n } else {\n 10\n }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unneeded_field_pattern",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 60
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for structure field patterns bound to wildcards.\n\n### Why is this bad?\nUsing `..` instead is shorter and leaves the focus on\nthe fields that are actually bound.\n\n### Example\n```rust\nlet f = Foo { a: 0, b: 0, c: 0 };\n\nmatch f {\n Foo { a: _, b: 0, .. } => {},\n Foo { a: _, b: _, c: _ } => {},\n}\n```\n\nUse instead:\n```rust\nlet f = Foo { a: 0, b: 0, c: 0 };\n\nmatch f {\n Foo { b: 0, .. } => {},\n Foo { .. } => {},\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unneeded_wildcard_pattern",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 317
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for tuple patterns with a wildcard\npattern (`_`) is next to a rest pattern (`..`).\n\n_NOTE_: While `_, ..` means there is at least one element left, `..`\nmeans there are 0 or more elements left. This can make a difference\nwhen refactoring, but shouldn't result in errors in the refactored code,\nsince the wildcard pattern isn't used anyway.\n\n### Why is this bad?\nThe wildcard pattern is unneeded as the rest pattern\ncan match that element as well.\n\n### Example\n```rust\nmatch t {\n TupleStruct(0, .., _) => (),\n _ => (),\n}\n```\n\nUse instead:\n```rust\nmatch t {\n TupleStruct(0, ..) => (),\n _ => (),\n}\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unnested_or_patterns",
|
||
"id_span": {
|
||
"path": "src/unnested_or_patterns.rs",
|
||
"line": 44
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for unnested or-patterns, e.g., `Some(0) | Some(2)` and\nsuggests replacing the pattern with a nested one, `Some(0 | 2)`.\n\nAnother way to think of this is that it rewrites patterns in\n*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*.\n\n### Why is this bad?\nIn the example above, `Some` is repeated, which unnecessarily complicates the pattern.\n\n### Example\n```rust\nfn main() {\n if let Some(0) | Some(2) = Some(0) {}\n}\n```\nUse instead:\n```rust\nfn main() {\n if let Some(0 | 2) = Some(0) {}\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "1.46.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unreachable",
|
||
"id_span": {
|
||
"path": "src/panic_unimplemented.rs",
|
||
"line": 75
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `unreachable!`.\n\n### Why is this bad?\nThis macro can cause code to panic.\n\n### Example\n```rust\nunreachable!();\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unreadable_literal",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 38
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if a long integral or floating-point constant does\nnot contain underscores.\n\n### Why is this bad?\nReading long numbers is difficult without separators.\n\n### Example\n```rust\n61864918973511\n```\n\nUse instead:\n```rust\n61_864_918_973_511\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `unreadable-literal-lint-fractions`: Should the fraction of a decimal be linted to include separators. (default: `true`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unsafe_derive_deserialize",
|
||
"id_span": {
|
||
"path": "src/derive.rs",
|
||
"line": 157
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for deriving `serde::Deserialize` on a type that\nhas methods using `unsafe`.\n\n### Why is this bad?\nDeriving `serde::Deserialize` will create a constructor\nthat may violate invariants held by another constructor.\n\n### Example\n```rust\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\npub struct Foo {\n // ..\n}\n\nimpl Foo {\n pub fn new() -> Self {\n // setup here ..\n }\n\n pub unsafe fn parts() -> (&str, &str) {\n // assumes invariants hold\n }\n}\n```",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unsafe_removed_from_name",
|
||
"id_span": {
|
||
"path": "src/unsafe_removed_from_name.rs",
|
||
"line": 25
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for imports that remove \"unsafe\" from an item's\nname.\n\n### Why is this bad?\nRenaming makes it less clear which traits and\nstructures are unsafe.\n\n### Example\n```rust\nuse std::cell::{UnsafeCell as TotallySafeCell};\n\nextern crate crossbeam;\nuse crossbeam::{spawn_unsafe as spawn};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unsafe_vector_initialization",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 134
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint used to suggest replacing `let mut vec =\nVec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The\nreplacement has very different performance characteristics so the lint is\ndeprecated.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unseparated_literal_suffix",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 158
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nWarns if literal suffixes are not separated by an\nunderscore.\nTo enforce unseparated literal suffix style,\nsee the `separated_literal_suffix` lint.\n\n### Why is this bad?\nSuffix style should be consistent.\n\n### Example\n```rust\n123832i32\n```\n\nUse instead:\n```rust\n123832_i32\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unsound_collection_transmute",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 384
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for transmutes between collections whose\ntypes have different ABI, size or alignment.\n\n### Why is this bad?\nThis is undefined behavior.\n\n### Known problems\nCurrently, we cannot know whether a type is a\ncollection, so we just lint the ones that come with `std`.\n\n### Example\n```rust\n// different size, therefore likely out-of-bounds memory access\n// You absolutely do not want this in your code!\nunsafe {\n std::mem::transmute::<_, Vec<u32>>(vec![2_u16])\n};\n```\n\nYou must always iterate, map and collect the values:\n\n```rust\nvec![2_u16].into_iter().map(u32::from).collect::<Vec<_>>();\n```",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unstable_as_mut_slice",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 80
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis used to check for `Vec::as_mut_slice`, which was unstable with good\nstable alternatives. `Vec::as_mut_slice` has now been stabilized.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unstable_as_slice",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 68
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis used to check for `Vec::as_slice`, which was unstable with good\nstable alternatives. `Vec::as_slice` has now been stabilized.",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_async",
|
||
"id_span": {
|
||
"path": "src/unused_async.rs",
|
||
"line": 37
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions that are declared `async` but have no `.await`s inside of them.\n\n### Why is this bad?\nAsync functions with no async code create overhead, both mentally and computationally.\nCallers of async methods either need to be calling from an async function themselves or run it on an executor, both of which\ncauses runtime overhead and hassle for the caller.\n\n### Example\n```rust\nasync fn get_random_number() -> i64 {\n 4 // Chosen by fair dice roll. Guaranteed to be random.\n}\nlet number_future = get_random_number();\n```\n\nUse instead:\n```rust\nfn get_random_number_improved() -> i64 {\n 4 // Chosen by fair dice roll. Guaranteed to be random.\n}\nlet number_future = async { get_random_number_improved() };\n```",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_collect",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 145
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThis lint has been superseded by #[must_use] in rustc.",
|
||
"version": "1.39.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_enumerate_index",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 604
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for uses of the `enumerate` method where the index is unused (`_`)\n\n### Why is this bad?\nThe index from `.enumerate()` is immediately dropped.\n\n### Example\n```rust\nlet v = vec![1, 2, 3, 4];\nfor (_, x) in v.iter().enumerate() {\n println!(\"{x}\");\n}\n```\nUse instead:\n```rust\nlet v = vec![1, 2, 3, 4];\nfor x in v.iter() {\n println!(\"{x}\");\n}\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_format_specs",
|
||
"id_span": {
|
||
"path": "src/format_args.rs",
|
||
"line": 158
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects [formatting parameters] that have no effect on the output of\n`format!()`, `println!()` or similar macros.\n\n### Why is this bad?\nShorter format specifiers are easier to read, it may also indicate that\nan expected formatting operation such as adding padding isn't happening.\n\n### Example\n```rust\nprintln!(\"{:.}\", 1.0);\n\nprintln!(\"not padded: {:5}\", format_args!(\"...\"));\n```\nUse instead:\n```rust\nprintln!(\"{}\", 1.0);\n\nprintln!(\"not padded: {}\", format_args!(\"...\"));\n// OR\nprintln!(\"padded: {:5}\", format!(\"...\"));\n```\n\n[formatting parameters]: https://doc.rust-lang.org/std/fmt/index.html#formatting-parameters",
|
||
"version": "1.66.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_io_amount",
|
||
"id_span": {
|
||
"path": "src/unused_io_amount.rs",
|
||
"line": 43
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for unused written/read amount.\n\n### Why is this bad?\n`io::Write::write(_vectored)` and\n`io::Read::read(_vectored)` are not guaranteed to\nprocess the entire buffer. They return how many bytes were processed, which\nmight be smaller\nthan a given buffer's length. If you don't need to deal with\npartial-write/read, use\n`write_all`/`read_exact` instead.\n\nWhen working with asynchronous code (either with the `futures`\ncrate or with `tokio`), a similar issue exists for\n`AsyncWriteExt::write()` and `AsyncReadExt::read()` : these\nfunctions are also not guaranteed to process the entire\nbuffer. Your code should either handle partial-writes/reads, or\ncall the `write_all`/`read_exact` methods on those traits instead.\n\n### Known problems\nDetects only common patterns.\n\n### Examples\n```rust\nuse std::io;\nfn foo<W: io::Write>(w: &mut W) -> io::Result<()> {\n // must be `w.write_all(b\"foo\")?;`\n w.write(b\"foo\")?;\n Ok(())\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_peekable",
|
||
"id_span": {
|
||
"path": "src/unused_peekable.rs",
|
||
"line": 40
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the creation of a `peekable` iterator that is never `.peek()`ed\n\n### Why is this bad?\nCreating a peekable iterator without using any of its methods is likely a mistake,\nor just a leftover after a refactor.\n\n### Example\n```rust\nlet collection = vec![1, 2, 3];\nlet iter = collection.iter().peekable();\n\nfor item in iter {\n // ...\n}\n```\n\nUse instead:\n```rust\nlet collection = vec![1, 2, 3];\nlet iter = collection.iter();\n\nfor item in iter {\n // ...\n}\n```",
|
||
"version": "1.65.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_rounding",
|
||
"id_span": {
|
||
"path": "src/unused_rounding.rs",
|
||
"line": 27
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\n\nDetects cases where a whole-number literal float is being rounded, using\nthe `floor`, `ceil`, or `round` methods.\n\n### Why is this bad?\n\nThis is unnecessary and confusing to the reader. Doing this is probably a mistake.\n\n### Example\n```rust\nlet x = 1f32.ceil();\n```\nUse instead:\n```rust\nlet x = 1f32;\n```",
|
||
"version": "1.63.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_self",
|
||
"id_span": {
|
||
"path": "src/unused_self.rs",
|
||
"line": 34
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks methods that contain a `self` argument but don't use it\n\n### Why is this bad?\nIt may be clearer to define the method as an associated function instead\nof an instance method if it doesn't require `self`.\n\n### Example\n```rust\nstruct A;\nimpl A {\n fn method(&self) {}\n}\n```\n\nCould be written:\n\n```rust\nstruct A;\nimpl A {\n fn method() {}\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "1.40.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unused_unit",
|
||
"id_span": {
|
||
"path": "src/unused_unit.rs",
|
||
"line": 30
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for unit (`()`) expressions that can be removed.\n\n### Why is this bad?\nSuch expressions add no value, but can make the code\nless readable. Depending on formatting they can make a `break` or `return`\nstatement look like a function call.\n\n### Example\n```rust\nfn return_unit() -> () {\n ()\n}\n```\nis equivalent to\n```rust\nfn return_unit() {}\n```",
|
||
"version": "1.31.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unusual_byte_groupings",
|
||
"id_span": {
|
||
"path": "src/literal_representation.rs",
|
||
"line": 107
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns if hexadecimal or binary literals are not grouped\nby nibble or byte.\n\n### Why is this bad?\nNegatively impacts readability.\n\n### Example\n```rust\nlet x: u32 = 0xFFF_FFF;\nlet y: u8 = 0b01_011_101;\n```",
|
||
"version": "1.49.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "unwrap_in_result",
|
||
"id_span": {
|
||
"path": "src/unwrap_in_result.rs",
|
||
"line": 53
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for functions of type `Result` that contain `expect()` or `unwrap()`\n\n### Why is this bad?\nThese functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics.\n\n### Known problems\nThis can cause false positives in functions that handle both recoverable and non recoverable errors.\n\n### Example\nBefore:\n```rust\nfn divisible_by_3(i_str: String) -> Result<(), String> {\n let i = i_str\n .parse::<i32>()\n .expect(\"cannot divide the input by three\");\n\n if i % 3 != 0 {\n Err(\"Number is not divisible by 3\")?\n }\n\n Ok(())\n}\n```\n\nAfter:\n```rust\nfn divisible_by_3(i_str: String) -> Result<(), String> {\n let i = i_str\n .parse::<i32>()\n .map_err(|e| format!(\"cannot divide the input by three: {}\", e))?;\n\n if i % 3 != 0 {\n Err(\"Number is not divisible by 3\")?\n }\n\n Ok(())\n}\n```",
|
||
"version": "1.48.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "unwrap_or_default",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 531
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usages of the following functions with an argument that constructs a default value\n(e.g., `Default::default` or `String::new`):\n- `unwrap_or`\n- `unwrap_or_else`\n- `or_insert`\n- `or_insert_with`\n\n### Why is this bad?\nReadability. Using `unwrap_or_default` in place of `unwrap_or`/`unwrap_or_else`, or `or_default`\nin place of `or_insert`/`or_insert_with`, is simpler and more concise.\n\n### Known problems\nIn some cases, the argument of `unwrap_or`, etc. is needed for type inference. The lint uses a\nheuristic to try to identify such cases. However, the heuristic can produce false negatives.\n\n### Examples\n```rust\nx.unwrap_or(Default::default());\nmap.entry(42).or_insert_with(String::new);\n```\n\nUse instead:\n```rust\nx.unwrap_or_default();\nmap.entry(42).or_default();\n```\n### Past names\n\n* `unwrap_or_else_default`\n\n",
|
||
"version": "1.56.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"unwrap_or_else_default"
|
||
]
|
||
},
|
||
{
|
||
"id": "unwrap_used",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 300
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.\n\n### Why is this bad?\nIt is better to handle the `None` or `Err` case,\nor at least call `.expect(_)` with a more helpful message. Still, for a lot of\nquick-and-dirty code, `unwrap` is a good choice, which is why this lint is\n`Allow` by default.\n\n`result.unwrap()` will let the thread panic on `Err` values.\nNormally, you want to implement more sophisticated error handling,\nand propagate errors upwards with `?` operator.\n\nEven if you want to panic on errors, not all `Error`s implement good\nmessages on display. Therefore, it may be beneficial to look at the places\nwhere they may get displayed. Activate this lint to do just that.\n\n### Examples\n```rust\noption.unwrap();\nresult.unwrap();\n```\n\nUse instead:\n```rust\noption.expect(\"more helpful message\");\nresult.expect(\"more helpful message\");\n```\n\nIf [expect_used](#expect_used) is enabled, instead:\n```rust\noption?;\n\n// or\n\nresult?;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allow-unwrap-in-tests`: Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` (default: `false`)\n### Past names\n\n* `option_unwrap_used`\n* `result_unwrap_used`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
},
|
||
"former_ids": [
|
||
"option_unwrap_used",
|
||
"result_unwrap_used"
|
||
]
|
||
},
|
||
{
|
||
"id": "upper_case_acronyms",
|
||
"id_span": {
|
||
"path": "src/upper_case_acronyms.rs",
|
||
"line": 37
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for fully capitalized names and optionally names containing a capitalized acronym.\n\n### Why is this bad?\nIn CamelCase, acronyms count as one word.\nSee [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case)\nfor more.\n\nBy default, the lint only triggers on fully-capitalized names.\nYou can use the `upper-case-acronyms-aggressive: true` config option to enable linting\non all camel case names\n\n### Known problems\nWhen two acronyms are contiguous, the lint can't tell where\nthe first acronym ends and the second starts, so it suggests to lowercase all of\nthe letters in the second acronym.\n\n### Example\n```rust\nstruct HTTPResponse;\n```\nUse instead:\n```rust\nstruct HttpResponse;\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `upper-case-acronyms-aggressive`: Enables verbose mode. Triggers if there is more than one uppercase char next to each other (default: `false`)",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "use_debug",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 123
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of `Debug` formatting. The purpose of this\nlint is to catch debugging remnants.\n\n### Why is this bad?\nThe purpose of the `Debug` trait is to facilitate\ndebugging Rust code. It should not be used in user-facing output.\n\n### Example\n```rust\nprintln!(\"{:?}\", foo);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "use_self",
|
||
"id_span": {
|
||
"path": "src/use_self.rs",
|
||
"line": 52
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for unnecessary repetition of structure name when a\nreplacement with `Self` is applicable.\n\n### Why is this bad?\nUnnecessary repetition. Mixed use of `Self` and struct\nname\nfeels inconsistent.\n\n### Known problems\n- Unaddressed false negative in fn bodies of trait implementations\n\n### Example\n```rust\nstruct Foo;\nimpl Foo {\n fn new() -> Foo {\n Foo {}\n }\n}\n```\ncould be\n```rust\nstruct Foo;\nimpl Foo {\n fn new() -> Self {\n Self {}\n }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `msrv`: The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "used_underscore_binding",
|
||
"id_span": {
|
||
"path": "src/misc.rs",
|
||
"line": 78
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for the use of bindings with a single leading\nunderscore.\n\n### Why is this bad?\nA single leading underscore is usually used to indicate\nthat a binding will not be used. Using such a binding breaks this\nexpectation.\n\n### Known problems\nThe lint does not work properly with desugaring and\nmacro, it has been allowed in the meantime.\n\n### Example\n```rust\nlet _x = 0;\nlet y = _x + 1; // Here we are using `_x`, even though it has a leading\n // underscore. We should rename `_x` to `x`\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_asref",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1517
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `.as_ref()` or `.as_mut()` where the\ntypes before and after the call are the same.\n\n### Why is this bad?\nThe call is unnecessary.\n\n### Example\n```rust\nlet x: &[i32] = &[1, 2, 3, 4, 5];\ndo_stuff(x.as_ref());\n```\nThe correct use would be:\n```rust\nlet x: &[i32] = &[1, 2, 3, 4, 5];\ndo_stuff(x);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_attribute",
|
||
"id_span": {
|
||
"path": "src/attrs/mod.rs",
|
||
"line": 95
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `extern crate` and `use` items annotated with\nlint attributes.\n\nThis lint permits lint attributes for lints emitted on the items themself.\nFor `use` items these lints are:\n* deprecated\n* unreachable_pub\n* unused_imports\n* clippy::enum_glob_use\n* clippy::macro_use_imports\n* clippy::wildcard_imports\n\nFor `extern crate` items these lints are:\n* `unused_imports` on items with `#[macro_use]`\n\n### Why is this bad?\nLint attributes have no effect on crate imports. Most\nlikely a `!` was forgotten.\n\n### Example\n```rust\n#[deny(dead_code)]\nextern crate foo;\n#[forbid(dead_code)]\nuse foo::bar;\n```\n\nUse instead:\n```rust\n#[allow(unused_imports)]\nuse foo::baz;\n#[allow(unused_imports)]\n#[macro_use]\nextern crate baz;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_conversion",
|
||
"id_span": {
|
||
"path": "src/useless_conversion.rs",
|
||
"line": 37
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls\nwhich uselessly convert to the same type.\n\n### Why is this bad?\nRedundant code.\n\n### Example\n```rust\n// format!() returns a `String`\nlet s: String = format!(\"hello\").into();\n```\n\nUse instead:\n```rust\nlet s: String = format!(\"hello\");\n```\n### Past names\n\n* `identity_conversion`\n\n",
|
||
"version": "1.45.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
},
|
||
"former_ids": [
|
||
"identity_conversion"
|
||
]
|
||
},
|
||
{
|
||
"id": "useless_format",
|
||
"id_span": {
|
||
"path": "src/format.rs",
|
||
"line": 37
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for the use of `format!(\"string literal with no\nargument\")` and `format!(\"{}\", foo)` where `foo` is a string.\n\n### Why is this bad?\nThere is no point of doing that. `format!(\"foo\")` can\nbe replaced by `\"foo\".to_owned()` if you really need a `String`. The even\nworse `&format!(\"foo\")` is often encountered in the wild. `format!(\"{}\",\nfoo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`\nif `foo: &str`.\n\n### Examples\n```rust\nlet foo = \"foo\";\nformat!(\"{}\", foo);\n```\n\nUse instead:\n```rust\nlet foo = \"foo\";\nfoo.to_owned();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_let_if_seq",
|
||
"id_span": {
|
||
"path": "src/let_if_seq.rs",
|
||
"line": 52
|
||
},
|
||
"group": "nursery",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for variable declarations immediately followed by a\nconditional affectation.\n\n### Why is this bad?\nThis is not idiomatic Rust.\n\n### Example\n```rust\nlet foo;\n\nif bar() {\n foo = 42;\n} else {\n foo = 0;\n}\n\nlet mut baz = None;\n\nif bar() {\n baz = Some(42);\n}\n```\n\nshould be written\n\n```rust\nlet foo = if bar() {\n 42\n} else {\n 0\n};\n\nlet baz = if bar() {\n Some(42)\n} else {\n None\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_transmute",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 66
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for transmutes to the original type of the object\nand transmutes that could be a cast.\n\n### Why is this bad?\nReadability. The code tricks people into thinking that\nsomething complex is going on.\n\n### Example\n```rust\ncore::intrinsics::transmute(t); // where the result type is the same as `t`'s\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "useless_vec",
|
||
"id_span": {
|
||
"path": "src/vec.rs",
|
||
"line": 48
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `vec![..]` when using `[..]` would\nbe possible.\n\n### Why is this bad?\nThis is less efficient.\n\n### Example\n```rust\nfn foo(_x: &[u8]) {}\n\nfoo(&vec![1, 2]);\n```\n\nUse instead:\n```rust\nfoo(&[1, 2]);\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `too-large-for-stack`: The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap (default: `200`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "vec_box",
|
||
"id_span": {
|
||
"path": "src/types/mod.rs",
|
||
"line": 81
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n\n### Why is this bad?\n`Vec` already keeps its contents in a separate area on\nthe heap. So if you `Box` its contents, you just add another level of indirection.\n\n### Known problems\nVec<Box<T: Sized>> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530),\n1st comment).\n\n### Example\n```rust\nstruct X {\n values: Vec<Box<i32>>,\n}\n```\n\nBetter:\n\n```rust\nstruct X {\n values: Vec<i32>,\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)- `vec-box-size-threshold`: The size of the boxed type in bytes, where boxing in a `Vec` is allowed (default: `4096`)",
|
||
"version": "1.33.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "vec_init_then_push",
|
||
"id_span": {
|
||
"path": "src/vec_init_then_push.rs",
|
||
"line": 44
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for calls to `push` immediately after creating a new `Vec`.\n\nIf the `Vec` is created using `with_capacity` this will only lint if the capacity is a\nconstant and the number of pushes is greater than or equal to the initial capacity.\n\nIf the `Vec` is extended after the initial sequence of pushes and it was default initialized\nthen this will only lint after there were at least four pushes. This number may change in\nthe future.\n\n### Why is this bad?\nThe `vec![]` macro is both more performant and easier to read than\nmultiple `push` calls.\n\n### Example\n```rust\nlet mut v = Vec::new();\nv.push(0);\nv.push(1);\nv.push(2);\n```\nUse instead:\n```rust\nlet v = vec![0, 1, 2];\n```",
|
||
"version": "1.51.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "vec_resize_to_zero",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3133
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nFinds occurrences of `Vec::resize(0, an_int)`\n\n### Why is this bad?\nThis is probably an argument inversion mistake.\n\n### Example\n```rust\nvec![1, 2, 3, 4, 5].resize(0, 5)\n```\n\nUse instead:\n```rust\nvec![1, 2, 3, 4, 5].clear()\n```",
|
||
"version": "1.46.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "verbose_bit_mask",
|
||
"id_span": {
|
||
"path": "src/operators/mod.rs",
|
||
"line": 269
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for bit masks that can be replaced by a call\nto `trailing_zeros`\n\n### Why is this bad?\n`x.trailing_zeros() > 4` is much clearer than `x & 15\n== 0`\n\n### Known problems\nllvm generates better code for `x & 15 == 0` on x86\n\n### Example\n```rust\nif x & 0b1111 == 0 { }\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `verbose-bit-mask-threshold`: The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' (default: `1`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "verbose_file_reads",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3160
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for usage of File::read_to_end and File::read_to_string.\n\n### Why is this bad?\n`fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.\nSee also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)\n\n### Example\n```rust\nlet mut f = File::open(\"foo.txt\").unwrap();\nlet mut bytes = Vec::new();\nf.read_to_end(&mut bytes).unwrap();\n```\nCan be written more concisely as\n```rust\nlet mut bytes = fs::read(\"foo.txt\").unwrap();\n```",
|
||
"version": "1.44.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "waker_clone_wake",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 3719
|
||
},
|
||
"group": "perf",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for usage of `waker.clone().wake()`\n\n### Why is this bad?\nCloning the waker is not necessary, `wake_by_ref()` enables the same operation\nwithout extra cloning/dropping.\n\n### Example\n```rust\nwaker.clone().wake();\n```\nShould be written\n```rust\nwaker.wake_by_ref();\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "while_immutable_condition",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 414
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks whether variables used within while loop condition\ncan be (and are) mutated in the body.\n\n### Why is this bad?\nIf the condition is unchanged, entering the body of the loop\nwill lead to an infinite loop.\n\n### Known problems\nIf the `while`-loop is in a closure, the check for mutation of the\ncondition variables in the body can cause false negatives. For example when only `Upvar` `a` is\nin the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.\n\n### Example\n```rust\nlet i = 0;\nwhile i > 10 {\n println!(\"let me loop forever!\");\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "while_let_loop",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 207
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nDetects `loop + match` combinations that are easier\nwritten as a `while let` loop.\n\n### Why is this bad?\nThe `while let` loop is usually shorter and more\nreadable.\n\n### Known problems\nSometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)).\n\n### Example\n```rust\nloop {\n let x = match y {\n Some(x) => x,\n None => break,\n };\n // .. do something with x\n}\n// is easier written as\nwhile let Some(x) = y {\n // .. do something with x\n};\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "HasPlaceholders"
|
||
}
|
||
},
|
||
{
|
||
"id": "while_let_on_iterator",
|
||
"id_span": {
|
||
"path": "src/loops/mod.rs",
|
||
"line": 300
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `while let` expressions on iterators.\n\n### Why is this bad?\nReadability. A simple `for` loop is shorter and conveys\nthe intent better.\n\n### Example\n```rust\nwhile let Some(val) = iter.next() {\n ..\n}\n```\n\nUse instead:\n```rust\nfor val in &mut iter {\n ..\n}\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "wildcard_dependencies",
|
||
"id_span": {
|
||
"path": "src/cargo/mod.rs",
|
||
"line": 164
|
||
},
|
||
"group": "cargo",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for wildcard dependencies in the `Cargo.toml`.\n\n### Why is this bad?\n[As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),\nit is highly unlikely that you work with any possible version of your dependency,\nand wildcard dependencies would cause unnecessary breakage in the ecosystem.\n\n### Example\n```toml\n[dependencies]\nregex = \"*\"\n```",
|
||
"version": "1.32.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "wildcard_enum_match_arm",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 290
|
||
},
|
||
"group": "restriction",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for wildcard enum matches using `_`.\n\n### Why is this bad?\nNew enum variants added by library updates can be missed.\n\n### Known problems\nSuggested replacements may be incorrect if guards exhaustively cover some\nvariants, and also may not use correct path to enum if it's not present in the current scope.\n\n### Example\n```rust\nmatch x {\n Foo::A(_) => {},\n _ => {},\n}\n```\n\nUse instead:\n```rust\nmatch x {\n Foo::A(_) => {},\n Foo::B(_) => {},\n}\n```",
|
||
"version": "1.34.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "wildcard_imports",
|
||
"id_span": {
|
||
"path": "src/wildcard_imports.rs",
|
||
"line": 95
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for wildcard imports `use _::*`.\n\n### Why is this bad?\nwildcard imports can pollute the namespace. This is especially bad if\nyou try to import something through a wildcard, that already has been imported by name from\na different source:\n\n```rust\nuse crate1::foo; // Imports a function named foo\nuse crate2::*; // Has a function named foo\n\nfoo(); // Calls crate1::foo\n```\n\nThis can lead to confusing error messages at best and to unexpected behavior at worst.\n\n### Exceptions\nWildcard imports are allowed from modules that their name contains `prelude`. Many crates\n(including the standard library) provide modules named \"prelude\" specifically designed\nfor wildcard import.\n\n`use super::*` is allowed in test modules. This is defined as any module with \"test\" in the name.\n\nThese exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag.\n\n### Known problems\nIf macros are imported through the wildcard, this macro is not included\nby the suggestion and has to be added by hand.\n\nApplying the suggestion when explicit imports of the things imported with a glob import\nexist, may result in `unused_imports` warnings.\n\n### Example\n```rust\nuse crate1::*;\n\nfoo();\n```\n\nUse instead:\n```rust\nuse crate1::foo;\n\nfoo();\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `allowed-wildcard-imports`: List of path segments allowed to have wildcard imports.\n\n #### Example\n\n```toml\n allowed-wildcard-imports = [ \"utils\", \"common\" ]\n ```\n\n #### Noteworthy\n\n 1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.\n 2. Paths with any segment that containing the word 'prelude'\n are already allowed by default. (default: `[]`)- `warn-on-all-wildcard-imports`: Whether to allow certain wildcard imports (prelude, super in tests). (default: `false`)",
|
||
"version": "1.43.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "wildcard_in_or_patterns",
|
||
"id_span": {
|
||
"path": "src/matches/mod.rs",
|
||
"line": 359
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for wildcard pattern used with others patterns in same match arm.\n\n### Why is this bad?\nWildcard pattern already covers any other pattern as it will match anyway.\nIt makes the code less readable, especially to spot wildcard pattern use in match arm.\n\n### Example\n```rust\nmatch s {\n \"a\" => {},\n \"bar\" | _ => {},\n}\n```\n\nUse instead:\n```rust\nmatch s {\n \"a\" => {},\n _ => {},\n}\n```",
|
||
"version": "1.42.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "write_literal",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 232
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns about the use of literals as `write!`/`writeln!` args.\n\n### Why is this bad?\nUsing literals as `writeln!` args is inefficient\n(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary\n(i.e., just put the literal in the format string)\n\n### Example\n```rust\nwriteln!(buf, \"{}\", \"foo\");\n```\n\nUse instead:\n```rust\nwriteln!(buf, \"foo\");\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "write_with_newline",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 204
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns when you use `write!()` with a format\nstring that\nends in a newline.\n\n### Why is this bad?\nYou should use `writeln!()` instead, which appends the\nnewline.\n\n### Example\n```rust\nwrite!(buf, \"Hello {}!\\n\", name);\n```\n\nUse instead:\n```rust\nwriteln!(buf, \"Hello {}!\", name);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "writeln_empty_string",
|
||
"id_span": {
|
||
"path": "src/write.rs",
|
||
"line": 173
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nThis lint warns when you use `writeln!(buf, \"\")` to\nprint a newline.\n\n### Why is this bad?\nYou should use `writeln!(buf)`, which is simpler.\n\n### Example\n```rust\nwriteln!(buf, \"\");\n```\n\nUse instead:\n```rust\nwriteln!(buf);\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "wrong_pub_self_convention",
|
||
"id_span": {
|
||
"path": "src/deprecated_lints.rs",
|
||
"line": 215
|
||
},
|
||
"group": "deprecated",
|
||
"level": "none",
|
||
"docs": "\n### What it does\nNothing. This lint has been deprecated.\n\n### Deprecation reason\nThe `avoid_breaking_exported_api` config option was added, which\nenables the `wrong_self_conversion` lint for public items.",
|
||
"version": "1.54.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "wrong_self_convention",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 442
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for methods with certain name prefixes or suffixes, and which\ndo not adhere to standard conventions regarding how `self` is taken.\nThe actual rules are:\n\n|Prefix |Postfix |`self` taken | `self` type |\n|-------|------------|-------------------------------|--------------|\n|`as_` | none |`&self` or `&mut self` | any |\n|`from_`| none | none | any |\n|`into_`| none |`self` | any |\n|`is_` | none |`&mut self` or `&self` or none | any |\n|`to_` | `_mut` |`&mut self` | any |\n|`to_` | not `_mut` |`self` | `Copy` |\n|`to_` | not `_mut` |`&self` | not `Copy` |\n\nNote: Clippy doesn't trigger methods with `to_` prefix in:\n- Traits definition.\nClippy can not tell if a type that implements a trait is `Copy` or not.\n- Traits implementation, when `&self` is taken.\nThe method signature is controlled by the trait and often `&self` is required for all types that implement the trait\n(see e.g. the `std::string::ToString` trait).\n\nClippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is required.\n\nPlease find more info here:\nhttps://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv\n\n### Why is this bad?\nConsistency breeds readability. If you follow the\nconventions, your users won't be surprised that they, e.g., need to supply a\nmutable reference to a `as_..` function.\n\n### Example\n```rust\nimpl X {\n fn as_str(self) -> &'static str {\n // ..\n }\n}\n```\n\n### Configuration\nThis lint has the following configuration variables:\n\n- `avoid-breaking-exported-api`: Suppress lints whenever the suggested change would cause breakage for other crates. (default: `true`)",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "wrong_transmute",
|
||
"id_span": {
|
||
"path": "src/transmute/mod.rs",
|
||
"line": 46
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for transmutes that can't ever be correct on any\narchitecture.\n\n### Why is this bad?\nIt's basically guaranteed to be undefined behavior.\n\n### Known problems\nWhen accessing C, users might want to store pointer\nsized objects in `extradata` arguments to save an allocation.\n\n### Example\n```rust\nlet ptr: *const T = core::intrinsics::transmute('x')\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "zero_divided_by_zero",
|
||
"id_span": {
|
||
"path": "src/zero_div_zero.rs",
|
||
"line": 24
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for `0.0 / 0.0`.\n\n### Why is this bad?\nIt's less readable than `f32::NAN` or `f64::NAN`.\n\n### Example\n```rust\nlet nan = 0.0f32 / 0.0;\n```\n\nUse instead:\n```rust\nlet nan = f32::NAN;\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "zero_prefixed_literal",
|
||
"id_span": {
|
||
"path": "src/misc_early/mod.rs",
|
||
"line": 225
|
||
},
|
||
"group": "complexity",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nWarns if an integral constant literal starts with `0`.\n\n### Why is this bad?\nIn some languages (including the infamous C language\nand most of its\nfamily), this marks an octal constant. In Rust however, this is a decimal\nconstant. This could\nbe confusing for both the writer and a reader of the constant.\n\n### Example\n\nIn Rust:\n```rust\nfn main() {\n let a = 0123;\n println!(\"{}\", a);\n}\n```\n\nprints `123`, while in C:\n\n```c\n#include <stdio.h>\n\nint main() {\n int a = 0123;\n printf(\"%d\\n\", a);\n}\n```\n\nprints `83` (as `83 == 0o123` while `123 == 0o173`).",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MaybeIncorrect"
|
||
}
|
||
},
|
||
{
|
||
"id": "zero_ptr",
|
||
"id_span": {
|
||
"path": "src/casts/mod.rs",
|
||
"line": 688
|
||
},
|
||
"group": "style",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nCatch casts from `0` to some pointer type\n\n### Why is this bad?\nThis generally means `null` and is better expressed as\n{`std`, `core`}`::ptr::`{`null`, `null_mut`}.\n\n### Example\n```rust\nlet a = 0 as *const u32;\n```\n\nUse instead:\n```rust\nlet a = std::ptr::null::<u32>();\n```",
|
||
"version": "pre 1.29.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "MachineApplicable"
|
||
}
|
||
},
|
||
{
|
||
"id": "zero_repeat_side_effects",
|
||
"id_span": {
|
||
"path": "src/zero_repeat_side_effects.rs",
|
||
"line": 40
|
||
},
|
||
"group": "suspicious",
|
||
"level": "warn",
|
||
"docs": "\n### What it does\nChecks for array or vec initializations which call a function or method,\nbut which have a repeat count of zero.\n\n### Why is this bad?\nSuch an initialization, despite having a repeat length of 0, will still call the inner function.\nThis may not be obvious and as such there may be unintended side effects in code.\n\n### Example\n```rust\nfn side_effect() -> i32 {\n println!(\"side effect\");\n 10\n}\nlet a = [side_effect(); 0];\n```\nUse instead:\n```rust\nfn side_effect() -> i32 {\n println!(\"side effect\");\n 10\n}\nside_effect();\nlet a: [i32; 0] = [];\n```",
|
||
"version": "1.75.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unspecified"
|
||
}
|
||
},
|
||
{
|
||
"id": "zero_sized_map_values",
|
||
"id_span": {
|
||
"path": "src/zero_sized_map_values.rs",
|
||
"line": 39
|
||
},
|
||
"group": "pedantic",
|
||
"level": "allow",
|
||
"docs": "\n### What it does\nChecks for maps with zero-sized value types anywhere in the code.\n\n### Why is this bad?\nSince there is only a single value for a zero-sized type, a map\ncontaining zero sized values is effectively a set. Using a set in that case improves\nreadability and communicates intent more clearly.\n\n### Known problems\n* A zero-sized type cannot be recovered later if it contains private fields.\n* This lints the signature of public items\n\n### Example\n```rust\nfn unique_words(text: &str) -> HashMap<&str, ()> {\n todo!();\n}\n```\nUse instead:\n```rust\nfn unique_words(text: &str) -> HashSet<&str> {\n todo!();\n}\n```",
|
||
"version": "1.50.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
},
|
||
{
|
||
"id": "zst_offset",
|
||
"id_span": {
|
||
"path": "src/methods/mod.rs",
|
||
"line": 1731
|
||
},
|
||
"group": "correctness",
|
||
"level": "deny",
|
||
"docs": "\n### What it does\nChecks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to\nzero-sized types\n\n### Why is this bad?\nThis is a no-op, and likely unintended\n\n### Example\n```rust\nunsafe { (&() as *const ()).offset(1) };\n```",
|
||
"version": "1.41.0",
|
||
"applicability": {
|
||
"is_multi_part_suggestion": false,
|
||
"applicability": "Unresolved"
|
||
}
|
||
}
|
||
] |