Remove src/docs
This commit is contained in:
parent
a201518a8a
commit
8134566988
@ -1,25 +0,0 @@
|
||||
### What it does
|
||||
Checks for comparisons where one side of the relation is
|
||||
either the minimum or maximum value for its type and warns if it involves a
|
||||
case that is always true or always false. Only integer and boolean types are
|
||||
checked.
|
||||
|
||||
### Why is this bad?
|
||||
An expression like `min <= x` may misleadingly imply
|
||||
that it is possible for `x` to be less than the minimum. Expressions like
|
||||
`max < x` are probably mistakes.
|
||||
|
||||
### Known problems
|
||||
For `usize` the size of the current compile target will
|
||||
be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
|
||||
a comparison to detect target pointer width will trigger this lint. One can
|
||||
use `mem::sizeof` and compare its value or conditional compilation
|
||||
attributes
|
||||
like `#[cfg(target_pointer_width = "64")] ..` instead.
|
||||
|
||||
### Example
|
||||
```
|
||||
let vec: Vec<isize> = Vec::new();
|
||||
if vec.len() <= 0 {}
|
||||
if 100 > i32::MAX {}
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
|
||||
Finds items imported through `alloc` when available through `core`.
|
||||
|
||||
### Why is this bad?
|
||||
|
||||
Crates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are
|
||||
imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint
|
||||
is also useful for crates migrating to become `no_std` compatible.
|
||||
|
||||
### Example
|
||||
```
|
||||
use alloc::slice::from_ref;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
use core::slice::from_ref;
|
||||
```
|
@ -1,22 +0,0 @@
|
||||
### What it does
|
||||
Checks for attributes that allow lints without a reason.
|
||||
|
||||
(This requires the `lint_reasons` feature)
|
||||
|
||||
### Why is this bad?
|
||||
Allowing a lint should always have a reason. This reason should be documented to
|
||||
ensure that others understand the reasoning
|
||||
|
||||
### Example
|
||||
```
|
||||
#![feature(lint_reasons)]
|
||||
|
||||
#![allow(clippy::some_lint)]
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
#![feature(lint_reasons)]
|
||||
|
||||
#![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks for ranges which almost include the entire range of letters from 'a' to 'z', but
|
||||
don't because they're a half open range.
|
||||
|
||||
### Why is this bad?
|
||||
This (`'a'..'z'`) is almost certainly a typo meant to include all letters.
|
||||
|
||||
### Example
|
||||
```
|
||||
let _ = 'a'..'z';
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let _ = 'a'..='z';
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks for `foo = bar; bar = foo` sequences.
|
||||
|
||||
### Why is this bad?
|
||||
This looks like a failed attempt to swap.
|
||||
|
||||
### Example
|
||||
```
|
||||
a = b;
|
||||
b = a;
|
||||
```
|
||||
If swapping is intended, use `swap()` instead:
|
||||
```
|
||||
std::mem::swap(&mut a, &mut b);
|
||||
```
|
@ -1,24 +0,0 @@
|
||||
### What it does
|
||||
Checks for floating point literals that approximate
|
||||
constants which are defined in
|
||||
[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
|
||||
or
|
||||
[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
|
||||
respectively, suggesting to use the predefined constant.
|
||||
|
||||
### Why is this bad?
|
||||
Usually, the definition in the standard library is more
|
||||
precise than what people come up with. If you find that your definition is
|
||||
actually more precise, please [file a Rust
|
||||
issue](https://github.com/rust-lang/rust/issues).
|
||||
|
||||
### Example
|
||||
```
|
||||
let x = 3.14;
|
||||
let y = 1_f64 / x;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let x = std::f32::consts::PI;
|
||||
let y = std::f64::consts::FRAC_1_PI;
|
||||
```
|
@ -1,33 +0,0 @@
|
||||
### What it does
|
||||
Checks any kind of arithmetic operation of any type.
|
||||
|
||||
Operators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust
|
||||
Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
|
||||
or can panic (`/`, `%`).
|
||||
|
||||
Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant
|
||||
environments, allowed types and non-constant operations that won't overflow are ignored.
|
||||
|
||||
### Why is this bad?
|
||||
For integers, overflow will trigger a panic in debug builds or wrap the result in
|
||||
release mode; division by zero will cause a panic in either mode. As a result, it is
|
||||
desirable to explicitly call checked, wrapping or saturating arithmetic methods.
|
||||
|
||||
#### Example
|
||||
```
|
||||
// `n` can be any number, including `i32::MAX`.
|
||||
fn foo(n: i32) -> i32 {
|
||||
n + 1
|
||||
}
|
||||
```
|
||||
|
||||
Third-party types can also overflow or present unwanted side-effects.
|
||||
|
||||
#### Example
|
||||
```
|
||||
use rust_decimal::Decimal;
|
||||
let _n = Decimal::MAX + Decimal::MAX;
|
||||
```
|
||||
|
||||
### Allowed types
|
||||
Custom allowed types can be specified through the "arithmetic-side-effects-allowed" filter.
|
@ -1,32 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `as` conversions.
|
||||
|
||||
Note that this lint is specialized in linting *every single* use of `as`
|
||||
regardless of whether good alternatives exist or not.
|
||||
If you want more precise lints for `as`, please consider using these separate lints:
|
||||
`unnecessary_cast`, `cast_lossless/cast_possible_truncation/cast_possible_wrap/cast_precision_loss/cast_sign_loss`,
|
||||
`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.
|
||||
There is a good explanation the reason why this lint should work in this way and how it is useful
|
||||
[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).
|
||||
|
||||
### Why is this bad?
|
||||
`as` conversions will perform many kinds of
|
||||
conversions, including silently lossy conversions and dangerous coercions.
|
||||
There are cases when it makes sense to use `as`, so the lint is
|
||||
Allow by default.
|
||||
|
||||
### Example
|
||||
```
|
||||
let a: u32;
|
||||
...
|
||||
f(a as u16);
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
f(a.try_into()?);
|
||||
|
||||
// or
|
||||
|
||||
f(a.try_into().expect("Unexpected u16 overflow in f"));
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer
|
||||
|
||||
### Why is this bad?
|
||||
Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior
|
||||
mutability is used, making it unlikely that having it as a mutable pointer is correct.
|
||||
|
||||
### Example
|
||||
```
|
||||
let string = String::with_capacity(1);
|
||||
let ptr = string.as_ptr() as *mut u8;
|
||||
unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let mut string = String::with_capacity(1);
|
||||
let ptr = string.as_mut_ptr();
|
||||
unsafe { ptr.write(4) };
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Check for the usage of `as _` conversion using inferred type.
|
||||
|
||||
### Why is this bad?
|
||||
The conversion might include lossy conversion and dangerous cast that might go
|
||||
undetected due to the type being inferred.
|
||||
|
||||
The lint is allowed by default as using `_` is less wordy than always specifying the type.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn foo(n: usize) {}
|
||||
let n: u16 = 256;
|
||||
foo(n as _);
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
fn foo(n: usize) {}
|
||||
let n: u16 = 256;
|
||||
foo(n as usize);
|
||||
```
|
@ -1,14 +0,0 @@
|
||||
### What it does
|
||||
Checks for `assert!(true)` and `assert!(false)` calls.
|
||||
|
||||
### Why is this bad?
|
||||
Will be optimized out by the compiler or should probably be replaced by a
|
||||
`panic!()` or `unreachable!()`
|
||||
|
||||
### Example
|
||||
```
|
||||
assert!(false)
|
||||
assert!(true)
|
||||
const B: bool = false;
|
||||
assert!(B)
|
||||
```
|
@ -1,14 +0,0 @@
|
||||
### What it does
|
||||
Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls.
|
||||
|
||||
### Why is this bad?
|
||||
An assertion failure cannot output an useful message of the error.
|
||||
|
||||
### Known problems
|
||||
The suggested replacement decreases the readability of code and log output.
|
||||
|
||||
### Example
|
||||
```
|
||||
assert!(r.is_ok());
|
||||
assert!(r.is_err());
|
||||
```
|
@ -1,28 +0,0 @@
|
||||
### What it does
|
||||
Checks for `a = a op b` or `a = b commutative_op a`
|
||||
patterns.
|
||||
|
||||
### Why is this bad?
|
||||
These can be written as the shorter `a op= b`.
|
||||
|
||||
### Known problems
|
||||
While forbidden by the spec, `OpAssign` traits may have
|
||||
implementations that differ from the regular `Op` impl.
|
||||
|
||||
### Example
|
||||
```
|
||||
let mut a = 5;
|
||||
let b = 0;
|
||||
// ...
|
||||
|
||||
a = a + b;
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let mut a = 5;
|
||||
let b = 0;
|
||||
// ...
|
||||
|
||||
a += b;
|
||||
```
|
@ -1,28 +0,0 @@
|
||||
### What it does
|
||||
Checks for async blocks that yield values of types
|
||||
that can themselves be awaited.
|
||||
|
||||
### Why is this bad?
|
||||
An await is likely missing.
|
||||
|
||||
### Example
|
||||
```
|
||||
async fn foo() {}
|
||||
|
||||
fn bar() {
|
||||
let x = async {
|
||||
foo()
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
async fn foo() {}
|
||||
|
||||
fn bar() {
|
||||
let x = async {
|
||||
foo().await
|
||||
};
|
||||
}
|
||||
```
|
@ -1,29 +0,0 @@
|
||||
### What it does
|
||||
Allows users to configure types which should not be held across `await`
|
||||
suspension points.
|
||||
|
||||
### Why is this bad?
|
||||
There are some types which are perfectly "safe" to be used concurrently
|
||||
from a memory access perspective but will cause bugs at runtime if they
|
||||
are held in such a way.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
await-holding-invalid-types = [
|
||||
# You can specify a type name
|
||||
"CustomLockType",
|
||||
# You can (optionally) specify a reason
|
||||
{ path = "OtherCustomLockType", reason = "Relies on a thread local" }
|
||||
]
|
||||
```
|
||||
|
||||
```
|
||||
struct CustomLockType;
|
||||
struct OtherCustomLockType;
|
||||
async fn foo() {
|
||||
let _x = CustomLockType;
|
||||
let _y = OtherCustomLockType;
|
||||
baz().await; // Lint violation
|
||||
}
|
||||
```
|
@ -1,51 +0,0 @@
|
||||
### What it does
|
||||
Checks for calls to await while holding a non-async-aware MutexGuard.
|
||||
|
||||
### Why is this bad?
|
||||
The Mutex types found in std::sync and parking_lot
|
||||
are not designed to operate in an async context across await points.
|
||||
|
||||
There are two potential solutions. One is to use an async-aware Mutex
|
||||
type. Many asynchronous foundation crates provide such a Mutex type. The
|
||||
other solution is to ensure the mutex is unlocked before calling await,
|
||||
either by introducing a scope or an explicit call to Drop::drop.
|
||||
|
||||
### Known problems
|
||||
Will report false positive for explicitly dropped guards
|
||||
([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is
|
||||
to wrap the `.lock()` call in a block instead of explicitly dropping the guard.
|
||||
|
||||
### Example
|
||||
```
|
||||
async fn foo(x: &Mutex<u32>) {
|
||||
let mut guard = x.lock().unwrap();
|
||||
*guard += 1;
|
||||
baz().await;
|
||||
}
|
||||
|
||||
async fn bar(x: &Mutex<u32>) {
|
||||
let mut guard = x.lock().unwrap();
|
||||
*guard += 1;
|
||||
drop(guard); // explicit drop
|
||||
baz().await;
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
async fn foo(x: &Mutex<u32>) {
|
||||
{
|
||||
let mut guard = x.lock().unwrap();
|
||||
*guard += 1;
|
||||
}
|
||||
baz().await;
|
||||
}
|
||||
|
||||
async fn bar(x: &Mutex<u32>) {
|
||||
{
|
||||
let mut guard = x.lock().unwrap();
|
||||
*guard += 1;
|
||||
} // guard dropped here at end of scope
|
||||
baz().await;
|
||||
}
|
||||
```
|
@ -1,47 +0,0 @@
|
||||
### What it does
|
||||
Checks for calls to await while holding a `RefCell` `Ref` or `RefMut`.
|
||||
|
||||
### Why is this bad?
|
||||
`RefCell` refs only check for exclusive mutable access
|
||||
at runtime. Holding onto a `RefCell` ref across an `await` suspension point
|
||||
risks panics from a mutable ref shared while other refs are outstanding.
|
||||
|
||||
### Known problems
|
||||
Will report false positive for explicitly dropped refs
|
||||
([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). A workaround for this is
|
||||
to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.
|
||||
|
||||
### Example
|
||||
```
|
||||
async fn foo(x: &RefCell<u32>) {
|
||||
let mut y = x.borrow_mut();
|
||||
*y += 1;
|
||||
baz().await;
|
||||
}
|
||||
|
||||
async fn bar(x: &RefCell<u32>) {
|
||||
let mut y = x.borrow_mut();
|
||||
*y += 1;
|
||||
drop(y); // explicit drop
|
||||
baz().await;
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
async fn foo(x: &RefCell<u32>) {
|
||||
{
|
||||
let mut y = x.borrow_mut();
|
||||
*y += 1;
|
||||
}
|
||||
baz().await;
|
||||
}
|
||||
|
||||
async fn bar(x: &RefCell<u32>) {
|
||||
{
|
||||
let mut y = x.borrow_mut();
|
||||
*y += 1;
|
||||
} // y dropped here at end of scope
|
||||
baz().await;
|
||||
}
|
||||
```
|
@ -1,30 +0,0 @@
|
||||
### What it does
|
||||
Checks for incompatible bit masks in comparisons.
|
||||
|
||||
The formula for detecting if an expression of the type `_ <bit_op> m
|
||||
<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
|
||||
{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following
|
||||
table:
|
||||
|
||||
|Comparison |Bit Op|Example |is always|Formula |
|
||||
|------------|------|-------------|---------|----------------------|
|
||||
|`==` or `!=`| `&` |`x & 2 == 3` |`false` |`c & m != c` |
|
||||
|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |
|
||||
|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |
|
||||
|`==` or `!=`| `\|` |`x \| 1 == 0`|`false` |`c \| m != c` |
|
||||
|`<` or `>=`| `\|` |`x \| 1 < 1` |`false` |`m >= c` |
|
||||
|`<=` or `>` | `\|` |`x \| 1 > 0` |`true` |`m > c` |
|
||||
|
||||
### Why is this bad?
|
||||
If the bits that the comparison cares about are always
|
||||
set to zero or one by the bit mask, the comparison is constant `true` or
|
||||
`false` (depending on mask, compared value, and operators).
|
||||
|
||||
So the code is actively misleading, and the only reason someone would write
|
||||
this intentionally is to win an underhanded Rust contest or create a
|
||||
test-case for this lint.
|
||||
|
||||
### Example
|
||||
```
|
||||
if (x & 1 == 2) { }
|
||||
```
|
@ -1,22 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or
|
||||
`_.or_else(|x| Err(y))`.
|
||||
|
||||
### Why is this bad?
|
||||
Readability, this can be written more concisely as
|
||||
`_.map(|x| y)` or `_.map_err(|x| y)`.
|
||||
|
||||
### Example
|
||||
```
|
||||
let _ = opt().and_then(|s| Some(s.len()));
|
||||
let _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });
|
||||
let _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });
|
||||
```
|
||||
|
||||
The correct use would be:
|
||||
|
||||
```
|
||||
let _ = opt().map(|s| s.len());
|
||||
let _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });
|
||||
let _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
|
||||
|
||||
### Why is this bad?
|
||||
Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
|
||||
These lints should only be enabled on a lint-by-lint basis and with careful consideration.
|
||||
|
||||
### Example
|
||||
```
|
||||
#![deny(clippy::restriction)]
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
#![deny(clippy::as_conversions)]
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Checks for `if` conditions that use blocks containing an
|
||||
expression, statements or conditions that use closures with blocks.
|
||||
|
||||
### Why is this bad?
|
||||
Style, using blocks in the condition makes it hard to read.
|
||||
|
||||
### Examples
|
||||
```
|
||||
if { true } { /* ... */ }
|
||||
|
||||
if { let x = somefunc(); x } { /* ... */ }
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
if true { /* ... */ }
|
||||
|
||||
let res = { let x = somefunc(); x };
|
||||
if res { /* ... */ }
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
This lint warns about boolean comparisons in assert-like macros.
|
||||
|
||||
### Why is this bad?
|
||||
It is shorter to use the equivalent.
|
||||
|
||||
### Example
|
||||
```
|
||||
assert_eq!("a".is_empty(), false);
|
||||
assert_ne!("a".is_empty(), true);
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
assert!(!"a".is_empty());
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
Checks for expressions of the form `x == true`,
|
||||
`x != true` and order comparisons such as `x < true` (or vice versa) and
|
||||
suggest using the variable directly.
|
||||
|
||||
### Why is this bad?
|
||||
Unnecessary code.
|
||||
|
||||
### Example
|
||||
```
|
||||
if x == true {}
|
||||
if y == false {}
|
||||
```
|
||||
use `x` directly:
|
||||
```
|
||||
if x {}
|
||||
if !y {}
|
||||
```
|
@ -1,26 +0,0 @@
|
||||
### What it does
|
||||
Instead of using an if statement to convert a bool to an int,
|
||||
this lint suggests using a `from()` function or an `as` coercion.
|
||||
|
||||
### Why is this bad?
|
||||
Coercion or `from()` is idiomatic way to convert bool to a number.
|
||||
Both methods are guaranteed to return 1 for true, and 0 for false.
|
||||
|
||||
See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
|
||||
|
||||
### Example
|
||||
```
|
||||
if condition {
|
||||
1_i64
|
||||
} else {
|
||||
0
|
||||
};
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
i64::from(condition);
|
||||
```
|
||||
or
|
||||
```
|
||||
condition as i64;
|
||||
```
|
@ -1,26 +0,0 @@
|
||||
### What it does
|
||||
Checks for the usage of `&expr as *const T` or
|
||||
`&mut expr as *mut T`, and suggest using `ptr::addr_of` or
|
||||
`ptr::addr_of_mut` instead.
|
||||
|
||||
### Why is this bad?
|
||||
This would improve readability and avoid creating a reference
|
||||
that points to an uninitialized value or unaligned place.
|
||||
Read the `ptr::addr_of` docs for more information.
|
||||
|
||||
### Example
|
||||
```
|
||||
let val = 1;
|
||||
let p = &val as *const i32;
|
||||
|
||||
let mut val_mut = 1;
|
||||
let p_mut = &mut val_mut as *mut i32;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let val = 1;
|
||||
let p = std::ptr::addr_of!(val);
|
||||
|
||||
let mut val_mut = 1;
|
||||
let p_mut = std::ptr::addr_of_mut!(val_mut);
|
||||
```
|
@ -1,27 +0,0 @@
|
||||
### What it does
|
||||
Checks for `&*(&T)`.
|
||||
|
||||
### Why is this bad?
|
||||
Dereferencing and then borrowing a reference value has no effect in most cases.
|
||||
|
||||
### Known problems
|
||||
False negative on such code:
|
||||
```
|
||||
let x = &12;
|
||||
let addr_x = &x as *const _ as usize;
|
||||
let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.
|
||||
// But if we fix it, assert will fail.
|
||||
assert_ne!(addr_x, addr_y);
|
||||
```
|
||||
|
||||
### Example
|
||||
```
|
||||
let s = &String::new();
|
||||
|
||||
let a: &String = &* s;
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let a: &String = s;
|
||||
```
|
@ -1,40 +0,0 @@
|
||||
### What it does
|
||||
Checks if `const` items which is interior mutable (e.g.,
|
||||
contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
|
||||
|
||||
### Why is this bad?
|
||||
Consts are copied everywhere they are referenced, i.e.,
|
||||
every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
these types in the first place.
|
||||
|
||||
The `const` value should be stored inside a `static` item.
|
||||
|
||||
### Known problems
|
||||
When an enum has variants with interior mutability, use of its non
|
||||
interior mutable variants can generate false positives. See issue
|
||||
[#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
|
||||
|
||||
Types that have underlying or potential interior mutability trigger the lint whether
|
||||
the interior mutable field is used or not. See issues
|
||||
[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
|
||||
[#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
|
||||
|
||||
### Example
|
||||
```
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
|
||||
CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
|
||||
static STATIC_ATOM: AtomicUsize = CONST_ATOM;
|
||||
STATIC_ATOM.store(9, SeqCst);
|
||||
assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for use of `&Box<T>` anywhere in the code.
|
||||
Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
|
||||
|
||||
### Why is this bad?
|
||||
A `&Box<T>` parameter requires the function caller to box `T` first before passing it to a function.
|
||||
Using `&T` defines a concrete type for the parameter and generalizes the function, this would also
|
||||
auto-deref to `&T` at the function call site if passed a `&Box<T>`.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn foo(bar: &Box<T>) { ... }
|
||||
```
|
||||
|
||||
Better:
|
||||
|
||||
```
|
||||
fn foo(bar: &T) { ... }
|
||||
```
|
@ -1,23 +0,0 @@
|
||||
### What it does
|
||||
Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code.
|
||||
Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
|
||||
|
||||
### Why is this bad?
|
||||
Collections already keeps their contents in a separate area on
|
||||
the heap. So if you `Box` them, you just add another level of indirection
|
||||
without any benefit whatsoever.
|
||||
|
||||
### Example
|
||||
```
|
||||
struct X {
|
||||
values: Box<Vec<Foo>>,
|
||||
}
|
||||
```
|
||||
|
||||
Better:
|
||||
|
||||
```
|
||||
struct X {
|
||||
values: Vec<Foo>,
|
||||
}
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
checks for `Box::new(T::default())`, which is better written as
|
||||
`Box::<T>::default()`.
|
||||
|
||||
### Why is this bad?
|
||||
First, it's more complex, involving two calls instead of one.
|
||||
Second, `Box::default()` can be faster
|
||||
[in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
|
||||
|
||||
### Example
|
||||
```
|
||||
let x: Box<String> = Box::new(Default::default());
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let x: Box<String> = Box::default();
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `Box<T>` where an unboxed `T` would
|
||||
work fine.
|
||||
|
||||
### Why is this bad?
|
||||
This is an unnecessary allocation, and bad for
|
||||
performance. It is only necessary to allocate if you wish to move the box
|
||||
into something.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn foo(x: Box<u32>) {}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
fn foo(x: u32) {}
|
||||
```
|
@ -1,32 +0,0 @@
|
||||
### What it does
|
||||
Checks if the `if` and `else` block contain shared code that can be
|
||||
moved out of the blocks.
|
||||
|
||||
### Why is this bad?
|
||||
Duplicate code is less maintainable.
|
||||
|
||||
### Known problems
|
||||
* The lint doesn't check if the moved expressions modify values that are being used in
|
||||
the if condition. The suggestion can in that case modify the behavior of the program.
|
||||
See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)
|
||||
|
||||
### Example
|
||||
```
|
||||
let foo = if … {
|
||||
println!("Hello World");
|
||||
13
|
||||
} else {
|
||||
println!("Hello World");
|
||||
42
|
||||
};
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
println!("Hello World");
|
||||
let foo = if … {
|
||||
13
|
||||
} else {
|
||||
42
|
||||
};
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Warns if a generic shadows a built-in type.
|
||||
|
||||
### Why is this bad?
|
||||
This gives surprising type errors.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
impl<u32> Foo<u32> {
|
||||
fn impl_func(&self) -> u32 {
|
||||
42
|
||||
}
|
||||
}
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
It checks for `str::bytes().count()` and suggests replacing it with
|
||||
`str::len()`.
|
||||
|
||||
### Why is this bad?
|
||||
`str::bytes().count()` is longer and may not be as performant as using
|
||||
`str::len()`.
|
||||
|
||||
### Example
|
||||
```
|
||||
"hello".bytes().count();
|
||||
String::from("hello").bytes().count();
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
"hello".len();
|
||||
String::from("hello").len();
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for the use of `.bytes().nth()`.
|
||||
|
||||
### Why is this bad?
|
||||
`.as_bytes().get()` is more efficient and more
|
||||
readable.
|
||||
|
||||
### Example
|
||||
```
|
||||
"Hello".bytes().nth(3);
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
"Hello".as_bytes().get(3);
|
||||
```
|
@ -1,33 +0,0 @@
|
||||
### What it does
|
||||
Checks to see if all common metadata is defined in
|
||||
`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
|
||||
|
||||
### Why is this bad?
|
||||
It will be more difficult for users to discover the
|
||||
purpose of the crate, and key information related to it.
|
||||
|
||||
### Example
|
||||
```
|
||||
[package]
|
||||
name = "clippy"
|
||||
version = "0.0.212"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["clippy", "lint", "plugin"]
|
||||
categories = ["development-tools", "development-tools::cargo-plugins"]
|
||||
```
|
||||
|
||||
Should include a description field like:
|
||||
|
||||
```
|
||||
[package]
|
||||
name = "clippy"
|
||||
version = "0.0.212"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["clippy", "lint", "plugin"]
|
||||
categories = ["development-tools", "development-tools::cargo-plugins"]
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Checks for calls to `ends_with` with possible file extensions
|
||||
and suggests to use a case-insensitive approach instead.
|
||||
|
||||
### Why is this bad?
|
||||
`ends_with` is case-sensitive and may not detect files with a valid extension.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn is_rust_file(filename: &str) -> bool {
|
||||
filename.ends_with(".rs")
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
fn is_rust_file(filename: &str) -> bool {
|
||||
let filename = std::path::Path::new(filename);
|
||||
filename.extension()
|
||||
.map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
|
||||
}
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for uses of the `abs()` method that cast the result to unsigned.
|
||||
|
||||
### Why is this bad?
|
||||
The `unsigned_abs()` method avoids panic when called on the MIN value.
|
||||
|
||||
### Example
|
||||
```
|
||||
let x: i32 = -42;
|
||||
let y: u32 = x.abs() as u32;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let x: i32 = -42;
|
||||
let y: u32 = x.unsigned_abs();
|
||||
```
|
@ -1,11 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts from an enum tuple constructor to an integer.
|
||||
|
||||
### Why is this bad?
|
||||
The cast is easily confused with casting a c-like enum value to an integer.
|
||||
|
||||
### Example
|
||||
```
|
||||
enum E { X(i32) };
|
||||
let _ = E::X as usize;
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts from an enum type to an integral type which will definitely truncate the
|
||||
value.
|
||||
|
||||
### Why is this bad?
|
||||
The resulting integral value will not match the value of the variant it came from.
|
||||
|
||||
### Example
|
||||
```
|
||||
enum E { X = 256 };
|
||||
let _ = E::X as u8;
|
||||
```
|
@ -1,26 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts between numerical types that may
|
||||
be replaced by safe conversion functions.
|
||||
|
||||
### Why is this bad?
|
||||
Rust's `as` keyword will perform many kinds of
|
||||
conversions, including silently lossy conversions. Conversion functions such
|
||||
as `i32::from` will only perform lossless conversions. Using the conversion
|
||||
functions prevents conversions from turning into silent lossy conversions if
|
||||
the types of the input expressions ever change, and make it easier for
|
||||
people reading the code to know that the conversion is lossless.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn as_u64(x: u8) -> u64 {
|
||||
x as u64
|
||||
}
|
||||
```
|
||||
|
||||
Using `::from` would look like this:
|
||||
|
||||
```
|
||||
fn as_u64(x: u8) -> u64 {
|
||||
u64::from(x)
|
||||
}
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks for a known NaN float being cast to an integer
|
||||
|
||||
### Why is this bad?
|
||||
NaNs are cast into zero, so one could simply use this and make the
|
||||
code more readable. The lint could also hint at a programmer error.
|
||||
|
||||
### Example
|
||||
```
|
||||
let _: (0.0_f32 / 0.0) as u64;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let _: = 0_u64;
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts between numerical types that may
|
||||
truncate large values. This is expected behavior, so the cast is `Allow` by
|
||||
default.
|
||||
|
||||
### Why is this bad?
|
||||
In some problem domains, it is good practice to avoid
|
||||
truncation. This lint can be activated to help assess where additional
|
||||
checks could be beneficial.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn as_u8(x: u64) -> u8 {
|
||||
x as u8
|
||||
}
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts from an unsigned type to a signed type of
|
||||
the same size. Performing such a cast is a 'no-op' for the compiler,
|
||||
i.e., nothing is changed at the bit level, and the binary representation of
|
||||
the value is reinterpreted. This can cause wrapping if the value is too big
|
||||
for the target signed type. However, the cast works as defined, so this lint
|
||||
is `Allow` by default.
|
||||
|
||||
### Why is this bad?
|
||||
While such a cast is not bad in itself, the results can
|
||||
be surprising when this is not the intended behavior, as demonstrated by the
|
||||
example below.
|
||||
|
||||
### Example
|
||||
```
|
||||
u32::MAX as i32; // will yield a value of `-1`
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts from any numerical to a float type where
|
||||
the receiving type cannot store all values from the original type without
|
||||
rounding errors. This possible rounding is to be expected, so this lint is
|
||||
`Allow` by default.
|
||||
|
||||
Basically, this warns on casting any integer with 32 or more bits to `f32`
|
||||
or any 64-bit integer to `f64`.
|
||||
|
||||
### Why is this bad?
|
||||
It's not bad at all. But in some applications it can be
|
||||
helpful to know where precision loss can take place. This lint can help find
|
||||
those places in the code.
|
||||
|
||||
### Example
|
||||
```
|
||||
let x = u64::MAX;
|
||||
x as f64;
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts, using `as` or `pointer::cast`,
|
||||
from a less-strictly-aligned pointer to a more-strictly-aligned pointer
|
||||
|
||||
### Why is this bad?
|
||||
Dereferencing the resulting pointer may be undefined
|
||||
behavior.
|
||||
|
||||
### Known problems
|
||||
Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
|
||||
on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like
|
||||
u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
|
||||
|
||||
### Example
|
||||
```
|
||||
let _ = (&1u8 as *const u8) as *const u16;
|
||||
let _ = (&mut 1u8 as *mut u8) as *mut u16;
|
||||
|
||||
(&1u8 as *const u8).cast::<u16>();
|
||||
(&mut 1u8 as *mut u8).cast::<u16>();
|
||||
```
|
@ -1,28 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts of `&T` to `&mut T` anywhere in the code.
|
||||
|
||||
### Why is this bad?
|
||||
It’s basically guaranteed to be undefined behavior.
|
||||
`UnsafeCell` is the only way to obtain aliasable data that is considered
|
||||
mutable.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn x(r: &i32) {
|
||||
unsafe {
|
||||
*(r as *const _ as *mut _) += 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Instead consider using interior mutability types.
|
||||
|
||||
```
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
fn x(r: &UnsafeCell<i32>) {
|
||||
unsafe {
|
||||
*r.get() += 1;
|
||||
}
|
||||
}
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks for casts from a signed to an unsigned numerical
|
||||
type. In this case, negative values wrap around to large positive values,
|
||||
which can be quite surprising in practice. However, as the cast works as
|
||||
defined, this lint is `Allow` by default.
|
||||
|
||||
### Why is this bad?
|
||||
Possibly surprising results. You can activate this lint
|
||||
as a one-time check to see where numerical wrapping can arise.
|
||||
|
||||
### Example
|
||||
```
|
||||
let y: i8 = -1;
|
||||
y as u128; // will return 18446744073709551615
|
||||
```
|
@ -1,38 +0,0 @@
|
||||
### What it does
|
||||
Checks for `as` casts between raw pointers to slices with differently sized elements.
|
||||
|
||||
### Why is this bad?
|
||||
The produced raw pointer to a slice does not update its length metadata. The produced
|
||||
pointer will point to a different number of bytes than the original pointer because the
|
||||
length metadata of a raw slice pointer is in elements rather than bytes.
|
||||
Producing a slice reference from the raw pointer will either create a slice with
|
||||
less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.
|
||||
|
||||
### Example
|
||||
// Missing data
|
||||
```
|
||||
let a = [1_i32, 2, 3, 4];
|
||||
let p = &a as *const [i32] as *const [u8];
|
||||
unsafe {
|
||||
println!("{:?}", &*p);
|
||||
}
|
||||
```
|
||||
// Undefined Behavior (note: also potential alignment issues)
|
||||
```
|
||||
let a = [1_u8, 2, 3, 4];
|
||||
let p = &a as *const [u8] as *const [u32];
|
||||
unsafe {
|
||||
println!("{:?}", &*p);
|
||||
}
|
||||
```
|
||||
Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
|
||||
```
|
||||
let a = [1_i32, 2, 3, 4];
|
||||
let old_ptr = &a as *const [i32];
|
||||
// The data pointer is cast to a pointer to the target `u8` not `[u8]`
|
||||
// The length comes from the known length of 4 i32s times the 4 bytes per i32
|
||||
let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);
|
||||
unsafe {
|
||||
println!("{:?}", &*new_ptr);
|
||||
}
|
||||
```
|
@ -1,20 +0,0 @@
|
||||
### What it does
|
||||
Checks for a raw slice being cast to a slice pointer
|
||||
|
||||
### Why is this bad?
|
||||
This can result in multiple `&mut` references to the same location when only a pointer is
|
||||
required.
|
||||
`ptr::slice_from_raw_parts` is a safe alternative that doesn't require
|
||||
the same [safety requirements] to be upheld.
|
||||
|
||||
### Example
|
||||
```
|
||||
let _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;
|
||||
let _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);
|
||||
let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
|
||||
```
|
||||
[safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Checks for expressions where a character literal is cast
|
||||
to `u8` and suggests using a byte literal instead.
|
||||
|
||||
### Why is this bad?
|
||||
In general, casting values to smaller types is
|
||||
error-prone and should be avoided where possible. In the particular case of
|
||||
converting a character literal to u8, it is easy to avoid by just using a
|
||||
byte literal instead. As an added bonus, `b'a'` is even slightly shorter
|
||||
than `'a' as u8`.
|
||||
|
||||
### Example
|
||||
```
|
||||
'x' as u8
|
||||
```
|
||||
|
||||
A better version, using the byte literal:
|
||||
|
||||
```
|
||||
b'x'
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `_.chars().last()` or
|
||||
`_.chars().next_back()` on a `str` to check if it ends with a given char.
|
||||
|
||||
### Why is this bad?
|
||||
Readability, this can be written more concisely as
|
||||
`_.ends_with(_)`.
|
||||
|
||||
### Example
|
||||
```
|
||||
name.chars().last() == Some('_') || name.chars().next_back() == Some('-');
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
name.ends_with('_') || name.ends_with('-');
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `.chars().next()` on a `str` to check
|
||||
if it starts with a given char.
|
||||
|
||||
### Why is this bad?
|
||||
Readability, this can be written more concisely as
|
||||
`_.starts_with(_)`.
|
||||
|
||||
### Example
|
||||
```
|
||||
let name = "foo";
|
||||
if name.chars().next() == Some('_') {};
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let name = "foo";
|
||||
if name.starts_with('_') {};
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks for explicit bounds checking when casting.
|
||||
|
||||
### Why is this bad?
|
||||
Reduces the readability of statements & is error prone.
|
||||
|
||||
### Example
|
||||
```
|
||||
foo <= i32::MAX as u32;
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
i32::try_from(foo).is_ok();
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `.clone()` on an `&&T`.
|
||||
|
||||
### Why is this bad?
|
||||
Cloning an `&&T` copies the inner `&T`, instead of
|
||||
cloning the underlying `T`.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn main() {
|
||||
let x = vec![1];
|
||||
let y = &&x;
|
||||
let z = y.clone();
|
||||
println!("{:p} {:p}", *y, z); // prints out the same pointer
|
||||
}
|
||||
```
|
@ -1,11 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `.clone()` on a `Copy` type.
|
||||
|
||||
### Why is this bad?
|
||||
The only reason `Copy` types implement `Clone` is for
|
||||
generics, not for using the `clone` method on a concrete type.
|
||||
|
||||
### Example
|
||||
```
|
||||
42u64.clone();
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `.clone()` on a ref-counted pointer,
|
||||
(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
|
||||
function syntax instead (e.g., `Rc::clone(foo)`).
|
||||
|
||||
### Why is this bad?
|
||||
Calling '.clone()' on an Rc, Arc, or Weak
|
||||
can obscure the fact that only the pointer is being cloned, not the underlying
|
||||
data.
|
||||
|
||||
### Example
|
||||
```
|
||||
let x = Rc::new(1);
|
||||
|
||||
x.clone();
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
Rc::clone(&x);
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for usages of `cloned()` on an `Iterator` or `Option` where
|
||||
`copied()` could be used instead.
|
||||
|
||||
### Why is this bad?
|
||||
`copied()` is better because it guarantees that the type being cloned
|
||||
implements `Copy`.
|
||||
|
||||
### Example
|
||||
```
|
||||
[1, 2, 3].iter().cloned();
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
[1, 2, 3].iter().copied();
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for comparisons to NaN.
|
||||
|
||||
### Why is this bad?
|
||||
NaN does not compare meaningfully to anything – not
|
||||
even itself – so those comparisons are simply wrong.
|
||||
|
||||
### Example
|
||||
```
|
||||
if x == f32::NAN { }
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
if x.is_nan() { }
|
||||
```
|
@ -1,23 +0,0 @@
|
||||
### What it does
|
||||
This lint checks for equality comparisons with `ptr::null`
|
||||
|
||||
### Why is this bad?
|
||||
It's easier and more readable to use the inherent
|
||||
`.is_null()`
|
||||
method instead
|
||||
|
||||
### Example
|
||||
```
|
||||
use std::ptr;
|
||||
|
||||
if x == ptr::null {
|
||||
// ..
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
if x.is_null() {
|
||||
// ..
|
||||
}
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
Checks for conversions to owned values just for the sake
|
||||
of a comparison.
|
||||
|
||||
### Why is this bad?
|
||||
The comparison can operate on a reference, so creating
|
||||
an owned value effectively throws it away directly afterwards, which is
|
||||
needlessly consuming code and heap space.
|
||||
|
||||
### Example
|
||||
```
|
||||
if x.to_owned() == y {}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
if x == y {}
|
||||
```
|
@ -1,13 +0,0 @@
|
||||
### What it does
|
||||
Checks for methods with high cognitive complexity.
|
||||
|
||||
### Why is this bad?
|
||||
Methods of high cognitive complexity tend to be hard to
|
||||
both read and maintain. Also LLVM will tend to optimize small methods better.
|
||||
|
||||
### Known problems
|
||||
Sometimes it's hard to find a way to reduce the
|
||||
complexity.
|
||||
|
||||
### Example
|
||||
You'll see it when you get the warning.
|
@ -1,29 +0,0 @@
|
||||
### What it does
|
||||
Checks for collapsible `else { if ... }` expressions
|
||||
that can be collapsed to `else if ...`.
|
||||
|
||||
### Why is this bad?
|
||||
Each `if`-statement adds one level of nesting, which
|
||||
makes code look more complex than it really is.
|
||||
|
||||
### Example
|
||||
```
|
||||
|
||||
if x {
|
||||
…
|
||||
} else {
|
||||
if y {
|
||||
…
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Should be written:
|
||||
|
||||
```
|
||||
if x {
|
||||
…
|
||||
} else if y {
|
||||
…
|
||||
}
|
||||
```
|
@ -1,23 +0,0 @@
|
||||
### What it does
|
||||
Checks for nested `if` statements which can be collapsed
|
||||
by `&&`-combining their conditions.
|
||||
|
||||
### Why is this bad?
|
||||
Each `if`-statement adds one level of nesting, which
|
||||
makes code look more complex than it really is.
|
||||
|
||||
### Example
|
||||
```
|
||||
if x {
|
||||
if y {
|
||||
// …
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
if x && y {
|
||||
// …
|
||||
}
|
||||
```
|
@ -1,31 +0,0 @@
|
||||
### What it does
|
||||
Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
|
||||
without adding any branches.
|
||||
|
||||
Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
|
||||
cases where merging would most likely make the code more readable.
|
||||
|
||||
### Why is this bad?
|
||||
It is unnecessarily verbose and complex.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn func(opt: Option<Result<u64, String>>) {
|
||||
let n = match opt {
|
||||
Some(n) => match n {
|
||||
Ok(n) => n,
|
||||
_ => return,
|
||||
}
|
||||
None => return,
|
||||
};
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
fn func(opt: Option<Result<u64, String>>) {
|
||||
let n = match opt {
|
||||
Some(Ok(n)) => n,
|
||||
_ => return,
|
||||
};
|
||||
}
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for consecutive calls to `str::replace` (2 or more)
|
||||
that can be collapsed into a single call.
|
||||
|
||||
### Why is this bad?
|
||||
Consecutive `str::replace` calls scan the string multiple times
|
||||
with repetitive code.
|
||||
|
||||
### Example
|
||||
```
|
||||
let hello = "hesuo worpd"
|
||||
.replace('s', "l")
|
||||
.replace("u", "l")
|
||||
.replace('p', "l");
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
|
||||
```
|
@ -1,36 +0,0 @@
|
||||
### What it does
|
||||
Checks comparison chains written with `if` that can be
|
||||
rewritten with `match` and `cmp`.
|
||||
|
||||
### Why is this bad?
|
||||
`if` is not guaranteed to be exhaustive and conditionals can get
|
||||
repetitive
|
||||
|
||||
### Known problems
|
||||
The match statement may be slower due to the compiler
|
||||
not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)
|
||||
|
||||
### Example
|
||||
```
|
||||
fn f(x: u8, y: u8) {
|
||||
if x > y {
|
||||
a()
|
||||
} else if x < y {
|
||||
b()
|
||||
} else {
|
||||
c()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
use std::cmp::Ordering;
|
||||
fn f(x: u8, y: u8) {
|
||||
match x.cmp(&y) {
|
||||
Ordering::Greater => a(),
|
||||
Ordering::Less => b(),
|
||||
Ordering::Equal => c()
|
||||
}
|
||||
}
|
||||
```
|
@ -1,31 +0,0 @@
|
||||
### What it does
|
||||
Checks for comparing to an empty slice such as `""` or `[]`,
|
||||
and suggests using `.is_empty()` where applicable.
|
||||
|
||||
### Why is this bad?
|
||||
Some structures can answer `.is_empty()` much faster
|
||||
than checking for equality. So it is good to get into the habit of using
|
||||
`.is_empty()`, and having it is cheap.
|
||||
Besides, it makes the intent clearer than a manual comparison in some contexts.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
if s == "" {
|
||||
..
|
||||
}
|
||||
|
||||
if arr == [] {
|
||||
..
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
if s.is_empty() {
|
||||
..
|
||||
}
|
||||
|
||||
if arr.is_empty() {
|
||||
..
|
||||
}
|
||||
```
|
@ -1,20 +0,0 @@
|
||||
### What it does
|
||||
Checks for types that implement `Copy` as well as
|
||||
`Iterator`.
|
||||
|
||||
### Why is this bad?
|
||||
Implicit copies can be confusing when working with
|
||||
iterator combinators.
|
||||
|
||||
### Example
|
||||
```
|
||||
#[derive(Copy, Clone)]
|
||||
struct Countdown(u8);
|
||||
|
||||
impl Iterator for Countdown {
|
||||
// ...
|
||||
}
|
||||
|
||||
let a: Vec<_> = my_iterator.take(1).collect();
|
||||
let b: Vec<_> = my_iterator.collect();
|
||||
```
|
@ -1,35 +0,0 @@
|
||||
### What it does
|
||||
Checks for use of `crate` as opposed to `$crate` in a macro definition.
|
||||
|
||||
### Why is this bad?
|
||||
`crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's
|
||||
crate. Rarely is the former intended. See:
|
||||
https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
|
||||
|
||||
### Example
|
||||
```
|
||||
#[macro_export]
|
||||
macro_rules! print_message {
|
||||
() => {
|
||||
println!("{}", crate::MESSAGE);
|
||||
};
|
||||
}
|
||||
pub const MESSAGE: &str = "Hello!";
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
#[macro_export]
|
||||
macro_rules! print_message {
|
||||
() => {
|
||||
println!("{}", $crate::MESSAGE);
|
||||
};
|
||||
}
|
||||
pub const MESSAGE: &str = "Hello!";
|
||||
```
|
||||
|
||||
Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the
|
||||
macro definition, e.g.:
|
||||
```
|
||||
#[allow(clippy::crate_in_macro_def)]
|
||||
macro_rules! ok { ... crate::foo ... }
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
|
||||
|
||||
### Why is this bad?
|
||||
Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
|
||||
|
||||
### Example
|
||||
```
|
||||
std::fs::create_dir("foo");
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
std::fs::create_dir_all("foo");
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
### What it does
|
||||
Checks for transmutes between a type `T` and `*T`.
|
||||
|
||||
### Why is this bad?
|
||||
It's easy to mistakenly transmute between a type and a
|
||||
pointer to that type.
|
||||
|
||||
### Example
|
||||
```
|
||||
core::intrinsics::transmute(t) // where the result type is the same as
|
||||
// `*t` or `&t`'s
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of dbg!() macro.
|
||||
|
||||
### Why is this bad?
|
||||
`dbg!` macro is intended as a debugging tool. It
|
||||
should not be in version control.
|
||||
|
||||
### Example
|
||||
```
|
||||
dbg!(true)
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
true
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
### What it does
|
||||
Checks for function/method calls with a mutable
|
||||
parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros.
|
||||
|
||||
### Why is this bad?
|
||||
In release builds `debug_assert!` macros are optimized out by the
|
||||
compiler.
|
||||
Therefore mutating something in a `debug_assert!` macro results in different behavior
|
||||
between a release and debug build.
|
||||
|
||||
### Example
|
||||
```
|
||||
debug_assert_eq!(vec![3].pop(), Some(3));
|
||||
|
||||
// or
|
||||
|
||||
debug_assert!(takes_a_mut_parameter(&mut x));
|
||||
```
|
@ -1,13 +0,0 @@
|
||||
### What it does
|
||||
Warns if there is a better representation for a numeric literal.
|
||||
|
||||
### Why is this bad?
|
||||
Especially for big powers of 2 a hexadecimal representation is more
|
||||
readable than a decimal representation.
|
||||
|
||||
### Example
|
||||
```
|
||||
`255` => `0xFF`
|
||||
`65_535` => `0xFFFF`
|
||||
`4_042_322_160` => `0xF0F0_F0F0`
|
||||
```
|
@ -1,46 +0,0 @@
|
||||
### What it does
|
||||
Checks for declaration of `const` items which is interior
|
||||
mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
|
||||
|
||||
### Why is this bad?
|
||||
Consts are copied everywhere they are referenced, i.e.,
|
||||
every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
these types in the first place.
|
||||
|
||||
The `const` should better be replaced by a `static` item if a global
|
||||
variable is wanted, or replaced by a `const fn` if a constructor is wanted.
|
||||
|
||||
### Known problems
|
||||
A "non-constant" const item is a legacy way to supply an
|
||||
initialized value to downstream `static` items (e.g., the
|
||||
`std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
|
||||
and this lint should be suppressed.
|
||||
|
||||
Even though the lint avoids triggering on a constant whose type has enums that have variants
|
||||
with interior mutability, and its value uses non interior mutable variants (see
|
||||
[#3962](https://github.com/rust-lang/rust-clippy/issues/3962) and
|
||||
[#3825](https://github.com/rust-lang/rust-clippy/issues/3825) for examples);
|
||||
it complains about associated constants without default values only based on its types;
|
||||
which might not be preferable.
|
||||
There're other enums plus associated constants cases that the lint cannot handle.
|
||||
|
||||
Types that have underlying or potential interior mutability trigger the lint whether
|
||||
the interior mutable field is used or not. See issues
|
||||
[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
|
||||
|
||||
### Example
|
||||
```
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
|
||||
const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
|
||||
STATIC_ATOM.store(9, SeqCst);
|
||||
assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
### What it does
|
||||
It checks for `std::iter::Empty::default()` and suggests replacing it with
|
||||
`std::iter::empty()`.
|
||||
### Why is this bad?
|
||||
`std::iter::empty()` is the more idiomatic way.
|
||||
### Example
|
||||
```
|
||||
let _ = std::iter::Empty::<usize>::default();
|
||||
let iter: std::iter::Empty<usize> = std::iter::Empty::default();
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let _ = std::iter::empty::<usize>();
|
||||
let iter: std::iter::Empty<usize> = std::iter::empty();
|
||||
```
|
@ -1,28 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
|
||||
inference.
|
||||
|
||||
Default numeric fallback means that if numeric types have not yet been bound to concrete
|
||||
types at the end of type inference, then integer type is bound to `i32`, and similarly
|
||||
floating type is bound to `f64`.
|
||||
|
||||
See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
|
||||
|
||||
### Why is this bad?
|
||||
For those who are very careful about types, default numeric fallback
|
||||
can be a pitfall that cause unexpected runtime behavior.
|
||||
|
||||
### Known problems
|
||||
This lint can only be allowed at the function level or above.
|
||||
|
||||
### Example
|
||||
```
|
||||
let i = 10;
|
||||
let f = 1.23;
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let i = 10i32;
|
||||
let f = 1.23f64;
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Checks for literal calls to `Default::default()`.
|
||||
|
||||
### Why is this bad?
|
||||
It's easier for the reader if the name of the type is used, rather than the
|
||||
generic `Default`.
|
||||
|
||||
### Example
|
||||
```
|
||||
let s: String = Default::default();
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let s = String::default();
|
||||
```
|
@ -1,36 +0,0 @@
|
||||
### What it does
|
||||
Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute).
|
||||
|
||||
### Why is this bad?
|
||||
Unions in Rust have unspecified layout by default, despite many people thinking that they
|
||||
lay out each field at the start of the union (like C does). That is, there are no guarantees
|
||||
about the offset of the fields for unions with multiple non-ZST fields without an explicitly
|
||||
specified layout. These cases may lead to undefined behavior in unsafe blocks.
|
||||
|
||||
### Example
|
||||
```
|
||||
union Foo {
|
||||
a: i32,
|
||||
b: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x: u32 = unsafe {
|
||||
Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding
|
||||
};
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
#[repr(C)]
|
||||
union Foo {
|
||||
a: i32,
|
||||
b: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x: u32 = unsafe {
|
||||
Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute
|
||||
};
|
||||
}
|
||||
```
|
@ -1,24 +0,0 @@
|
||||
### What it does
|
||||
Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
|
||||
with `#[rustfmt::skip]`.
|
||||
|
||||
### Why is this bad?
|
||||
Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
|
||||
are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
|
||||
|
||||
### Known problems
|
||||
This lint doesn't detect crate level inner attributes, because they get
|
||||
processed before the PreExpansionPass lints get executed. See
|
||||
[#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
||||
|
||||
### Example
|
||||
```
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn main() { }
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
#[rustfmt::skip]
|
||||
fn main() { }
|
||||
```
|
@ -1,13 +0,0 @@
|
||||
### What it does
|
||||
Checks for `#[deprecated]` annotations with a `since`
|
||||
field that is not a valid semantic version.
|
||||
|
||||
### Why is this bad?
|
||||
For checking the version of the deprecation, it must be
|
||||
a valid semver. Failing that, the contained information is useless.
|
||||
|
||||
### Example
|
||||
```
|
||||
#[deprecated(since = "forever")]
|
||||
fn something_else() { /* ... */ }
|
||||
```
|
@ -1,22 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of `*&` and `*&mut` in expressions.
|
||||
|
||||
### Why is this bad?
|
||||
Immediately dereferencing a reference is no-op and
|
||||
makes the code less clear.
|
||||
|
||||
### Known problems
|
||||
Multiple dereference/addrof pairs are not handled so
|
||||
the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
|
||||
|
||||
### Example
|
||||
```
|
||||
let a = f(*&mut b);
|
||||
let c = *&d;
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
let a = f(b);
|
||||
let c = d;
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
Checks for slicing expressions which are equivalent to dereferencing the
|
||||
value.
|
||||
|
||||
### Why is this bad?
|
||||
Some people may prefer to dereference rather than slice.
|
||||
|
||||
### Example
|
||||
```
|
||||
let vec = vec![1, 2, 3];
|
||||
let slice = &vec[..];
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
let vec = vec![1, 2, 3];
|
||||
let slice = &*vec;
|
||||
```
|
@ -1,35 +0,0 @@
|
||||
### What it does
|
||||
Detects manual `std::default::Default` implementations that are identical to a derived implementation.
|
||||
|
||||
### Why is this bad?
|
||||
It is less concise.
|
||||
|
||||
### Example
|
||||
```
|
||||
struct Foo {
|
||||
bar: bool
|
||||
}
|
||||
|
||||
impl Default for Foo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bar: false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
#[derive(Default)]
|
||||
struct Foo {
|
||||
bar: bool
|
||||
}
|
||||
```
|
||||
|
||||
### Known problems
|
||||
Derive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)
|
||||
in generic types and the user defined `impl` may be more generalized or
|
||||
specialized than what derive will produce. This lint can't detect the manual `impl`
|
||||
has exactly equal bounds, and therefore this lint is disabled for types with
|
||||
generic parameters.
|
@ -1,23 +0,0 @@
|
||||
### What it does
|
||||
Checks for deriving `Hash` but implementing `PartialEq`
|
||||
explicitly or vice versa.
|
||||
|
||||
### Why is this bad?
|
||||
The implementation of these traits must agree (for
|
||||
example for use with `HashMap`) so it’s probably a bad idea to use a
|
||||
default-generated `Hash` implementation with an explicitly defined
|
||||
`PartialEq`. In particular, the following must hold for any type:
|
||||
|
||||
```
|
||||
k1 == k2 ⇒ hash(k1) == hash(k2)
|
||||
```
|
||||
|
||||
### Example
|
||||
```
|
||||
#[derive(Hash)]
|
||||
struct Foo;
|
||||
|
||||
impl PartialEq for Foo {
|
||||
...
|
||||
}
|
||||
```
|
@ -1,44 +0,0 @@
|
||||
### What it does
|
||||
Checks for deriving `Ord` but implementing `PartialOrd`
|
||||
explicitly or vice versa.
|
||||
|
||||
### Why is this bad?
|
||||
The implementation of these traits must agree (for
|
||||
example for use with `sort`) so it’s probably a bad idea to use a
|
||||
default-generated `Ord` implementation with an explicitly defined
|
||||
`PartialOrd`. In particular, the following must hold for any type
|
||||
implementing `Ord`:
|
||||
|
||||
```
|
||||
k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
|
||||
```
|
||||
|
||||
### Example
|
||||
```
|
||||
#[derive(Ord, PartialEq, Eq)]
|
||||
struct Foo;
|
||||
|
||||
impl PartialOrd for Foo {
|
||||
...
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Foo;
|
||||
|
||||
impl PartialOrd for Foo {
|
||||
fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Foo {
|
||||
...
|
||||
}
|
||||
```
|
||||
or, if you don't need a custom ordering:
|
||||
```
|
||||
#[derive(Ord, PartialOrd, PartialEq, Eq)]
|
||||
struct Foo;
|
||||
```
|
@ -1,25 +0,0 @@
|
||||
### What it does
|
||||
Checks for types that derive `PartialEq` and could implement `Eq`.
|
||||
|
||||
### Why is this bad?
|
||||
If a type `T` derives `PartialEq` and all of its members implement `Eq`,
|
||||
then `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used
|
||||
in APIs that require `Eq` types. It also allows structs containing `T` to derive
|
||||
`Eq` themselves.
|
||||
|
||||
### Example
|
||||
```
|
||||
#[derive(PartialEq)]
|
||||
struct Foo {
|
||||
i_am_eq: i32,
|
||||
i_am_eq_too: Vec<String>,
|
||||
}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Foo {
|
||||
i_am_eq: i32,
|
||||
i_am_eq_too: Vec<String>,
|
||||
}
|
||||
```
|
@ -1,36 +0,0 @@
|
||||
### What it does
|
||||
Denies the configured macros in clippy.toml
|
||||
|
||||
Note: Even though this lint is warn-by-default, it will only trigger if
|
||||
macros are defined in the clippy.toml file.
|
||||
|
||||
### Why is this bad?
|
||||
Some macros are undesirable in certain contexts, and it's beneficial to
|
||||
lint for them as needed.
|
||||
|
||||
### Example
|
||||
An example clippy.toml configuration:
|
||||
```
|
||||
disallowed-macros = [
|
||||
# Can use a string as the path of the disallowed macro.
|
||||
"std::print",
|
||||
# Can also use an inline table with a `path` key.
|
||||
{ path = "std::println" },
|
||||
# When using an inline table, can add a `reason` for why the macro
|
||||
# is disallowed.
|
||||
{ path = "serde::Serialize", reason = "no serializing" },
|
||||
]
|
||||
```
|
||||
```
|
||||
use serde::Serialize;
|
||||
|
||||
// Example code where clippy issues a warning
|
||||
println!("warns");
|
||||
|
||||
// The diagnostic will contain the message "no serializing"
|
||||
#[derive(Serialize)]
|
||||
struct Data {
|
||||
name: String,
|
||||
value: usize,
|
||||
}
|
||||
```
|
@ -1,41 +0,0 @@
|
||||
### What it does
|
||||
Denies the configured methods and functions in clippy.toml
|
||||
|
||||
Note: Even though this lint is warn-by-default, it will only trigger if
|
||||
methods are defined in the clippy.toml file.
|
||||
|
||||
### Why is this bad?
|
||||
Some methods are undesirable in certain contexts, and it's beneficial to
|
||||
lint for them as needed.
|
||||
|
||||
### Example
|
||||
An example clippy.toml configuration:
|
||||
```
|
||||
disallowed-methods = [
|
||||
# Can use a string as the path of the disallowed method.
|
||||
"std::boxed::Box::new",
|
||||
# Can also use an inline table with a `path` key.
|
||||
{ path = "std::time::Instant::now" },
|
||||
# When using an inline table, can add a `reason` for why the method
|
||||
# is disallowed.
|
||||
{ path = "std::vec::Vec::leak", reason = "no leaking memory" },
|
||||
]
|
||||
```
|
||||
|
||||
```
|
||||
// Example code where clippy issues a warning
|
||||
let xs = vec![1, 2, 3, 4];
|
||||
xs.leak(); // Vec::leak is disallowed in the config.
|
||||
// The diagnostic contains the message "no leaking memory".
|
||||
|
||||
let _now = Instant::now(); // Instant::now is disallowed in the config.
|
||||
|
||||
let _box = Box::new(3); // Box::new is disallowed in the config.
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
// Example code which does not raise clippy warning
|
||||
let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
|
||||
xs.push(123); // Vec::push is _not_ disallowed in the config.
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of disallowed names for variables, such
|
||||
as `foo`.
|
||||
|
||||
### Why is this bad?
|
||||
These names are usually placeholder names and should be
|
||||
avoided.
|
||||
|
||||
### Example
|
||||
```
|
||||
let foo = 3.14;
|
||||
```
|
@ -1,32 +0,0 @@
|
||||
### What it does
|
||||
Checks for usage of unicode scripts other than those explicitly allowed
|
||||
by the lint config.
|
||||
|
||||
This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
|
||||
It also ignores the `Common` script type.
|
||||
While configuring, be sure to use official script name [aliases] from
|
||||
[the list of supported scripts][supported_scripts].
|
||||
|
||||
See also: [`non_ascii_idents`].
|
||||
|
||||
[aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
|
||||
[supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
|
||||
|
||||
### Why is this bad?
|
||||
It may be not desired to have many different scripts for
|
||||
identifiers in the codebase.
|
||||
|
||||
Note that if you only want to allow plain English, you might want to use
|
||||
built-in [`non_ascii_idents`] lint instead.
|
||||
|
||||
[`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
|
||||
|
||||
### Example
|
||||
```
|
||||
// Assuming that `clippy.toml` contains the following line:
|
||||
// allowed-locales = ["Latin", "Cyrillic"]
|
||||
let counter = 10; // OK, latin is allowed.
|
||||
let счётчик = 10; // OK, cyrillic is allowed.
|
||||
let zähler = 10; // OK, it's still latin.
|
||||
let カウンタ = 10; // Will spawn the lint.
|
||||
```
|
@ -1,33 +0,0 @@
|
||||
### What it does
|
||||
Denies the configured types in clippy.toml.
|
||||
|
||||
Note: Even though this lint is warn-by-default, it will only trigger if
|
||||
types are defined in the clippy.toml file.
|
||||
|
||||
### Why is this bad?
|
||||
Some types are undesirable in certain contexts.
|
||||
|
||||
### Example:
|
||||
An example clippy.toml configuration:
|
||||
```
|
||||
disallowed-types = [
|
||||
# Can use a string as the path of the disallowed type.
|
||||
"std::collections::BTreeMap",
|
||||
# Can also use an inline table with a `path` key.
|
||||
{ path = "std::net::TcpListener" },
|
||||
# When using an inline table, can add a `reason` for why the type
|
||||
# is disallowed.
|
||||
{ path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" },
|
||||
]
|
||||
```
|
||||
|
||||
```
|
||||
use std::collections::BTreeMap;
|
||||
// or its use
|
||||
let x = std::collections::BTreeMap::new();
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
// A similar type that is allowed by the config
|
||||
use std::collections::HashMap;
|
||||
```
|
@ -1,19 +0,0 @@
|
||||
### What it does
|
||||
Checks for diverging calls that are not match arms or
|
||||
statements.
|
||||
|
||||
### Why is this bad?
|
||||
It is often confusing to read. In addition, the
|
||||
sub-expression evaluation order for Rust is not well documented.
|
||||
|
||||
### Known problems
|
||||
Someone might want to use `some_bool || panic!()` as a
|
||||
shorthand.
|
||||
|
||||
### Example
|
||||
```
|
||||
let a = b() || panic!() || c();
|
||||
// `c()` is dead, `panic!()` is only called if `b()` returns `false`
|
||||
let x = (a, b, c, panic!());
|
||||
// can simply be replaced by `panic!()`
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
### What it does
|
||||
Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)
|
||||
outside of code blocks
|
||||
### Why is this bad?
|
||||
It is likely a typo when defining an intra-doc link
|
||||
|
||||
### Example
|
||||
```
|
||||
/// See also: ['foo']
|
||||
fn bar() {}
|
||||
```
|
||||
Use instead:
|
||||
```
|
||||
/// See also: [`foo`]
|
||||
fn bar() {}
|
||||
```
|
@ -1,35 +0,0 @@
|
||||
### What it does
|
||||
Checks for the presence of `_`, `::` or camel-case words
|
||||
outside ticks in documentation.
|
||||
|
||||
### Why is this bad?
|
||||
*Rustdoc* supports markdown formatting, `_`, `::` and
|
||||
camel-case probably indicates some code which should be included between
|
||||
ticks. `_` can also be used for emphasis in markdown, this lint tries to
|
||||
consider that.
|
||||
|
||||
### Known problems
|
||||
Lots of bad docs won’t be fixed, what the lint checks
|
||||
for is limited, and there are still false positives. HTML elements and their
|
||||
content are not linted.
|
||||
|
||||
In addition, when writing documentation comments, including `[]` brackets
|
||||
inside a link text would trip the parser. Therefore, documenting link with
|
||||
`[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
|
||||
would fail.
|
||||
|
||||
### Examples
|
||||
```
|
||||
/// Do something with the foo_bar parameter. See also
|
||||
/// that::other::module::foo.
|
||||
// ^ `foo_bar` and `that::other::module::foo` should be ticked.
|
||||
fn doit(foo_bar: usize) {}
|
||||
```
|
||||
|
||||
```
|
||||
// Link text with `[]` brackets should be written as following:
|
||||
/// Consume the array and return the inner
|
||||
/// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].
|
||||
/// [SmallVec]: SmallVec
|
||||
fn main() {}
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
Checks for double comparisons that could be simplified to a single expression.
|
||||
|
||||
|
||||
### Why is this bad?
|
||||
Readability.
|
||||
|
||||
### Example
|
||||
```
|
||||
if x == y || x < y {}
|
||||
```
|
||||
|
||||
Use instead:
|
||||
|
||||
```
|
||||
if x <= y {}
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
### What it does
|
||||
Checks for a `#[must_use]` attribute without
|
||||
further information on functions and methods that return a type already
|
||||
marked as `#[must_use]`.
|
||||
|
||||
### Why is this bad?
|
||||
The attribute isn't needed. Not using the result
|
||||
will already be reported. Alternatively, one can add some text to the
|
||||
attribute to improve the lint message.
|
||||
|
||||
### Examples
|
||||
```
|
||||
#[must_use]
|
||||
fn double_must_use() -> Result<(), ()> {
|
||||
unimplemented!();
|
||||
}
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
### What it does
|
||||
Detects expressions of the form `--x`.
|
||||
|
||||
### Why is this bad?
|
||||
It can mislead C/C++ programmers to think `x` was
|
||||
decremented.
|
||||
|
||||
### Example
|
||||
```
|
||||
let mut x = 3;
|
||||
--x;
|
||||
```
|
@ -1,24 +0,0 @@
|
||||
### What it does
|
||||
Checks for unnecessary double parentheses.
|
||||
|
||||
### Why is this bad?
|
||||
This makes code harder to read and might indicate a
|
||||
mistake.
|
||||
|
||||
### Example
|
||||
```
|
||||
fn simple_double_parens() -> i32 {
|
||||
((0))
|
||||
}
|
||||
|
||||
foo((0));
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```
|
||||
fn simple_no_parens() -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
foo(0);
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user