Merge remote-tracking branch 'upstream/master' into rustup
This commit is contained in:
commit
9f53fc32cf
298 changed files with 4937 additions and 5233 deletions
|
|
@ -1,95 +1,184 @@
|
|||
error: casting `bool` to `u8` is more cleanly stated with `u8::from(_)`
|
||||
error: casts from `bool` to `u8` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:8:13
|
||||
|
|
||||
LL | let _ = true as u8;
|
||||
| ^^^^^^^^^^ help: try: `u8::from(true)`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
= note: `-D clippy::cast-lossless` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
|
||||
help: use `u8::from` instead
|
||||
|
|
||||
LL | let _ = u8::from(true);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u16` is more cleanly stated with `u16::from(_)`
|
||||
error: casts from `bool` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:9:13
|
||||
|
|
||||
LL | let _ = true as u16;
|
||||
| ^^^^^^^^^^^ help: try: `u16::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u16::from` instead
|
||||
|
|
||||
LL | let _ = u16::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u32` is more cleanly stated with `u32::from(_)`
|
||||
error: casts from `bool` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:10:13
|
||||
|
|
||||
LL | let _ = true as u32;
|
||||
| ^^^^^^^^^^^ help: try: `u32::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u32::from` instead
|
||||
|
|
||||
LL | let _ = u32::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u64` is more cleanly stated with `u64::from(_)`
|
||||
error: casts from `bool` to `u64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:11:13
|
||||
|
|
||||
LL | let _ = true as u64;
|
||||
| ^^^^^^^^^^^ help: try: `u64::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u64::from` instead
|
||||
|
|
||||
LL | let _ = u64::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u128` is more cleanly stated with `u128::from(_)`
|
||||
error: casts from `bool` to `u128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:12:13
|
||||
|
|
||||
LL | let _ = true as u128;
|
||||
| ^^^^^^^^^^^^ help: try: `u128::from(true)`
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u128::from` instead
|
||||
|
|
||||
LL | let _ = u128::from(true);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `usize` is more cleanly stated with `usize::from(_)`
|
||||
error: casts from `bool` to `usize` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:13:13
|
||||
|
|
||||
LL | let _ = true as usize;
|
||||
| ^^^^^^^^^^^^^ help: try: `usize::from(true)`
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `usize::from` instead
|
||||
|
|
||||
LL | let _ = usize::from(true);
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `i8` is more cleanly stated with `i8::from(_)`
|
||||
error: casts from `bool` to `i8` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:15:13
|
||||
|
|
||||
LL | let _ = true as i8;
|
||||
| ^^^^^^^^^^ help: try: `i8::from(true)`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i8::from` instead
|
||||
|
|
||||
LL | let _ = i8::from(true);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `i16` is more cleanly stated with `i16::from(_)`
|
||||
error: casts from `bool` to `i16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:16:13
|
||||
|
|
||||
LL | let _ = true as i16;
|
||||
| ^^^^^^^^^^^ help: try: `i16::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i16::from` instead
|
||||
|
|
||||
LL | let _ = i16::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `i32` is more cleanly stated with `i32::from(_)`
|
||||
error: casts from `bool` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:17:13
|
||||
|
|
||||
LL | let _ = true as i32;
|
||||
| ^^^^^^^^^^^ help: try: `i32::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | let _ = i32::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `i64` is more cleanly stated with `i64::from(_)`
|
||||
error: casts from `bool` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:18:13
|
||||
|
|
||||
LL | let _ = true as i64;
|
||||
| ^^^^^^^^^^^ help: try: `i64::from(true)`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | let _ = i64::from(true);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `i128` is more cleanly stated with `i128::from(_)`
|
||||
error: casts from `bool` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:19:13
|
||||
|
|
||||
LL | let _ = true as i128;
|
||||
| ^^^^^^^^^^^^ help: try: `i128::from(true)`
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | let _ = i128::from(true);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `isize` is more cleanly stated with `isize::from(_)`
|
||||
error: casts from `bool` to `isize` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:20:13
|
||||
|
|
||||
LL | let _ = true as isize;
|
||||
| ^^^^^^^^^^^^^ help: try: `isize::from(true)`
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `isize::from` instead
|
||||
|
|
||||
LL | let _ = isize::from(true);
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u16` is more cleanly stated with `u16::from(_)`
|
||||
error: casts from `bool` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:23:13
|
||||
|
|
||||
LL | let _ = (true | false) as u16;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::from(true | false)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u16::from` instead
|
||||
|
|
||||
LL | let _ = u16::from(true | false);
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `U8` is more cleanly stated with `U8::from(_)`
|
||||
error: casts from `bool` to `u8` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:25:13
|
||||
|
|
||||
LL | let _ = true as U8;
|
||||
| ^^^^^^^^^^ help: try: `U8::from(true)`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `U8::from` instead
|
||||
|
|
||||
LL | let _ = U8::from(true);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `bool` to `u8` is more cleanly stated with `u8::from(_)`
|
||||
error: casts from `bool` to `u8` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_bool.rs:53:13
|
||||
|
|
||||
LL | let _ = true as u8;
|
||||
| ^^^^^^^^^^ help: try: `u8::from(true)`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u8::from` instead
|
||||
|
|
||||
LL | let _ = u8::from(true);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +1,160 @@
|
|||
error: casting `i8` to `f32` may become silently lossy if you later change the type
|
||||
error: casts from `i8` to `f32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:12:13
|
||||
|
|
||||
LL | let _ = x0 as f32;
|
||||
| ^^^^^^^^^ help: try: `f32::from(x0)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
= note: `-D clippy::cast-lossless` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
|
||||
help: use `f32::from` instead
|
||||
|
|
||||
LL | let _ = f32::from(x0);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `i8` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:13:13
|
||||
|
|
||||
LL | let _ = x0 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x0)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x0);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `F32` may become silently lossy if you later change the type
|
||||
error: casts from `i8` to `f32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:14:13
|
||||
|
|
||||
LL | let _ = x0 as F32;
|
||||
| ^^^^^^^^^ help: try: `F32::from(x0)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `F32::from` instead
|
||||
|
|
||||
LL | let _ = F32::from(x0);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `F64` may become silently lossy if you later change the type
|
||||
error: casts from `i8` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:15:13
|
||||
|
|
||||
LL | let _ = x0 as F64;
|
||||
| ^^^^^^^^^ help: try: `F64::from(x0)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `F64::from` instead
|
||||
|
|
||||
LL | let _ = F64::from(x0);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u8` to `f32` may become silently lossy if you later change the type
|
||||
error: casts from `u8` to `f32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:17:13
|
||||
|
|
||||
LL | let _ = x1 as f32;
|
||||
| ^^^^^^^^^ help: try: `f32::from(x1)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f32::from` instead
|
||||
|
|
||||
LL | let _ = f32::from(x1);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u8` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `u8` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:18:13
|
||||
|
|
||||
LL | let _ = x1 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x1)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x1);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i16` to `f32` may become silently lossy if you later change the type
|
||||
error: casts from `i16` to `f32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:20:13
|
||||
|
|
||||
LL | let _ = x2 as f32;
|
||||
| ^^^^^^^^^ help: try: `f32::from(x2)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f32::from` instead
|
||||
|
|
||||
LL | let _ = f32::from(x2);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i16` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `i16` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:21:13
|
||||
|
|
||||
LL | let _ = x2 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x2)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x2);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u16` to `f32` may become silently lossy if you later change the type
|
||||
error: casts from `u16` to `f32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:23:13
|
||||
|
|
||||
LL | let _ = x3 as f32;
|
||||
| ^^^^^^^^^ help: try: `f32::from(x3)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f32::from` instead
|
||||
|
|
||||
LL | let _ = f32::from(x3);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u16` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `u16` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:24:13
|
||||
|
|
||||
LL | let _ = x3 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x3)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x3);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i32` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `i32` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:26:13
|
||||
|
|
||||
LL | let _ = x4 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x4)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x4);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u32` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `u32` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:28:13
|
||||
|
|
||||
LL | let _ = x5 as f64;
|
||||
| ^^^^^^^^^ help: try: `f64::from(x5)`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(x5);
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting `f32` to `f64` may become silently lossy if you later change the type
|
||||
error: casts from `f32` to `f64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_float.rs:31:13
|
||||
|
|
||||
LL | let _ = 1.0f32 as f64;
|
||||
| ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `f64::from` instead
|
||||
|
|
||||
LL | let _ = f64::from(1.0f32);
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,39 +1,93 @@
|
|||
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
|
||||
#![warn(clippy::cast_lossless)]
|
||||
|
||||
type I64 = i64;
|
||||
type U128 = u128;
|
||||
type I64Alias = i64;
|
||||
|
||||
fn main() {
|
||||
// Test clippy::cast_lossless with casts to integer types
|
||||
let _ = i16::from(1i8);
|
||||
let _ = i32::from(1i8);
|
||||
let _ = i64::from(1i8);
|
||||
let _ = i16::from(1u8);
|
||||
let _ = i32::from(1u8);
|
||||
let _ = i64::from(1u8);
|
||||
let _ = u16::from(1u8);
|
||||
let _ = u32::from(1u8);
|
||||
let _ = u64::from(1u8);
|
||||
let _ = i32::from(1i16);
|
||||
let _ = i64::from(1i16);
|
||||
let _ = i32::from(1u16);
|
||||
let _ = i64::from(1u16);
|
||||
let _ = u32::from(1u16);
|
||||
let _ = u64::from(1u16);
|
||||
let _ = i64::from(1i32);
|
||||
let _ = i64::from(1u32);
|
||||
let _ = u64::from(1u32);
|
||||
u16::from(0u8);
|
||||
//~^ cast_lossless
|
||||
i16::from(0u8);
|
||||
//~^ cast_lossless
|
||||
u32::from(0u8);
|
||||
//~^ cast_lossless
|
||||
i32::from(0u8);
|
||||
//~^ cast_lossless
|
||||
u64::from(0u8);
|
||||
//~^ cast_lossless
|
||||
i64::from(0u8);
|
||||
//~^ cast_lossless
|
||||
u128::from(0u8);
|
||||
//~^ cast_lossless
|
||||
i128::from(0u8);
|
||||
//~^ cast_lossless
|
||||
|
||||
u32::from(0u16);
|
||||
//~^ cast_lossless
|
||||
i32::from(0u16);
|
||||
//~^ cast_lossless
|
||||
u64::from(0u16);
|
||||
//~^ cast_lossless
|
||||
i64::from(0u16);
|
||||
//~^ cast_lossless
|
||||
u128::from(0u16);
|
||||
//~^ cast_lossless
|
||||
i128::from(0u16);
|
||||
//~^ cast_lossless
|
||||
|
||||
u64::from(0u32);
|
||||
//~^ cast_lossless
|
||||
i64::from(0u32);
|
||||
//~^ cast_lossless
|
||||
u128::from(0u32);
|
||||
//~^ cast_lossless
|
||||
i128::from(0u32);
|
||||
//~^ cast_lossless
|
||||
|
||||
u128::from(0u64);
|
||||
//~^ cast_lossless
|
||||
i128::from(0u64);
|
||||
//~^ cast_lossless
|
||||
|
||||
i16::from(0i8);
|
||||
//~^ cast_lossless
|
||||
i32::from(0i8);
|
||||
//~^ cast_lossless
|
||||
i64::from(0i8);
|
||||
//~^ cast_lossless
|
||||
i128::from(0i8);
|
||||
//~^ cast_lossless
|
||||
|
||||
i32::from(0i16);
|
||||
//~^ cast_lossless
|
||||
i64::from(0i16);
|
||||
//~^ cast_lossless
|
||||
i128::from(0i16);
|
||||
//~^ cast_lossless
|
||||
|
||||
i64::from(0i32);
|
||||
//~^ cast_lossless
|
||||
i128::from(0i32);
|
||||
//~^ cast_lossless
|
||||
|
||||
i128::from(0i64);
|
||||
//~^ cast_lossless
|
||||
|
||||
// Test with an expression wrapped in parens
|
||||
let _ = u16::from(1u8 + 1u8);
|
||||
//~^ cast_lossless
|
||||
|
||||
let _ = I64::from(1i8);
|
||||
let _ = I64Alias::from(1i8);
|
||||
//~^ cast_lossless
|
||||
|
||||
// Do not lint if destination type is u128
|
||||
// see https://github.com/rust-lang/rust-clippy/issues/12492
|
||||
let _ = 1u8 as u128;
|
||||
let _ = 1u8 as U128;
|
||||
let _: u16 = 0u8.into();
|
||||
//~^ cast_lossless
|
||||
let _: i16 = (-1i8).into();
|
||||
//~^ cast_lossless
|
||||
let _: u16 = (1u8 + 2).into();
|
||||
//~^ cast_lossless
|
||||
let _: u32 = (1i8 as u16).into();
|
||||
//~^ cast_lossless
|
||||
}
|
||||
|
||||
// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
|
||||
|
|
@ -68,5 +122,30 @@ fn issue11458() {
|
|||
}
|
||||
let x = 10_u128;
|
||||
let _ = i32::from(sign_cast!(x, u8, i8));
|
||||
//~^ cast_lossless
|
||||
let _ = i32::from(sign_cast!(x, u8, i8) + 1);
|
||||
//~^ cast_lossless
|
||||
}
|
||||
|
||||
fn issue12695() {
|
||||
macro_rules! in_macro {
|
||||
() => {
|
||||
u32::from(1u8)
|
||||
//~^ cast_lossless
|
||||
};
|
||||
}
|
||||
|
||||
let _ = in_macro!();
|
||||
}
|
||||
|
||||
fn ty_from_macro() {
|
||||
macro_rules! ty {
|
||||
() => {
|
||||
u32
|
||||
};
|
||||
}
|
||||
|
||||
let _ = <ty!()>::from(0u8);
|
||||
}
|
||||
|
||||
const IN_CONST: u64 = 0u8 as u64;
|
||||
|
|
|
|||
|
|
@ -1,39 +1,93 @@
|
|||
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
|
||||
#![warn(clippy::cast_lossless)]
|
||||
|
||||
type I64 = i64;
|
||||
type U128 = u128;
|
||||
type I64Alias = i64;
|
||||
|
||||
fn main() {
|
||||
// Test clippy::cast_lossless with casts to integer types
|
||||
let _ = 1i8 as i16;
|
||||
let _ = 1i8 as i32;
|
||||
let _ = 1i8 as i64;
|
||||
let _ = 1u8 as i16;
|
||||
let _ = 1u8 as i32;
|
||||
let _ = 1u8 as i64;
|
||||
let _ = 1u8 as u16;
|
||||
let _ = 1u8 as u32;
|
||||
let _ = 1u8 as u64;
|
||||
let _ = 1i16 as i32;
|
||||
let _ = 1i16 as i64;
|
||||
let _ = 1u16 as i32;
|
||||
let _ = 1u16 as i64;
|
||||
let _ = 1u16 as u32;
|
||||
let _ = 1u16 as u64;
|
||||
let _ = 1i32 as i64;
|
||||
let _ = 1u32 as i64;
|
||||
let _ = 1u32 as u64;
|
||||
0u8 as u16;
|
||||
//~^ cast_lossless
|
||||
0u8 as i16;
|
||||
//~^ cast_lossless
|
||||
0u8 as u32;
|
||||
//~^ cast_lossless
|
||||
0u8 as i32;
|
||||
//~^ cast_lossless
|
||||
0u8 as u64;
|
||||
//~^ cast_lossless
|
||||
0u8 as i64;
|
||||
//~^ cast_lossless
|
||||
0u8 as u128;
|
||||
//~^ cast_lossless
|
||||
0u8 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0u16 as u32;
|
||||
//~^ cast_lossless
|
||||
0u16 as i32;
|
||||
//~^ cast_lossless
|
||||
0u16 as u64;
|
||||
//~^ cast_lossless
|
||||
0u16 as i64;
|
||||
//~^ cast_lossless
|
||||
0u16 as u128;
|
||||
//~^ cast_lossless
|
||||
0u16 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0u32 as u64;
|
||||
//~^ cast_lossless
|
||||
0u32 as i64;
|
||||
//~^ cast_lossless
|
||||
0u32 as u128;
|
||||
//~^ cast_lossless
|
||||
0u32 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0u64 as u128;
|
||||
//~^ cast_lossless
|
||||
0u64 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0i8 as i16;
|
||||
//~^ cast_lossless
|
||||
0i8 as i32;
|
||||
//~^ cast_lossless
|
||||
0i8 as i64;
|
||||
//~^ cast_lossless
|
||||
0i8 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0i16 as i32;
|
||||
//~^ cast_lossless
|
||||
0i16 as i64;
|
||||
//~^ cast_lossless
|
||||
0i16 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0i32 as i64;
|
||||
//~^ cast_lossless
|
||||
0i32 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
0i64 as i128;
|
||||
//~^ cast_lossless
|
||||
|
||||
// Test with an expression wrapped in parens
|
||||
let _ = (1u8 + 1u8) as u16;
|
||||
//~^ cast_lossless
|
||||
|
||||
let _ = 1i8 as I64;
|
||||
let _ = 1i8 as I64Alias;
|
||||
//~^ cast_lossless
|
||||
|
||||
// Do not lint if destination type is u128
|
||||
// see https://github.com/rust-lang/rust-clippy/issues/12492
|
||||
let _ = 1u8 as u128;
|
||||
let _ = 1u8 as U128;
|
||||
let _: u16 = 0u8 as _;
|
||||
//~^ cast_lossless
|
||||
let _: i16 = -1i8 as _;
|
||||
//~^ cast_lossless
|
||||
let _: u16 = (1u8 + 2) as _;
|
||||
//~^ cast_lossless
|
||||
let _: u32 = 1i8 as u16 as _;
|
||||
//~^ cast_lossless
|
||||
}
|
||||
|
||||
// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
|
||||
|
|
@ -68,5 +122,30 @@ fn issue11458() {
|
|||
}
|
||||
let x = 10_u128;
|
||||
let _ = sign_cast!(x, u8, i8) as i32;
|
||||
//~^ cast_lossless
|
||||
let _ = (sign_cast!(x, u8, i8) + 1) as i32;
|
||||
//~^ cast_lossless
|
||||
}
|
||||
|
||||
fn issue12695() {
|
||||
macro_rules! in_macro {
|
||||
() => {
|
||||
1u8 as u32
|
||||
//~^ cast_lossless
|
||||
};
|
||||
}
|
||||
|
||||
let _ = in_macro!();
|
||||
}
|
||||
|
||||
fn ty_from_macro() {
|
||||
macro_rules! ty {
|
||||
() => {
|
||||
u32
|
||||
};
|
||||
}
|
||||
|
||||
let _ = 0u8 as ty!();
|
||||
}
|
||||
|
||||
const IN_CONST: u64 = 0u8 as u64;
|
||||
|
|
|
|||
|
|
@ -1,137 +1,488 @@
|
|||
error: casting `i8` to `i16` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:9:13
|
||||
error: casts from `u8` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:8:5
|
||||
|
|
||||
LL | let _ = 1i8 as i16;
|
||||
| ^^^^^^^^^^ help: try: `i16::from(1i8)`
|
||||
LL | 0u8 as u16;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
= note: `-D clippy::cast-lossless` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
|
||||
|
||||
error: casting `i8` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:10:13
|
||||
help: use `u16::from` instead
|
||||
|
|
||||
LL | let _ = 1i8 as i32;
|
||||
| ^^^^^^^^^^ help: try: `i32::from(1i8)`
|
||||
LL | u16::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:11:13
|
||||
error: casts from `u8` to `i16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:10:5
|
||||
|
|
||||
LL | let _ = 1i8 as i64;
|
||||
| ^^^^^^^^^^ help: try: `i64::from(1i8)`
|
||||
|
||||
error: casting `u8` to `i16` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:12:13
|
||||
LL | 0u8 as i16;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1u8 as i16;
|
||||
| ^^^^^^^^^^ help: try: `i16::from(1u8)`
|
||||
|
||||
error: casting `u8` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:13:13
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i16::from` instead
|
||||
|
|
||||
LL | let _ = 1u8 as i32;
|
||||
| ^^^^^^^^^^ help: try: `i32::from(1u8)`
|
||||
LL | i16::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u8` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:14:13
|
||||
error: casts from `u8` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:12:5
|
||||
|
|
||||
LL | let _ = 1u8 as i64;
|
||||
| ^^^^^^^^^^ help: try: `i64::from(1u8)`
|
||||
|
||||
error: casting `u8` to `u16` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:15:13
|
||||
LL | 0u8 as u32;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1u8 as u16;
|
||||
| ^^^^^^^^^^ help: try: `u16::from(1u8)`
|
||||
|
||||
error: casting `u8` to `u32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:16:13
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u32::from` instead
|
||||
|
|
||||
LL | let _ = 1u8 as u32;
|
||||
| ^^^^^^^^^^ help: try: `u32::from(1u8)`
|
||||
LL | u32::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u8` to `u64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:17:13
|
||||
error: casts from `u8` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:14:5
|
||||
|
|
||||
LL | let _ = 1u8 as u64;
|
||||
| ^^^^^^^^^^ help: try: `u64::from(1u8)`
|
||||
|
||||
error: casting `i16` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:18:13
|
||||
LL | 0u8 as i32;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1i16 as i32;
|
||||
| ^^^^^^^^^^^ help: try: `i32::from(1i16)`
|
||||
|
||||
error: casting `i16` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:19:13
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | let _ = 1i16 as i64;
|
||||
| ^^^^^^^^^^^ help: try: `i64::from(1i16)`
|
||||
LL | i32::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u16` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:20:13
|
||||
error: casts from `u8` to `u64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:16:5
|
||||
|
|
||||
LL | let _ = 1u16 as i32;
|
||||
| ^^^^^^^^^^^ help: try: `i32::from(1u16)`
|
||||
|
||||
error: casting `u16` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:21:13
|
||||
LL | 0u8 as u64;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1u16 as i64;
|
||||
| ^^^^^^^^^^^ help: try: `i64::from(1u16)`
|
||||
|
||||
error: casting `u16` to `u32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:22:13
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u64::from` instead
|
||||
|
|
||||
LL | let _ = 1u16 as u32;
|
||||
| ^^^^^^^^^^^ help: try: `u32::from(1u16)`
|
||||
LL | u64::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u16` to `u64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:23:13
|
||||
error: casts from `u8` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:18:5
|
||||
|
|
||||
LL | let _ = 1u16 as u64;
|
||||
| ^^^^^^^^^^^ help: try: `u64::from(1u16)`
|
||||
|
||||
error: casting `i32` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:24:13
|
||||
LL | 0u8 as i64;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1i32 as i64;
|
||||
| ^^^^^^^^^^^ help: try: `i64::from(1i32)`
|
||||
|
||||
error: casting `u32` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:25:13
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | let _ = 1u32 as i64;
|
||||
| ^^^^^^^^^^^ help: try: `i64::from(1u32)`
|
||||
LL | i64::from(0u8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u32` to `u64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:26:13
|
||||
error: casts from `u8` to `u128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:20:5
|
||||
|
|
||||
LL | let _ = 1u32 as u64;
|
||||
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`
|
||||
LL | 0u8 as u128;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u128::from` instead
|
||||
|
|
||||
LL | u128::from(0u8);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `u8` to `u16` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:29:13
|
||||
error: casts from `u8` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:22:5
|
||||
|
|
||||
LL | 0u8 as i128;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0u8);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:25:5
|
||||
|
|
||||
LL | 0u16 as u32;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u32::from` instead
|
||||
|
|
||||
LL | u32::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:27:5
|
||||
|
|
||||
LL | 0u16 as i32;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | i32::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `u64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:29:5
|
||||
|
|
||||
LL | 0u16 as u64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u64::from` instead
|
||||
|
|
||||
LL | u64::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:31:5
|
||||
|
|
||||
LL | 0u16 as i64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | i64::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `u128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:33:5
|
||||
|
|
||||
LL | 0u16 as u128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u128::from` instead
|
||||
|
|
||||
LL | u128::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:35:5
|
||||
|
|
||||
LL | 0u16 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0u16);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u32` to `u64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:38:5
|
||||
|
|
||||
LL | 0u32 as u64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u64::from` instead
|
||||
|
|
||||
LL | u64::from(0u32);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u32` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:40:5
|
||||
|
|
||||
LL | 0u32 as i64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | i64::from(0u32);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u32` to `u128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:42:5
|
||||
|
|
||||
LL | 0u32 as u128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u128::from` instead
|
||||
|
|
||||
LL | u128::from(0u32);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u32` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:44:5
|
||||
|
|
||||
LL | 0u32 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0u32);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u64` to `u128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:47:5
|
||||
|
|
||||
LL | 0u64 as u128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u128::from` instead
|
||||
|
|
||||
LL | u128::from(0u64);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u64` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:49:5
|
||||
|
|
||||
LL | 0u64 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0u64);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:52:5
|
||||
|
|
||||
LL | 0i8 as i16;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i16::from` instead
|
||||
|
|
||||
LL | i16::from(0i8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:54:5
|
||||
|
|
||||
LL | 0i8 as i32;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | i32::from(0i8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:56:5
|
||||
|
|
||||
LL | 0i8 as i64;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | i64::from(0i8);
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:58:5
|
||||
|
|
||||
LL | 0i8 as i128;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0i8);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i16` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:61:5
|
||||
|
|
||||
LL | 0i16 as i32;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | i32::from(0i16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i16` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:63:5
|
||||
|
|
||||
LL | 0i16 as i64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | i64::from(0i16);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i16` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:65:5
|
||||
|
|
||||
LL | 0i16 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0i16);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i32` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:68:5
|
||||
|
|
||||
LL | 0i32 as i64;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i64::from` instead
|
||||
|
|
||||
LL | i64::from(0i32);
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i32` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:70:5
|
||||
|
|
||||
LL | 0i32 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0i32);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i64` to `i128` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:73:5
|
||||
|
|
||||
LL | 0i64 as i128;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i128::from` instead
|
||||
|
|
||||
LL | i128::from(0i64);
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u8` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:77:13
|
||||
|
|
||||
LL | let _ = (1u8 + 1u8) as u16;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
|
||||
|
||||
error: casting `i8` to `I64` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:31:13
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
LL | let _ = 1i8 as I64;
|
||||
| ^^^^^^^^^^ help: try: `I64::from(1i8)`
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `u16::from` instead
|
||||
|
|
||||
LL | let _ = u16::from(1u8 + 1u8);
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:70:13
|
||||
error: casts from `i8` to `i64` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:80:13
|
||||
|
|
||||
LL | let _ = 1i8 as I64Alias;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `I64Alias::from` instead
|
||||
|
|
||||
LL | let _ = I64Alias::from(1i8);
|
||||
| ~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u8` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:83:18
|
||||
|
|
||||
LL | let _: u16 = 0u8 as _;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `Into::into` instead
|
||||
|
|
||||
LL | let _: u16 = 0u8.into();
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:85:18
|
||||
|
|
||||
LL | let _: i16 = -1i8 as _;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `Into::into` instead
|
||||
|
|
||||
LL | let _: i16 = (-1i8).into();
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u8` to `u16` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:87:18
|
||||
|
|
||||
LL | let _: u16 = (1u8 + 2) as _;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `Into::into` instead
|
||||
|
|
||||
LL | let _: u16 = (1u8 + 2).into();
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `u16` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:89:18
|
||||
|
|
||||
LL | let _: u32 = 1i8 as u16 as _;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `Into::into` instead
|
||||
|
|
||||
LL | let _: u32 = (1i8 as u16).into();
|
||||
| ~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casts from `i8` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:124:13
|
||||
|
|
||||
LL | let _ = sign_cast!(x, u8, i8) as i32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8))`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | let _ = i32::from(sign_cast!(x, u8, i8));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting `i8` to `i32` may become silently lossy if you later change the type
|
||||
--> tests/ui/cast_lossless_integer.rs:71:13
|
||||
error: casts from `i8` to `i32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:126:13
|
||||
|
|
||||
LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8) + 1)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `i32::from` instead
|
||||
|
|
||||
LL | let _ = i32::from(sign_cast!(x, u8, i8) + 1);
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
error: casts from `u8` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:133:13
|
||||
|
|
||||
LL | 1u8 as u32
|
||||
| ^^^^^^^^^^
|
||||
...
|
||||
LL | let _ = in_macro!();
|
||||
| ----------- in this macro invocation
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
= note: this error originates in the macro `in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: use `u32::from` instead
|
||||
|
|
||||
LL | u32::from(1u8)
|
||||
|
|
||||
|
||||
error: casts from `u8` to `u32` can be expressed infallibly using `From`
|
||||
--> tests/ui/cast_lossless_integer.rs:148:13
|
||||
|
|
||||
LL | let _ = 0u8 as ty!();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: an `as` cast can become silently lossy if the types change in the future
|
||||
help: use `<ty!()>::from` instead
|
||||
|
|
||||
LL | let _ = <ty!()>::from(0u8);
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 40 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
#![deny(clippy::implicit_hasher)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn main() {}
|
||||
|
||||
pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
|
||||
//~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
|
||||
let _ = [0u8; 0];
|
||||
let _: HashSet<usize> = HashSet::default();
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#![deny(clippy::implicit_hasher)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: parameter of type `HashSet` should be generalized over different hashers
|
||||
--> tests/ui/crashes/ice-3717.rs:7:21
|
||||
--> tests/ui/crashes/ice-3717.rs:9:21
|
||||
|
|
||||
LL | pub fn ice_3717(_: &HashSet<usize>) {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ fn main() {
|
|||
let _ = unsafe { *core::ptr::addr_of!(a) };
|
||||
|
||||
let _repeat = [0; 64];
|
||||
// do NOT lint for array as sematic differences with/out `*&`.
|
||||
// do NOT lint for array as semantic differences with/out `*&`.
|
||||
let _arr = *&[0, 1, 2, 3, 4];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ fn main() {
|
|||
let _ = unsafe { *core::ptr::addr_of!(a) };
|
||||
|
||||
let _repeat = *&[0; 64];
|
||||
// do NOT lint for array as sematic differences with/out `*&`.
|
||||
// do NOT lint for array as semantic differences with/out `*&`.
|
||||
let _arr = *&[0, 1, 2, 3, 4];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,295 +0,0 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Default)]
|
||||
struct FooDefault<'a> {
|
||||
a: bool,
|
||||
b: i32,
|
||||
c: u64,
|
||||
d: Vec<i32>,
|
||||
e: FooND1,
|
||||
f: FooND2,
|
||||
g: HashMap<i32, i32>,
|
||||
h: (i32, Vec<i32>),
|
||||
i: [Vec<i32>; 3],
|
||||
j: [i32; 5],
|
||||
k: Option<i32>,
|
||||
l: &'a [i32],
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
struct TupleDefault(bool, i32, u64);
|
||||
|
||||
|
||||
struct FooND1 {
|
||||
a: bool,
|
||||
}
|
||||
|
||||
impl std::default::Default for FooND1 {
|
||||
fn default() -> Self {
|
||||
Self { a: true }
|
||||
}
|
||||
}
|
||||
|
||||
struct FooND2 {
|
||||
a: i32,
|
||||
}
|
||||
|
||||
impl std::default::Default for FooND2 {
|
||||
fn default() -> Self {
|
||||
Self { a: 5 }
|
||||
}
|
||||
}
|
||||
|
||||
struct FooNDNew {
|
||||
a: bool,
|
||||
}
|
||||
|
||||
impl FooNDNew {
|
||||
fn new() -> Self {
|
||||
Self { a: true }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FooNDNew {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
struct FooNDVec(Vec<i32>);
|
||||
|
||||
impl Default for FooNDVec {
|
||||
fn default() -> Self {
|
||||
Self(vec![5, 12])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct StrDefault<'a>(&'a str);
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
struct AlreadyDerived(i32, bool);
|
||||
|
||||
macro_rules! mac {
|
||||
() => {
|
||||
0
|
||||
};
|
||||
($e:expr) => {
|
||||
struct X(u32);
|
||||
impl Default for X {
|
||||
fn default() -> Self {
|
||||
Self($e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mac!(0);
|
||||
|
||||
#[derive(Default)]
|
||||
struct Y(u32);
|
||||
|
||||
struct RustIssue26925<T> {
|
||||
a: Option<T>,
|
||||
}
|
||||
|
||||
// We should watch out for cases where a manual impl is needed because a
|
||||
// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925).
|
||||
// For example, a struct with Option<T> does not require T: Default, but a derive adds
|
||||
// that type bound anyways. So until #26925 get fixed we should disable lint
|
||||
// for the following case
|
||||
impl<T> Default for RustIssue26925<T> {
|
||||
fn default() -> Self {
|
||||
Self { a: None }
|
||||
}
|
||||
}
|
||||
|
||||
struct SpecializedImpl<A, B> {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
||||
impl<T: Default> Default for SpecializedImpl<T, T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: T::default(),
|
||||
b: T::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct WithoutSelfCurly {
|
||||
a: bool,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
struct WithoutSelfParan(bool);
|
||||
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/7655
|
||||
|
||||
pub struct SpecializedImpl2<T> {
|
||||
v: Vec<T>,
|
||||
}
|
||||
|
||||
impl Default for SpecializedImpl2<String> {
|
||||
fn default() -> Self {
|
||||
Self { v: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/7654
|
||||
|
||||
pub struct Color {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
pub b: u8,
|
||||
}
|
||||
|
||||
/// `#000000`
|
||||
impl Default for Color {
|
||||
fn default() -> Self {
|
||||
Color { r: 0, g: 0, b: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Color2 {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
pub b: u8,
|
||||
}
|
||||
|
||||
impl Default for Color2 {
|
||||
/// `#000000`
|
||||
fn default() -> Self {
|
||||
Self { r: 0, g: 0, b: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RepeatDefault1 {
|
||||
a: [i8; 32],
|
||||
}
|
||||
|
||||
|
||||
pub struct RepeatDefault2 {
|
||||
a: [i8; 33],
|
||||
}
|
||||
|
||||
impl Default for RepeatDefault2 {
|
||||
fn default() -> Self {
|
||||
RepeatDefault2 { a: [0; 33] }
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/7753
|
||||
|
||||
pub enum IntOrString {
|
||||
Int(i32),
|
||||
String(String),
|
||||
}
|
||||
|
||||
impl Default for IntOrString {
|
||||
fn default() -> Self {
|
||||
IntOrString::Int(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum SimpleEnum {
|
||||
Foo,
|
||||
#[default]
|
||||
Bar,
|
||||
}
|
||||
|
||||
|
||||
pub enum NonExhaustiveEnum {
|
||||
Foo,
|
||||
#[non_exhaustive]
|
||||
Bar,
|
||||
}
|
||||
|
||||
impl Default for NonExhaustiveEnum {
|
||||
fn default() -> Self {
|
||||
NonExhaustiveEnum::Bar
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/10396
|
||||
|
||||
#[derive(Default)]
|
||||
struct DefaultType;
|
||||
|
||||
struct GenericType<T = DefaultType> {
|
||||
t: T,
|
||||
}
|
||||
|
||||
impl Default for GenericType {
|
||||
fn default() -> Self {
|
||||
Self { t: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
struct InnerGenericType<T> {
|
||||
t: T,
|
||||
}
|
||||
|
||||
impl Default for InnerGenericType<DefaultType> {
|
||||
fn default() -> Self {
|
||||
Self { t: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
struct OtherGenericType<T = DefaultType> {
|
||||
inner: InnerGenericType<T>,
|
||||
}
|
||||
|
||||
impl Default for OtherGenericType {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inner: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue10158 {
|
||||
pub trait T {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct S {}
|
||||
impl T for S {}
|
||||
|
||||
pub struct Outer {
|
||||
pub inner: Box<dyn T>,
|
||||
}
|
||||
|
||||
impl Default for Outer {
|
||||
fn default() -> Self {
|
||||
Outer {
|
||||
// Box::<S>::default() adjusts to Box<dyn T>
|
||||
inner: Box::<S>::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue11368 {
|
||||
pub struct A {
|
||||
a: u32,
|
||||
}
|
||||
|
||||
impl Default for A {
|
||||
#[track_caller]
|
||||
fn default() -> Self {
|
||||
Self { a: 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct FooDefault<'a> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:20:1
|
||||
--> tests/ui/derivable_impls.rs:22:1
|
||||
|
|
||||
LL | / impl std::default::Default for FooDefault<'_> {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -20,7 +20,7 @@ LL | struct FooDefault<'a> {
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:41:1
|
||||
--> tests/ui/derivable_impls.rs:43:1
|
||||
|
|
||||
LL | / impl std::default::Default for TupleDefault {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -37,7 +37,7 @@ LL | struct TupleDefault(bool, i32, u64);
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:93:1
|
||||
--> tests/ui/derivable_impls.rs:95:1
|
||||
|
|
||||
LL | / impl Default for StrDefault<'_> {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -54,7 +54,7 @@ LL | struct StrDefault<'a>(&'a str);
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:119:1
|
||||
--> tests/ui/derivable_impls.rs:121:1
|
||||
|
|
||||
LL | / impl Default for Y {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -71,7 +71,7 @@ LL | struct Y(u32);
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:158:1
|
||||
--> tests/ui/derivable_impls.rs:160:1
|
||||
|
|
||||
LL | / impl Default for WithoutSelfCurly {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -88,7 +88,7 @@ LL | struct WithoutSelfCurly {
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:166:1
|
||||
--> tests/ui/derivable_impls.rs:168:1
|
||||
|
|
||||
LL | / impl Default for WithoutSelfParan {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -105,7 +105,7 @@ LL | struct WithoutSelfParan(bool);
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:216:1
|
||||
--> tests/ui/derivable_impls.rs:218:1
|
||||
|
|
||||
LL | / impl Default for RepeatDefault1 {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
@ -122,7 +122,7 @@ LL | pub struct RepeatDefault1 {
|
|||
|
|
||||
|
||||
error: this `impl` can be derived
|
||||
--> tests/ui/derivable_impls.rs:250:1
|
||||
--> tests/ui/derivable_impls.rs:252:1
|
||||
|
|
||||
LL | / impl Default for SimpleEnum {
|
||||
LL | | fn default() -> Self {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
|
||||
#![warn(clippy::expl_impl_clone_on_copy)]
|
||||
|
||||
|
||||
#[derive(Copy)]
|
||||
struct Qux;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> tests/ui/derive.rs:8:1
|
||||
--> tests/ui/derive.rs:7:1
|
||||
|
|
||||
LL | / impl Clone for Qux {
|
||||
LL | |
|
||||
|
|
@ -10,7 +10,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> tests/ui/derive.rs:8:1
|
||||
--> tests/ui/derive.rs:7:1
|
||||
|
|
||||
LL | / impl Clone for Qux {
|
||||
LL | |
|
||||
|
|
@ -23,7 +23,7 @@ LL | | }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> tests/ui/derive.rs:33:1
|
||||
--> tests/ui/derive.rs:32:1
|
||||
|
|
||||
LL | / impl<'a> Clone for Lt<'a> {
|
||||
LL | |
|
||||
|
|
@ -34,7 +34,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> tests/ui/derive.rs:33:1
|
||||
--> tests/ui/derive.rs:32:1
|
||||
|
|
||||
LL | / impl<'a> Clone for Lt<'a> {
|
||||
LL | |
|
||||
|
|
@ -45,7 +45,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> tests/ui/derive.rs:45:1
|
||||
--> tests/ui/derive.rs:44:1
|
||||
|
|
||||
LL | / impl Clone for BigArray {
|
||||
LL | |
|
||||
|
|
@ -56,7 +56,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> tests/ui/derive.rs:45:1
|
||||
--> tests/ui/derive.rs:44:1
|
||||
|
|
||||
LL | / impl Clone for BigArray {
|
||||
LL | |
|
||||
|
|
@ -67,7 +67,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> tests/ui/derive.rs:57:1
|
||||
--> tests/ui/derive.rs:56:1
|
||||
|
|
||||
LL | / impl Clone for FnPtr {
|
||||
LL | |
|
||||
|
|
@ -78,7 +78,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> tests/ui/derive.rs:57:1
|
||||
--> tests/ui/derive.rs:56:1
|
||||
|
|
||||
LL | / impl Clone for FnPtr {
|
||||
LL | |
|
||||
|
|
@ -89,7 +89,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> tests/ui/derive.rs:78:1
|
||||
--> tests/ui/derive.rs:77:1
|
||||
|
|
||||
LL | / impl<T: Clone> Clone for Generic2<T> {
|
||||
LL | |
|
||||
|
|
@ -100,7 +100,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> tests/ui/derive.rs:78:1
|
||||
--> tests/ui/derive.rs:77:1
|
||||
|
|
||||
LL | / impl<T: Clone> Clone for Generic2<T> {
|
||||
LL | |
|
||||
|
|
|
|||
|
|
@ -54,21 +54,24 @@ fn test_units() {
|
|||
|
||||
/// This tests allowed identifiers.
|
||||
/// KiB MiB GiB TiB PiB EiB
|
||||
/// DirectX
|
||||
/// AccessKit
|
||||
/// CoreFoundation CoreGraphics CoreText
|
||||
/// Direct2D Direct3D DirectWrite DirectX
|
||||
/// ECMAScript
|
||||
/// GPLv2 GPLv3
|
||||
/// GitHub GitLab
|
||||
/// IPv4 IPv6
|
||||
/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
|
||||
/// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript
|
||||
/// WebAssembly
|
||||
/// NaN NaNs
|
||||
/// OAuth GraphQL
|
||||
/// OCaml
|
||||
/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
|
||||
/// WebGL WebGL2 WebGPU
|
||||
/// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
|
||||
/// OpenType
|
||||
/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport
|
||||
/// TensorFlow
|
||||
/// TrueType
|
||||
/// iOS macOS FreeBSD
|
||||
/// iOS macOS FreeBSD NetBSD OpenBSD
|
||||
/// TeX LaTeX BibTeX BibLaTeX
|
||||
/// MinGW
|
||||
/// CamelCase (see also #2395)
|
||||
|
|
|
|||
|
|
@ -54,21 +54,24 @@ fn test_units() {
|
|||
|
||||
/// This tests allowed identifiers.
|
||||
/// KiB MiB GiB TiB PiB EiB
|
||||
/// DirectX
|
||||
/// AccessKit
|
||||
/// CoreFoundation CoreGraphics CoreText
|
||||
/// Direct2D Direct3D DirectWrite DirectX
|
||||
/// ECMAScript
|
||||
/// GPLv2 GPLv3
|
||||
/// GitHub GitLab
|
||||
/// IPv4 IPv6
|
||||
/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
|
||||
/// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript
|
||||
/// WebAssembly
|
||||
/// NaN NaNs
|
||||
/// OAuth GraphQL
|
||||
/// OCaml
|
||||
/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
|
||||
/// WebGL WebGL2 WebGPU
|
||||
/// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
|
||||
/// OpenType
|
||||
/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport
|
||||
/// TensorFlow
|
||||
/// TrueType
|
||||
/// iOS macOS FreeBSD
|
||||
/// iOS macOS FreeBSD NetBSD OpenBSD
|
||||
/// TeX LaTeX BibTeX BibLaTeX
|
||||
/// MinGW
|
||||
/// CamelCase (see also #2395)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:75:5
|
||||
--> tests/ui/doc/doc-fixable.rs:78:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -144,7 +144,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:92:5
|
||||
--> tests/ui/doc/doc-fixable.rs:95:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -155,7 +155,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:100:8
|
||||
--> tests/ui/doc/doc-fixable.rs:103:8
|
||||
|
|
||||
LL | /// ## CamelCaseThing
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -166,7 +166,7 @@ LL | /// ## `CamelCaseThing`
|
|||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:103:7
|
||||
--> tests/ui/doc/doc-fixable.rs:106:7
|
||||
|
|
||||
LL | /// # CamelCaseThing
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -177,7 +177,7 @@ LL | /// # `CamelCaseThing`
|
|||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:105:22
|
||||
--> tests/ui/doc/doc-fixable.rs:108:22
|
||||
|
|
||||
LL | /// Not a title #897 CamelCaseThing
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -188,7 +188,7 @@ LL | /// Not a title #897 `CamelCaseThing`
|
|||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:106:5
|
||||
--> tests/ui/doc/doc-fixable.rs:109:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -199,7 +199,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:113:5
|
||||
--> tests/ui/doc/doc-fixable.rs:116:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -210,7 +210,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:126:5
|
||||
--> tests/ui/doc/doc-fixable.rs:129:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -221,7 +221,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:137:43
|
||||
--> tests/ui/doc/doc-fixable.rs:140:43
|
||||
|
|
||||
LL | /** E.g., serialization of an empty list: FooBar
|
||||
| ^^^^^^
|
||||
|
|
@ -232,7 +232,7 @@ LL | /** E.g., serialization of an empty list: `FooBar`
|
|||
| ~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:142:5
|
||||
--> tests/ui/doc/doc-fixable.rs:145:5
|
||||
|
|
||||
LL | And BarQuz too.
|
||||
| ^^^^^^
|
||||
|
|
@ -243,7 +243,7 @@ LL | And `BarQuz` too.
|
|||
| ~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:143:1
|
||||
--> tests/ui/doc/doc-fixable.rs:146:1
|
||||
|
|
||||
LL | be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -254,7 +254,7 @@ LL | `be_sure_we_got_to_the_end_of_it`
|
|||
|
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:148:43
|
||||
--> tests/ui/doc/doc-fixable.rs:151:43
|
||||
|
|
||||
LL | /** E.g., serialization of an empty list: FooBar
|
||||
| ^^^^^^
|
||||
|
|
@ -265,7 +265,7 @@ LL | /** E.g., serialization of an empty list: `FooBar`
|
|||
| ~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:153:5
|
||||
--> tests/ui/doc/doc-fixable.rs:156:5
|
||||
|
|
||||
LL | And BarQuz too.
|
||||
| ^^^^^^
|
||||
|
|
@ -276,7 +276,7 @@ LL | And `BarQuz` too.
|
|||
| ~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:154:1
|
||||
--> tests/ui/doc/doc-fixable.rs:157:1
|
||||
|
|
||||
LL | be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -287,7 +287,7 @@ LL | `be_sure_we_got_to_the_end_of_it`
|
|||
|
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:165:5
|
||||
--> tests/ui/doc/doc-fixable.rs:168:5
|
||||
|
|
||||
LL | /// be_sure_we_got_to_the_end_of_it
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -298,7 +298,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
|
|||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:184:22
|
||||
--> tests/ui/doc/doc-fixable.rs:187:22
|
||||
|
|
||||
LL | /// An iterator over mycrate::Collection's values.
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -309,7 +309,7 @@ LL | /// An iterator over `mycrate::Collection`'s values.
|
|||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:208:34
|
||||
--> tests/ui/doc/doc-fixable.rs:211:34
|
||||
|
|
||||
LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
@ -320,7 +320,7 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
|
|||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:231:22
|
||||
--> tests/ui/doc/doc-fixable.rs:234:22
|
||||
|
|
||||
LL | /// There is no try (do() or do_not()).
|
||||
| ^^^^
|
||||
|
|
@ -331,7 +331,7 @@ LL | /// There is no try (`do()` or do_not()).
|
|||
| ~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:231:30
|
||||
--> tests/ui/doc/doc-fixable.rs:234:30
|
||||
|
|
||||
LL | /// There is no try (do() or do_not()).
|
||||
| ^^^^^^^^
|
||||
|
|
@ -342,7 +342,7 @@ LL | /// There is no try (do() or `do_not()`).
|
|||
| ~~~~~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:234:5
|
||||
--> tests/ui/doc/doc-fixable.rs:237:5
|
||||
|
|
||||
LL | /// ABes
|
||||
| ^^^^
|
||||
|
|
@ -353,7 +353,7 @@ LL | /// `ABes`
|
|||
| ~~~~~~
|
||||
|
||||
error: item in documentation is missing backticks
|
||||
--> tests/ui/doc/doc-fixable.rs:240:9
|
||||
--> tests/ui/doc/doc-fixable.rs:243:9
|
||||
|
|
||||
LL | /// foo()
|
||||
| ^^^^^
|
||||
|
|
@ -364,7 +364,7 @@ LL | /// `foo()`
|
|||
| ~~~~~~~
|
||||
|
||||
error: you should put bare URLs between `<`/`>` or make a proper Markdown link
|
||||
--> tests/ui/doc/doc-fixable.rs:244:5
|
||||
--> tests/ui/doc/doc-fixable.rs:247:5
|
||||
|
|
||||
LL | /// https://github.com/rust-lang/rust-clippy/pull/12836
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/rust-lang/rust-clippy/pull/12836>`
|
||||
|
|
|
|||
|
|
@ -78,4 +78,8 @@ fn main() {
|
|||
const NEG_INF1: f32 = -1.0e+33f32;
|
||||
const NEG_INF2: f64 = -1.0e+3300f64;
|
||||
const NEG_INF3: f32 = -3.40282357e+38_f32;
|
||||
|
||||
// issue #12954
|
||||
const _: f64 = 3.0;
|
||||
const _: f64 = 3.0000000000000000;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,4 +78,8 @@ fn main() {
|
|||
const NEG_INF1: f32 = -1.0e+33f32;
|
||||
const NEG_INF2: f64 = -1.0e+3300f64;
|
||||
const NEG_INF3: f32 = -3.40282357e+38_f32;
|
||||
|
||||
// issue #12954
|
||||
const _: f64 = 3.0000000000000000e+00;
|
||||
const _: f64 = 3.0000000000000000;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,5 +91,11 @@ error: float has excessive precision
|
|||
LL | let _ = 1.000_000_000_000_001e-324_f64;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0_f64`
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: float has excessive precision
|
||||
--> tests/ui/excessive_precision.rs:83:20
|
||||
|
|
||||
LL | const _: f64 = 3.0000000000000000e+00;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `3.0`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ fn main() {
|
|||
let _ = 1.5_f64.sqrt();
|
||||
let _ = 1.5_f64.powi(3);
|
||||
|
||||
macro_rules! m {
|
||||
($e:expr) => {
|
||||
5.5 - $e
|
||||
};
|
||||
}
|
||||
|
||||
let _ = (1f32 + m!(2.0)).exp2();
|
||||
|
||||
// Cases where the lint shouldn't be applied
|
||||
let _ = x.powf(2.1);
|
||||
let _ = x.powf(-2.1);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ fn main() {
|
|||
let _ = 1.5_f64.powf(1.0 / 2.0);
|
||||
let _ = 1.5_f64.powf(3.0);
|
||||
|
||||
macro_rules! m {
|
||||
($e:expr) => {
|
||||
5.5 - $e
|
||||
};
|
||||
}
|
||||
|
||||
let _ = 2f32.powf(1f32 + m!(2.0));
|
||||
|
||||
// Cases where the lint shouldn't be applied
|
||||
let _ = x.powf(2.1);
|
||||
let _ = x.powf(-2.1);
|
||||
|
|
|
|||
|
|
@ -119,76 +119,82 @@ LL | let _ = 1.5_f64.powf(3.0);
|
|||
| ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:35:13
|
||||
--> tests/ui/floating_point_powf.rs:34:13
|
||||
|
|
||||
LL | let _ = 2f32.powf(1f32 + m!(2.0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1f32 + m!(2.0)).exp2()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:43:13
|
||||
|
|
||||
LL | let _ = 2f64.powf(x);
|
||||
| ^^^^^^^^^^^^ help: consider using: `x.exp2()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:36:13
|
||||
--> tests/ui/floating_point_powf.rs:44:13
|
||||
|
|
||||
LL | let _ = 2f64.powf(3.1);
|
||||
| ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:37:13
|
||||
--> tests/ui/floating_point_powf.rs:45:13
|
||||
|
|
||||
LL | let _ = 2f64.powf(-3.1);
|
||||
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:38:13
|
||||
--> tests/ui/floating_point_powf.rs:46:13
|
||||
|
|
||||
LL | let _ = std::f64::consts::E.powf(x);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:39:13
|
||||
--> tests/ui/floating_point_powf.rs:47:13
|
||||
|
|
||||
LL | let _ = std::f64::consts::E.powf(3.1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()`
|
||||
|
||||
error: exponent for bases 2 and e can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:40:13
|
||||
--> tests/ui/floating_point_powf.rs:48:13
|
||||
|
|
||||
LL | let _ = std::f64::consts::E.powf(-3.1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()`
|
||||
|
||||
error: square-root of a number can be computed more efficiently and accurately
|
||||
--> tests/ui/floating_point_powf.rs:41:13
|
||||
--> tests/ui/floating_point_powf.rs:49:13
|
||||
|
|
||||
LL | let _ = x.powf(1.0 / 2.0);
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
|
||||
|
||||
error: cube-root of a number can be computed more accurately
|
||||
--> tests/ui/floating_point_powf.rs:42:13
|
||||
--> tests/ui/floating_point_powf.rs:50:13
|
||||
|
|
||||
LL | let _ = x.powf(1.0 / 3.0);
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
|
||||
|
||||
error: exponentiation with integer powers can be computed more efficiently
|
||||
--> tests/ui/floating_point_powf.rs:43:13
|
||||
--> tests/ui/floating_point_powf.rs:51:13
|
||||
|
|
||||
LL | let _ = x.powf(3.0);
|
||||
| ^^^^^^^^^^^ help: consider using: `x.powi(3)`
|
||||
|
||||
error: exponentiation with integer powers can be computed more efficiently
|
||||
--> tests/ui/floating_point_powf.rs:44:13
|
||||
--> tests/ui/floating_point_powf.rs:52:13
|
||||
|
|
||||
LL | let _ = x.powf(-2.0);
|
||||
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
|
||||
|
||||
error: exponentiation with integer powers can be computed more efficiently
|
||||
--> tests/ui/floating_point_powf.rs:45:13
|
||||
--> tests/ui/floating_point_powf.rs:53:13
|
||||
|
|
||||
LL | let _ = x.powf(-2_147_483_648.0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)`
|
||||
|
||||
error: exponentiation with integer powers can be computed more efficiently
|
||||
--> tests/ui/floating_point_powf.rs:46:13
|
||||
--> tests/ui/floating_point_powf.rs:54:13
|
||||
|
|
||||
LL | let _ = x.powf(2_147_483_647.0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)`
|
||||
|
||||
error: aborting due to 31 previous errors
|
||||
error: aborting due to 32 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,177 +0,0 @@
|
|||
#![deny(clippy::index_refutable_slice)]
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
|
||||
enum SomeEnum<T> {
|
||||
One(T),
|
||||
Two(T),
|
||||
Three(T),
|
||||
Four(T),
|
||||
}
|
||||
|
||||
fn lintable_examples() {
|
||||
// Try with reference
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some([slice_0, ..]) = slice {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{}", slice_0);
|
||||
}
|
||||
|
||||
// Try with copy
|
||||
let slice: Option<[u32; 3]> = Some([1, 2, 3]);
|
||||
if let Some([slice_0, ..]) = slice {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{}", slice_0);
|
||||
}
|
||||
|
||||
// Try with long slice and small indices
|
||||
let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
if let Some([slice_0, _, slice_2, ..]) = slice {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{}", slice_2);
|
||||
println!("{}", slice_0);
|
||||
}
|
||||
|
||||
// Multiple bindings
|
||||
let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
|
||||
if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{}", slice_0);
|
||||
}
|
||||
|
||||
// Two lintable slices in one if let
|
||||
let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
|
||||
let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
|
||||
if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
//~| ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{} -> {}", a_2, b_1);
|
||||
}
|
||||
|
||||
// This requires the slice values to be borrowed as the slice values can only be
|
||||
// borrowed and `String` doesn't implement copy
|
||||
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
|
||||
if let Some([_, ref slice_1, ..]) = slice {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{:?}", slice_1);
|
||||
}
|
||||
println!("{:?}", slice);
|
||||
|
||||
// This should not suggest using the `ref` keyword as the scrutinee is already
|
||||
// a reference
|
||||
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
|
||||
if let Some([slice_0, ..]) = &slice {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
println!("{:?}", slice_0);
|
||||
}
|
||||
println!("{:?}", slice);
|
||||
}
|
||||
|
||||
fn slice_index_above_limit() {
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
|
||||
if let Some(slice) = slice {
|
||||
// Would cause a panic, IDK
|
||||
println!("{}", slice[7]);
|
||||
}
|
||||
}
|
||||
|
||||
fn slice_is_used() {
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some(slice) = slice {
|
||||
println!("{:?}", slice.len());
|
||||
}
|
||||
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some(slice) = slice {
|
||||
println!("{:?}", slice.to_vec());
|
||||
}
|
||||
|
||||
let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
|
||||
if let Some(slice) = opt {
|
||||
if !slice.is_empty() {
|
||||
println!("first: {}", slice[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The slice is used by an external function and should therefore not be linted
|
||||
fn check_slice_as_arg() {
|
||||
fn is_interesting<T>(slice: &[T; 2]) -> bool {
|
||||
!slice.is_empty()
|
||||
}
|
||||
|
||||
let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
|
||||
if let Some(slice) = &slice_wrapped {
|
||||
if is_interesting(slice) {
|
||||
println!("This is interesting {}", slice[0]);
|
||||
}
|
||||
}
|
||||
println!("{:?}", slice_wrapped);
|
||||
}
|
||||
|
||||
fn check_slice_in_struct() {
|
||||
#[derive(Debug)]
|
||||
struct Wrapper<'a> {
|
||||
inner: Option<&'a [String]>,
|
||||
is_awesome: bool,
|
||||
}
|
||||
|
||||
impl<'a> Wrapper<'a> {
|
||||
fn is_super_awesome(&self) -> bool {
|
||||
self.is_awesome
|
||||
}
|
||||
}
|
||||
|
||||
let inner = &[String::from("New"), String::from("World")];
|
||||
let wrap = Wrapper {
|
||||
inner: Some(inner),
|
||||
is_awesome: true,
|
||||
};
|
||||
|
||||
// Test 1: Field access
|
||||
if let Some([slice_0, ..]) = wrap.inner {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
if wrap.is_awesome {
|
||||
println!("This is awesome! {}", slice_0);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 2: function access
|
||||
if let Some([slice_0, ..]) = wrap.inner {
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
if wrap.is_super_awesome() {
|
||||
println!("This is super awesome! {}", slice_0);
|
||||
}
|
||||
}
|
||||
println!("Complete wrap: {:?}", wrap);
|
||||
}
|
||||
|
||||
/// This would be a nice additional feature to have in the future, but adding it
|
||||
/// now would make the PR too large. This is therefore only a test that we don't
|
||||
/// lint cases we can't make a reasonable suggestion for
|
||||
fn mutable_slice_index() {
|
||||
// Mut access
|
||||
let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]);
|
||||
if let Some(ref mut slice) = slice {
|
||||
slice[0] = String::from("Mr. Penguin");
|
||||
}
|
||||
println!("Use after modification: {:?}", slice);
|
||||
|
||||
// Mut access on reference
|
||||
let mut slice: Option<[String; 1]> = Some([String::from("Cat")]);
|
||||
if let Some(slice) = &mut slice {
|
||||
slice[0] = String::from("Lord Meow Meow");
|
||||
}
|
||||
println!("Use after modification: {:?}", slice);
|
||||
}
|
||||
|
||||
/// The lint will ignore bindings with sub patterns as it would be hard
|
||||
/// to build correct suggestions for these instances :)
|
||||
fn binding_with_sub_pattern() {
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some(slice @ [_, _, _]) = slice {
|
||||
println!("{:?}", slice[2]);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![deny(clippy::index_refutable_slice)]
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
enum SomeEnum<T> {
|
||||
One(T),
|
||||
Two(T),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:14:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:16:17
|
||||
|
|
||||
LL | if let Some(slice) = slice {
|
||||
| ^^^^^
|
||||
|
|
@ -19,7 +19,7 @@ LL | println!("{}", slice_0);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:21:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:23:17
|
||||
|
|
||||
LL | if let Some(slice) = slice {
|
||||
| ^^^^^
|
||||
|
|
@ -34,7 +34,7 @@ LL | println!("{}", slice_0);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:28:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17
|
||||
|
|
||||
LL | if let Some(slice) = slice {
|
||||
| ^^^^^
|
||||
|
|
@ -50,7 +50,7 @@ LL ~ println!("{}", slice_0);
|
|||
|
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:36:26
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:38:26
|
||||
|
|
||||
LL | if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
|
||||
| ^^^^^
|
||||
|
|
@ -65,7 +65,7 @@ LL | println!("{}", slice_0);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:29
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:29
|
||||
|
|
||||
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
|
||||
| ^
|
||||
|
|
@ -80,7 +80,7 @@ LL | println!("{} -> {}", a_2, b[1]);
|
|||
| ~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:38
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:38
|
||||
|
|
||||
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
|
||||
| ^
|
||||
|
|
@ -95,7 +95,7 @@ LL | println!("{} -> {}", a[2], b_1);
|
|||
| ~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:53:21
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:55:21
|
||||
|
|
||||
LL | if let Some(ref slice) = slice {
|
||||
| ^^^^^
|
||||
|
|
@ -110,7 +110,7 @@ LL | println!("{:?}", slice_1);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:62:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:64:17
|
||||
|
|
||||
LL | if let Some(slice) = &slice {
|
||||
| ^^^^^
|
||||
|
|
@ -125,7 +125,7 @@ LL | println!("{:?}", slice_0);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:132:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:134:17
|
||||
|
|
||||
LL | if let Some(slice) = wrap.inner {
|
||||
| ^^^^^
|
||||
|
|
@ -140,7 +140,7 @@ LL | println!("This is awesome! {}", slice_0);
|
|||
| ~~~~~~~
|
||||
|
||||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:140:17
|
||||
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:142:17
|
||||
|
|
||||
LL | if let Some(slice) = wrap.inner {
|
||||
| ^^^^^
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
#![deny(clippy::index_refutable_slice)]
|
||||
|
||||
extern crate if_chain;
|
||||
use if_chain::if_chain;
|
||||
|
||||
macro_rules! if_let_slice_macro {
|
||||
() => {
|
||||
// This would normally be linted
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some(slice) = slice {
|
||||
println!("{}", slice[0]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Don't lint this
|
||||
if_let_slice_macro!();
|
||||
|
||||
// Do lint this
|
||||
if_chain! {
|
||||
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||
if let Some([slice_0, ..]) = slice;
|
||||
//~^ ERROR: this binding can be a slice pattern to avoid indexing
|
||||
then {
|
||||
println!("{}", slice_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#![deny(clippy::index_refutable_slice)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
extern crate if_chain;
|
||||
use if_chain::if_chain;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this binding can be a slice pattern to avoid indexing
|
||||
--> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:23:21
|
||||
--> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:25:21
|
||||
|
|
||||
LL | if let Some(slice) = slice;
|
||||
| ^^^^^
|
||||
|
|
|
|||
|
|
@ -1,196 +0,0 @@
|
|||
#![warn(clippy::let_unit_value)]
|
||||
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
|
||||
|
||||
macro_rules! let_and_return {
|
||||
($n:expr) => {{
|
||||
let ret = $n;
|
||||
}};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("x");
|
||||
let _y = 1; // this is fine
|
||||
let _z = ((), 1); // this as well
|
||||
if true {
|
||||
// do not lint this, since () is explicit
|
||||
let _a = ();
|
||||
let () = dummy();
|
||||
let () = ();
|
||||
() = dummy();
|
||||
() = ();
|
||||
let _a: () = ();
|
||||
let _a: () = dummy();
|
||||
}
|
||||
|
||||
consume_units_with_for_loop(); // should be fine as well
|
||||
|
||||
multiline_sugg();
|
||||
|
||||
let_and_return!(()) // should be fine
|
||||
}
|
||||
|
||||
fn dummy() {}
|
||||
|
||||
// Related to issue #1964
|
||||
fn consume_units_with_for_loop() {
|
||||
// `for_let_unit` lint should not be triggered by consuming them using for loop.
|
||||
let v = vec![(), (), ()];
|
||||
let mut count = 0;
|
||||
for _ in v {
|
||||
count += 1;
|
||||
}
|
||||
assert_eq!(count, 3);
|
||||
|
||||
// Same for consuming from some other Iterator<Item = ()>.
|
||||
let (tx, rx) = ::std::sync::mpsc::channel();
|
||||
tx.send(()).unwrap();
|
||||
drop(tx);
|
||||
|
||||
count = 0;
|
||||
for _ in rx.iter() {
|
||||
count += 1;
|
||||
}
|
||||
assert_eq!(count, 1);
|
||||
}
|
||||
|
||||
fn multiline_sugg() {
|
||||
let v: Vec<u8> = vec![2];
|
||||
|
||||
v
|
||||
.into_iter()
|
||||
.map(|i| i * 2)
|
||||
.filter(|i| i % 2 == 0)
|
||||
.map(|_| ())
|
||||
.next()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ContainsUnit(()); // should be fine
|
||||
|
||||
fn _returns_generic() {
|
||||
fn f<T>() -> T {
|
||||
unimplemented!()
|
||||
}
|
||||
fn f2<T, U>(_: T) -> U {
|
||||
unimplemented!()
|
||||
}
|
||||
fn f3<T>(x: T) -> T {
|
||||
x
|
||||
}
|
||||
fn f5<T: Default>(x: bool) -> Option<T> {
|
||||
x.then(|| T::default())
|
||||
}
|
||||
|
||||
let _: () = f();
|
||||
let x: () = f();
|
||||
|
||||
let _: () = f2(0i32);
|
||||
let x: () = f2(0i32);
|
||||
|
||||
let _: () = f3(());
|
||||
let x: () = f3(());
|
||||
|
||||
fn f4<T>(mut x: Vec<T>) -> T {
|
||||
x.pop().unwrap()
|
||||
}
|
||||
let _: () = f4(vec![()]);
|
||||
let x: () = f4(vec![()]);
|
||||
|
||||
let _: () = {
|
||||
let x = 5;
|
||||
f2(x)
|
||||
};
|
||||
|
||||
let _: () = if true { f() } else { f2(0) };
|
||||
let x: () = if true { f() } else { f2(0) };
|
||||
|
||||
match Some(0) {
|
||||
None => f2(1),
|
||||
Some(0) => f(),
|
||||
Some(1) => f2(3),
|
||||
Some(_) => (),
|
||||
};
|
||||
|
||||
let _: () = f5(true).unwrap();
|
||||
|
||||
#[allow(clippy::let_unit_value)]
|
||||
{
|
||||
let x = f();
|
||||
let y;
|
||||
let z;
|
||||
match 0 {
|
||||
0 => {
|
||||
y = f();
|
||||
z = f();
|
||||
},
|
||||
1 => {
|
||||
println!("test");
|
||||
y = f();
|
||||
z = f3(());
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
let x1;
|
||||
let x2;
|
||||
if true {
|
||||
x1 = f();
|
||||
x2 = x1;
|
||||
} else {
|
||||
x2 = f();
|
||||
x1 = x2;
|
||||
}
|
||||
|
||||
let opt;
|
||||
match f5(true) {
|
||||
Some(x) => opt = x,
|
||||
None => panic!(),
|
||||
};
|
||||
|
||||
#[warn(clippy::let_unit_value)]
|
||||
{
|
||||
let _: () = x;
|
||||
let _: () = y;
|
||||
let _: () = z;
|
||||
let _: () = x1;
|
||||
let _: () = x2;
|
||||
let _: () = opt;
|
||||
}
|
||||
}
|
||||
|
||||
let () = f();
|
||||
}
|
||||
|
||||
fn attributes() {
|
||||
fn f() {}
|
||||
|
||||
#[allow(clippy::let_unit_value)]
|
||||
let _ = f();
|
||||
#[expect(clippy::let_unit_value)]
|
||||
let _ = f();
|
||||
}
|
||||
|
||||
async fn issue10433() {
|
||||
let _pending: () = std::future::pending().await;
|
||||
}
|
||||
|
||||
pub async fn issue11502(a: ()) {}
|
||||
|
||||
pub fn issue12594() {
|
||||
fn returns_unit() {}
|
||||
|
||||
fn returns_result<T>(res: T) -> Result<T, ()> {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn actual_test() {
|
||||
// create first a unit value'd value
|
||||
returns_unit();
|
||||
returns_result(()).unwrap();
|
||||
returns_result(()).unwrap();
|
||||
// make sure we replace only the first variable
|
||||
let res = 1;
|
||||
returns_result(res).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![warn(clippy::let_unit_value)]
|
||||
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
macro_rules! let_and_return {
|
||||
($n:expr) => {{
|
||||
let ret = $n;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:11:5
|
||||
--> tests/ui/let_unit.rs:13:5
|
||||
|
|
||||
LL | let _x = println!("x");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
|
||||
|
|
@ -8,7 +8,7 @@ LL | let _x = println!("x");
|
|||
= help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:59:5
|
||||
--> tests/ui/let_unit.rs:61:5
|
||||
|
|
||||
LL | / let _ = v
|
||||
LL | | .into_iter()
|
||||
|
|
@ -31,7 +31,7 @@ LL + .unwrap();
|
|||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:108:5
|
||||
--> tests/ui/let_unit.rs:110:5
|
||||
|
|
||||
LL | / let x = match Some(0) {
|
||||
LL | | None => f2(1),
|
||||
|
|
@ -52,7 +52,7 @@ LL + };
|
|||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:189:9
|
||||
--> tests/ui/let_unit.rs:191:9
|
||||
|
|
||||
LL | let res = returns_unit();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
//@revisions: edition2018 edition2021
|
||||
//@[edition2018] edition:2018
|
||||
//@[edition2021] edition:2021
|
||||
|
||||
#![warn(clippy::manual_assert)]
|
||||
#![allow(dead_code, unused_doc_comments)]
|
||||
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]
|
||||
|
||||
macro_rules! one {
|
||||
() => {
|
||||
1
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = vec![1, 2, 3];
|
||||
let c = Some(2);
|
||||
if !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& c.is_some()
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
{
|
||||
panic!("qaqaq{:?}", a);
|
||||
}
|
||||
assert!(a.is_empty(), "qaqaq{:?}", a);
|
||||
assert!(a.is_empty(), "qwqwq");
|
||||
if a.len() == 3 {
|
||||
println!("qwq");
|
||||
println!("qwq");
|
||||
println!("qwq");
|
||||
}
|
||||
if let Some(b) = c {
|
||||
panic!("orz {}", b);
|
||||
}
|
||||
if a.len() == 3 {
|
||||
panic!("qaqaq");
|
||||
} else {
|
||||
println!("qwq");
|
||||
}
|
||||
let b = vec![1, 2, 3];
|
||||
assert!(!b.is_empty(), "panic1");
|
||||
assert!(!(b.is_empty() && a.is_empty()), "panic2");
|
||||
assert!(!(a.is_empty() && !b.is_empty()), "panic3");
|
||||
assert!(!(b.is_empty() || a.is_empty()), "panic4");
|
||||
assert!(!(a.is_empty() || !b.is_empty()), "panic5");
|
||||
assert!(!a.is_empty(), "with expansion {}", one!());
|
||||
if a.is_empty() {
|
||||
let _ = 0;
|
||||
} else if a.len() == 1 {
|
||||
panic!("panic6");
|
||||
}
|
||||
}
|
||||
|
||||
fn issue7730(a: u8) {
|
||||
// Suggestion should preserve comment
|
||||
// comment
|
||||
/* this is a
|
||||
multiline
|
||||
comment */
|
||||
/// Doc comment
|
||||
// comment after `panic!`
|
||||
assert!(!(a > 2), "panic with comment");
|
||||
}
|
||||
|
||||
fn issue12505() {
|
||||
struct Foo<T, const N: usize>(T);
|
||||
|
||||
impl<T, const N: usize> Foo<T, N> {
|
||||
const BAR: () = assert!(!(N == 0), );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:30:5
|
||||
--> tests/ui/manual_assert.rs:32:5
|
||||
|
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qaqaq{:?}", a);
|
||||
|
|
@ -10,7 +10,7 @@ LL | | }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:33:5
|
||||
--> tests/ui/manual_assert.rs:35:5
|
||||
|
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qwqwq");
|
||||
|
|
@ -18,7 +18,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:50:5
|
||||
--> tests/ui/manual_assert.rs:52:5
|
||||
|
|
||||
LL | / if b.is_empty() {
|
||||
LL | | panic!("panic1");
|
||||
|
|
@ -26,7 +26,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:53:5
|
||||
--> tests/ui/manual_assert.rs:55:5
|
||||
|
|
||||
LL | / if b.is_empty() && a.is_empty() {
|
||||
LL | | panic!("panic2");
|
||||
|
|
@ -34,7 +34,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:56:5
|
||||
--> tests/ui/manual_assert.rs:58:5
|
||||
|
|
||||
LL | / if a.is_empty() && !b.is_empty() {
|
||||
LL | | panic!("panic3");
|
||||
|
|
@ -42,7 +42,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:59:5
|
||||
--> tests/ui/manual_assert.rs:61:5
|
||||
|
|
||||
LL | / if b.is_empty() || a.is_empty() {
|
||||
LL | | panic!("panic4");
|
||||
|
|
@ -50,7 +50,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:62:5
|
||||
--> tests/ui/manual_assert.rs:64:5
|
||||
|
|
||||
LL | / if a.is_empty() || !b.is_empty() {
|
||||
LL | | panic!("panic5");
|
||||
|
|
@ -58,7 +58,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:65:5
|
||||
--> tests/ui/manual_assert.rs:67:5
|
||||
|
|
||||
LL | / if a.is_empty() {
|
||||
LL | | panic!("with expansion {}", one!())
|
||||
|
|
@ -66,7 +66,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:77:5
|
||||
--> tests/ui/manual_assert.rs:79:5
|
||||
|
|
||||
LL | / if a > 2 {
|
||||
LL | | // comment
|
||||
|
|
@ -83,7 +83,7 @@ LL | assert!(!(a > 2), "panic with comment");
|
|||
|
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:91:25
|
||||
--> tests/ui/manual_assert.rs:93:25
|
||||
|
|
||||
LL | const BAR: () = if N == 0 {
|
||||
| _________________________^
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
//@revisions: edition2018 edition2021
|
||||
//@[edition2018] edition:2018
|
||||
//@[edition2021] edition:2021
|
||||
|
||||
#![warn(clippy::manual_assert)]
|
||||
#![allow(dead_code, unused_doc_comments)]
|
||||
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]
|
||||
|
||||
macro_rules! one {
|
||||
() => {
|
||||
1
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = vec![1, 2, 3];
|
||||
let c = Some(2);
|
||||
if !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& c.is_some()
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
&& !a.is_empty()
|
||||
&& a.len() == 3
|
||||
{
|
||||
panic!("qaqaq{:?}", a);
|
||||
}
|
||||
assert!(a.is_empty(), "qaqaq{:?}", a);
|
||||
assert!(a.is_empty(), "qwqwq");
|
||||
if a.len() == 3 {
|
||||
println!("qwq");
|
||||
println!("qwq");
|
||||
println!("qwq");
|
||||
}
|
||||
if let Some(b) = c {
|
||||
panic!("orz {}", b);
|
||||
}
|
||||
if a.len() == 3 {
|
||||
panic!("qaqaq");
|
||||
} else {
|
||||
println!("qwq");
|
||||
}
|
||||
let b = vec![1, 2, 3];
|
||||
assert!(!b.is_empty(), "panic1");
|
||||
assert!(!(b.is_empty() && a.is_empty()), "panic2");
|
||||
assert!(!(a.is_empty() && !b.is_empty()), "panic3");
|
||||
assert!(!(b.is_empty() || a.is_empty()), "panic4");
|
||||
assert!(!(a.is_empty() || !b.is_empty()), "panic5");
|
||||
assert!(!a.is_empty(), "with expansion {}", one!());
|
||||
if a.is_empty() {
|
||||
let _ = 0;
|
||||
} else if a.len() == 1 {
|
||||
panic!("panic6");
|
||||
}
|
||||
}
|
||||
|
||||
fn issue7730(a: u8) {
|
||||
// Suggestion should preserve comment
|
||||
// comment
|
||||
/* this is a
|
||||
multiline
|
||||
comment */
|
||||
/// Doc comment
|
||||
// comment after `panic!`
|
||||
assert!(!(a > 2), "panic with comment");
|
||||
}
|
||||
|
||||
fn issue12505() {
|
||||
struct Foo<T, const N: usize>(T);
|
||||
|
||||
impl<T, const N: usize> Foo<T, N> {
|
||||
const BAR: () = assert!(!(N == 0), );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:30:5
|
||||
--> tests/ui/manual_assert.rs:32:5
|
||||
|
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qaqaq{:?}", a);
|
||||
|
|
@ -10,7 +10,7 @@ LL | | }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:33:5
|
||||
--> tests/ui/manual_assert.rs:35:5
|
||||
|
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qwqwq");
|
||||
|
|
@ -18,7 +18,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:50:5
|
||||
--> tests/ui/manual_assert.rs:52:5
|
||||
|
|
||||
LL | / if b.is_empty() {
|
||||
LL | | panic!("panic1");
|
||||
|
|
@ -26,7 +26,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:53:5
|
||||
--> tests/ui/manual_assert.rs:55:5
|
||||
|
|
||||
LL | / if b.is_empty() && a.is_empty() {
|
||||
LL | | panic!("panic2");
|
||||
|
|
@ -34,7 +34,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:56:5
|
||||
--> tests/ui/manual_assert.rs:58:5
|
||||
|
|
||||
LL | / if a.is_empty() && !b.is_empty() {
|
||||
LL | | panic!("panic3");
|
||||
|
|
@ -42,7 +42,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:59:5
|
||||
--> tests/ui/manual_assert.rs:61:5
|
||||
|
|
||||
LL | / if b.is_empty() || a.is_empty() {
|
||||
LL | | panic!("panic4");
|
||||
|
|
@ -50,7 +50,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:62:5
|
||||
--> tests/ui/manual_assert.rs:64:5
|
||||
|
|
||||
LL | / if a.is_empty() || !b.is_empty() {
|
||||
LL | | panic!("panic5");
|
||||
|
|
@ -58,7 +58,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:65:5
|
||||
--> tests/ui/manual_assert.rs:67:5
|
||||
|
|
||||
LL | / if a.is_empty() {
|
||||
LL | | panic!("with expansion {}", one!())
|
||||
|
|
@ -66,7 +66,7 @@ LL | | }
|
|||
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:77:5
|
||||
--> tests/ui/manual_assert.rs:79:5
|
||||
|
|
||||
LL | / if a > 2 {
|
||||
LL | | // comment
|
||||
|
|
@ -83,7 +83,7 @@ LL | assert!(!(a > 2), "panic with comment");
|
|||
|
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> tests/ui/manual_assert.rs:91:25
|
||||
--> tests/ui/manual_assert.rs:93:25
|
||||
|
|
||||
LL | const BAR: () = if N == 0 {
|
||||
| _________________________^
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//@[edition2018] edition:2018
|
||||
//@[edition2021] edition:2021
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
#![warn(clippy::manual_assert)]
|
||||
#![allow(dead_code, unused_doc_comments)]
|
||||
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
#![warn(clippy::manual_async_fn)]
|
||||
#![allow(clippy::needless_pub_self, unused)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
async fn fut() -> i32 { 42 }
|
||||
|
||||
#[rustfmt::skip]
|
||||
async fn fut2() -> i32 { 42 }
|
||||
|
||||
#[rustfmt::skip]
|
||||
async fn fut3() -> i32 { 42 }
|
||||
|
||||
async fn empty_fut() {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
async fn empty_fut2() {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
async fn empty_fut3() {}
|
||||
|
||||
async fn core_fut() -> i32 { 42 }
|
||||
|
||||
// should be ignored
|
||||
fn has_other_stmts() -> impl core::future::Future<Output = i32> {
|
||||
let _ = 42;
|
||||
async move { 42 }
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
fn not_fut() -> i32 {
|
||||
42
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
async fn already_async() -> impl Future<Output = i32> {
|
||||
async { 42 }
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
async fn inh_fut() -> i32 {
|
||||
// NOTE: this code is here just to check that the indentation is correct in the suggested fix
|
||||
let a = 42;
|
||||
let b = 21;
|
||||
if a < b {
|
||||
let c = 21;
|
||||
let d = 42;
|
||||
if c < d {
|
||||
let _ = 42;
|
||||
}
|
||||
}
|
||||
42
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
fn not_fut(&self) -> i32 {
|
||||
42
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
fn has_other_stmts() -> impl core::future::Future<Output = i32> {
|
||||
let _ = 42;
|
||||
async move { 42 }
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
async fn already_async(&self) -> impl Future<Output = i32> {
|
||||
async { 42 }
|
||||
}
|
||||
}
|
||||
|
||||
// Tests related to lifetime capture
|
||||
|
||||
async fn elided(_: &i32) -> i32 { 42 }
|
||||
|
||||
// should be ignored
|
||||
fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
|
||||
async { 42 }
|
||||
}
|
||||
|
||||
async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
|
||||
|
||||
// should be ignored
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
fn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> {
|
||||
async { 42 }
|
||||
}
|
||||
|
||||
// should be ignored
|
||||
mod issue_5765 {
|
||||
use std::future::Future;
|
||||
|
||||
struct A;
|
||||
impl A {
|
||||
fn f(&self) -> impl Future<Output = ()> {
|
||||
async {}
|
||||
}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let _future = {
|
||||
let a = A;
|
||||
a.f()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn issue_10450() -> i32 { 42 }
|
||||
|
||||
pub(crate) async fn issue_10450_2() -> i32 { 42 }
|
||||
|
||||
pub(self) async fn issue_10450_3() -> i32 { 42 }
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![warn(clippy::manual_async_fn)]
|
||||
#![allow(clippy::needless_pub_self, unused)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
fn fut() -> impl Future<Output = i32> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:6:1
|
||||
--> tests/ui/manual_async_fn.rs:8:1
|
||||
|
|
||||
LL | fn fut() -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -16,7 +16,7 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:11:1
|
||||
--> tests/ui/manual_async_fn.rs:13:1
|
||||
|
|
||||
LL | fn fut2() ->impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -31,7 +31,7 @@ LL | fn fut2() ->impl Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:16:1
|
||||
--> tests/ui/manual_async_fn.rs:18:1
|
||||
|
|
||||
LL | fn fut3()-> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -46,7 +46,7 @@ LL | fn fut3()-> impl Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:20:1
|
||||
--> tests/ui/manual_async_fn.rs:22:1
|
||||
|
|
||||
LL | fn empty_fut() -> impl Future<Output = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -61,7 +61,7 @@ LL | fn empty_fut() -> impl Future<Output = ()> {}
|
|||
| ~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:25:1
|
||||
--> tests/ui/manual_async_fn.rs:27:1
|
||||
|
|
||||
LL | fn empty_fut2() ->impl Future<Output = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -76,7 +76,7 @@ LL | fn empty_fut2() ->impl Future<Output = ()> {}
|
|||
| ~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:30:1
|
||||
--> tests/ui/manual_async_fn.rs:32:1
|
||||
|
|
||||
LL | fn empty_fut3()-> impl Future<Output = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -91,7 +91,7 @@ LL | fn empty_fut3()-> impl Future<Output = ()> {}
|
|||
| ~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:34:1
|
||||
--> tests/ui/manual_async_fn.rs:36:1
|
||||
|
|
||||
LL | fn core_fut() -> impl core::future::Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -106,7 +106,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:56:5
|
||||
--> tests/ui/manual_async_fn.rs:58:5
|
||||
|
|
||||
LL | fn inh_fut() -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -133,7 +133,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:91:1
|
||||
--> tests/ui/manual_async_fn.rs:93:1
|
||||
|
|
||||
LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -148,7 +148,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:100:1
|
||||
--> tests/ui/manual_async_fn.rs:102:1
|
||||
|
|
||||
LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -163,7 +163,7 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> +
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:129:1
|
||||
--> tests/ui/manual_async_fn.rs:131:1
|
||||
|
|
||||
LL | pub fn issue_10450() -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -178,7 +178,7 @@ LL | pub fn issue_10450() -> impl Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:133:1
|
||||
--> tests/ui/manual_async_fn.rs:135:1
|
||||
|
|
||||
LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -193,7 +193,7 @@ LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { 42 }
|
|||
| ~~~~~~
|
||||
|
||||
error: this function can be simplified using the `async fn` syntax
|
||||
--> tests/ui/manual_async_fn.rs:137:1
|
||||
--> tests/ui/manual_async_fn.rs:139:1
|
||||
|
|
||||
LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
#![warn(clippy::manual_split_once)]
|
||||
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
|
||||
|
||||
extern crate itertools;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let _ = "key=value".splitn(2, '=').nth(2);
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
let (_, _) = "key=value".split_once('=').unwrap();
|
||||
|
||||
let s = String::from("key=value");
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
let s = Box::<str>::from("key=value");
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
let s = &"key=value";
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
fn _f(s: &str) -> Option<&str> {
|
||||
let _ = s.split_once('=')?.1;
|
||||
let _ = s.split_once('=')?.1;
|
||||
let _ = s.rsplit_once('=')?.0;
|
||||
let _ = s.rsplit_once('=')?.0;
|
||||
None
|
||||
}
|
||||
|
||||
// Don't lint, slices don't have `split_once`
|
||||
let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
|
||||
|
||||
// `rsplitn` gives the results in the reverse order of `rsplit_once`
|
||||
let _ = "key=value".rsplit_once('=').unwrap().0;
|
||||
let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();
|
||||
let _ = s.rsplit_once('=').map(|x| x.0);
|
||||
}
|
||||
|
||||
fn indirect() -> Option<()> {
|
||||
let (l, r) = "a.b.c".split_once('.').unwrap();
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".split_once('.')?;
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".rsplit_once('.').unwrap();
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".rsplit_once('.')?;
|
||||
|
||||
|
||||
|
||||
// could lint, currently doesn't
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let other = 1;
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let mut mut_binding = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let tuple = (iter.next()?, iter.next()?);
|
||||
|
||||
// should not lint
|
||||
|
||||
let mut missing_unwrap = "a.b.c".splitn(2, '.');
|
||||
let l = missing_unwrap.next();
|
||||
let r = missing_unwrap.next();
|
||||
|
||||
let mut mixed_unrap = "a.b.c".splitn(2, '.');
|
||||
let unwrap = mixed_unrap.next().unwrap();
|
||||
let question_mark = mixed_unrap.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let same_name = iter.next()?;
|
||||
let same_name = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let shadows_existing = "d";
|
||||
let shadows_existing = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let becomes_shadowed = iter.next()?;
|
||||
let becomes_shadowed = "d";
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
let third_usage = iter.next()?;
|
||||
|
||||
let mut n_three = "a.b.c".splitn(3, '.');
|
||||
let l = n_three.next()?;
|
||||
let r = n_three.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
{
|
||||
let in_block = iter.next()?;
|
||||
}
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut lacks_binding = "a.b.c".splitn(2, '.');
|
||||
let _ = lacks_binding.next()?;
|
||||
let r = lacks_binding.next()?;
|
||||
|
||||
let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut assigned = "";
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let l = iter.next()?;
|
||||
assigned = iter.next()?;
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.51"]
|
||||
fn _msrv_1_51() {
|
||||
// `str::split_once` was stabilized in 1.52. Do not lint this
|
||||
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let a = iter.next().unwrap();
|
||||
let b = iter.next().unwrap();
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.52"]
|
||||
fn _msrv_1_52() {
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
|
||||
let (a, b) = "a.b.c".split_once('.').unwrap();
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![warn(clippy::manual_split_once)]
|
||||
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
extern crate itertools;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:11:13
|
||||
--> tests/ui/manual_split_once.rs:13:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
|
@ -8,79 +8,79 @@ LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
|||
= help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:12:13
|
||||
--> tests/ui/manual_split_once.rs:14:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:13:18
|
||||
--> tests/ui/manual_split_once.rs:15:18
|
||||
|
|
||||
LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:16:13
|
||||
--> tests/ui/manual_split_once.rs:18:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:19:13
|
||||
--> tests/ui/manual_split_once.rs:21:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:22:13
|
||||
--> tests/ui/manual_split_once.rs:24:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').skip(1).next().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:25:17
|
||||
--> tests/ui/manual_split_once.rs:27:17
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1)?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:26:17
|
||||
--> tests/ui/manual_split_once.rs:28:17
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').skip(1).next()?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:27:17
|
||||
--> tests/ui/manual_split_once.rs:29:17
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').nth(1)?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:28:17
|
||||
--> tests/ui/manual_split_once.rs:30:17
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').skip(1).next()?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:36:13
|
||||
--> tests/ui/manual_split_once.rs:38:13
|
||||
|
|
||||
LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:37:18
|
||||
--> tests/ui/manual_split_once.rs:39:18
|
||||
|
|
||||
LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:38:13
|
||||
--> tests/ui/manual_split_once.rs:40:13
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').nth(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:42:5
|
||||
--> tests/ui/manual_split_once.rs:44:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -103,7 +103,7 @@ LL - let r = iter.next().unwrap();
|
|||
|
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:46:5
|
||||
--> tests/ui/manual_split_once.rs:48:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -126,7 +126,7 @@ LL - let r = iter.next()?;
|
|||
|
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:50:5
|
||||
--> tests/ui/manual_split_once.rs:52:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".rsplitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -149,7 +149,7 @@ LL - let l = iter.next().unwrap();
|
|||
|
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:54:5
|
||||
--> tests/ui/manual_split_once.rs:56:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".rsplitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -172,13 +172,13 @@ LL - let l = iter.next()?;
|
|||
|
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:139:13
|
||||
--> tests/ui/manual_split_once.rs:141:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:141:5
|
||||
--> tests/ui/manual_split_once.rs:143:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -234,4 +234,20 @@ fn implicit_deref_ref() {
|
|||
};
|
||||
}
|
||||
|
||||
mod issue_13018 {
|
||||
use std::collections::HashMap;
|
||||
|
||||
type RefName = i32;
|
||||
pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
|
||||
if let Some(names) = index.get(&id) { names } else { &[] }
|
||||
}
|
||||
|
||||
pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
|
||||
match index.get(&id) {
|
||||
Some(names) => names,
|
||||
None => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -284,4 +284,20 @@ fn implicit_deref_ref() {
|
|||
};
|
||||
}
|
||||
|
||||
mod issue_13018 {
|
||||
use std::collections::HashMap;
|
||||
|
||||
type RefName = i32;
|
||||
pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
|
||||
if let Some(names) = index.get(&id) { names } else { &[] }
|
||||
}
|
||||
|
||||
pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
|
||||
match index.get(&id) {
|
||||
Some(names) => names,
|
||||
None => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,258 +0,0 @@
|
|||
#![warn(clippy::match_same_arms)]
|
||||
#![allow(
|
||||
clippy::disallowed_names,
|
||||
clippy::diverging_sub_expression,
|
||||
clippy::uninlined_format_args,
|
||||
clippy::match_single_binding,
|
||||
clippy::match_like_matches_macro
|
||||
)]
|
||||
fn bar<T>(_: T) {}
|
||||
fn foo() -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn match_same_arms() {
|
||||
let _ = match 42 {
|
||||
_ => {
|
||||
foo();
|
||||
let mut a = 42 + [23].len() as i32;
|
||||
if true {
|
||||
a += 7;
|
||||
}
|
||||
a = -31 - a;
|
||||
a
|
||||
},
|
||||
};
|
||||
//~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm
|
||||
|
||||
let _ = match 42 {
|
||||
51 | 42 => foo(), //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => true,
|
||||
};
|
||||
|
||||
let _ = match Some(42) {
|
||||
None | Some(_) => 24, //~ ERROR: this match arm has an identical body to another arm
|
||||
};
|
||||
|
||||
let _ = match Some(42) {
|
||||
Some(foo) => 24,
|
||||
None => 24,
|
||||
};
|
||||
|
||||
let _ = match Some(42) {
|
||||
Some(42) => 24,
|
||||
Some(a) => 24, // bindings are different
|
||||
None => 0,
|
||||
};
|
||||
|
||||
let _ = match Some(42) {
|
||||
Some(a) if a > 0 => 24,
|
||||
Some(a) => 24, // one arm has a guard
|
||||
None => 0,
|
||||
};
|
||||
|
||||
match (Some(42), Some(42)) {
|
||||
(None, Some(a)) | (Some(a), None) => bar(a), //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => (),
|
||||
}
|
||||
|
||||
// No warning because guards are different
|
||||
let _ = match Some(42) {
|
||||
Some(a) if a == 42 => a,
|
||||
Some(a) if a == 24 => a,
|
||||
Some(_) => 24,
|
||||
None => 0,
|
||||
};
|
||||
|
||||
let _ = match (Some(42), Some(42)) {
|
||||
(None, Some(a)) | (Some(a), None) if a == 42 => a, //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
match (Some(42), Some(42)) {
|
||||
(Some(a), ..) | (.., Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let _ = match Some(()) {
|
||||
Some(()) => 0.0,
|
||||
None => -0.0,
|
||||
};
|
||||
|
||||
match (Some(42), Some("")) {
|
||||
(Some(a), None) => bar(a),
|
||||
(None, Some(a)) => bar(a), // bindings have different types
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let x: Result<i32, &str> = Ok(3);
|
||||
|
||||
// No warning because of the guard.
|
||||
match x {
|
||||
Ok(x) if x * x == 64 => println!("ok"),
|
||||
Ok(_) => println!("ok"),
|
||||
Err(_) => println!("err"),
|
||||
}
|
||||
|
||||
// This used to be a false positive; see issue #1996.
|
||||
match x {
|
||||
Ok(3) => println!("ok"),
|
||||
Ok(x) if x * x == 64 => println!("ok 64"),
|
||||
Ok(_) => println!("ok"),
|
||||
Err(_) => println!("err"),
|
||||
}
|
||||
|
||||
match (x, Some(1i32)) {
|
||||
(Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => println!("err"),
|
||||
}
|
||||
|
||||
// No warning; different types for `x`.
|
||||
match (x, Some(1.0f64)) {
|
||||
(Ok(x), Some(_)) => println!("ok {}", x),
|
||||
(Ok(_), Some(x)) => println!("ok {}", x),
|
||||
_ => println!("err"),
|
||||
}
|
||||
|
||||
// False negative #2251.
|
||||
match x {
|
||||
Ok(_tmp) => println!("ok"),
|
||||
Ok(_) | Ok(3) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm
|
||||
Err(_) => {
|
||||
unreachable!();
|
||||
},
|
||||
}
|
||||
|
||||
// False positive #1390
|
||||
macro_rules! empty {
|
||||
($e:expr) => {};
|
||||
}
|
||||
match 0 {
|
||||
0 => {
|
||||
empty!(0);
|
||||
},
|
||||
1 => {
|
||||
empty!(1);
|
||||
},
|
||||
x => {
|
||||
empty!(x);
|
||||
},
|
||||
};
|
||||
|
||||
// still lint if the tokens are the same
|
||||
match 0 {
|
||||
1 | 0 => {
|
||||
empty!(0);
|
||||
},
|
||||
x => {
|
||||
empty!(x);
|
||||
},
|
||||
}
|
||||
//~^^^^^^^ ERROR: this match arm has an identical body to another arm
|
||||
|
||||
match_expr_like_matches_macro_priority();
|
||||
}
|
||||
|
||||
fn match_expr_like_matches_macro_priority() {
|
||||
enum E {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
}
|
||||
let x = E::A;
|
||||
let _ans = match x {
|
||||
E::A => false,
|
||||
E::B => false,
|
||||
_ => true,
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = match Some(0) {
|
||||
Some(0) => 0,
|
||||
Some(1) => 1,
|
||||
#[cfg(feature = "foo")]
|
||||
Some(2) => 2,
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
enum Foo {
|
||||
X(u32),
|
||||
Y(u32),
|
||||
Z(u32),
|
||||
}
|
||||
|
||||
// Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.
|
||||
let _ = match Foo::X(0) {
|
||||
Foo::X(0) => 1,
|
||||
Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,
|
||||
Foo::Z(_) => 1,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// Suggest moving `Foo::Z(_)` up.
|
||||
let _ = match Foo::X(0) {
|
||||
Foo::X(0) | Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm
|
||||
Foo::X(_) | Foo::Y(_) => 2,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// Suggest moving `Foo::X(0)` down.
|
||||
let _ = match Foo::X(0) {
|
||||
Foo::Y(_) | Foo::Z(0) => 2,
|
||||
Foo::Z(_) | Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// Don't lint.
|
||||
let _ = match 0 {
|
||||
-2 => 1,
|
||||
-5..=50 => 2,
|
||||
-150..=88 => 1,
|
||||
_ => 3,
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
x: u32,
|
||||
y: u32,
|
||||
z: u32,
|
||||
}
|
||||
|
||||
// Lint.
|
||||
let _ = match None {
|
||||
Some(Bar { y: 10, z: 0, .. }) => 2,
|
||||
None => 50,
|
||||
Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm
|
||||
_ => 200,
|
||||
};
|
||||
|
||||
let _ = match 0 {
|
||||
0 => todo!(),
|
||||
1 => todo!(),
|
||||
2 => core::convert::identity::<u32>(todo!()),
|
||||
3 => core::convert::identity::<u32>(todo!()),
|
||||
_ => 5,
|
||||
};
|
||||
|
||||
let _ = match 0 {
|
||||
1 | 0 => cfg!(not_enable),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312
|
||||
mod with_lifetime {
|
||||
enum MaybeStaticStr<'a> {
|
||||
Static(&'static str),
|
||||
Borrowed(&'a str),
|
||||
}
|
||||
|
||||
impl<'a> MaybeStaticStr<'a> {
|
||||
fn get(&self) -> &'a str {
|
||||
match *self {
|
||||
MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
|
||||
//~^ ERROR: this match arm has an identical body to another arm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,9 @@
|
|||
clippy::match_single_binding,
|
||||
clippy::match_like_matches_macro
|
||||
)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
fn bar<T>(_: T) {}
|
||||
fn foo() -> bool {
|
||||
unimplemented!()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this match arm has an identical body to the `_` wildcard arm
|
||||
--> tests/ui/match_same_arms2.rs:16:9
|
||||
--> tests/ui/match_same_arms2.rs:19:9
|
||||
|
|
||||
LL | / 42 => {
|
||||
LL | | foo();
|
||||
|
|
@ -12,7 +12,7 @@ LL | | _ => {
|
|||
|
|
||||
= help: or try changing either arm body
|
||||
note: `_` wildcard arm here
|
||||
--> tests/ui/match_same_arms2.rs:25:9
|
||||
--> tests/ui/match_same_arms2.rs:28:9
|
||||
|
|
||||
LL | / _ => {
|
||||
LL | | foo();
|
||||
|
|
@ -26,7 +26,7 @@ LL | | },
|
|||
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:39:9
|
||||
--> tests/ui/match_same_arms2.rs:42:9
|
||||
|
|
||||
LL | 51 => foo(),
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -42,7 +42,7 @@ LL - 42 => foo(),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:45:9
|
||||
--> tests/ui/match_same_arms2.rs:48:9
|
||||
|
|
||||
LL | None => 24,
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -58,7 +58,7 @@ LL - Some(_) => 24,
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:67:9
|
||||
--> tests/ui/match_same_arms2.rs:70:9
|
||||
|
|
||||
LL | (None, Some(a)) => bar(a),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -74,7 +74,7 @@ LL - (Some(a), None) => bar(a),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:81:9
|
||||
--> tests/ui/match_same_arms2.rs:84:9
|
||||
|
|
||||
LL | (None, Some(a)) if a == 42 => a,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -90,7 +90,7 @@ LL - (Some(a), None) if a == 42 => a,
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:86:9
|
||||
--> tests/ui/match_same_arms2.rs:89:9
|
||||
|
|
||||
LL | (Some(a), ..) => bar(a),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -106,7 +106,7 @@ LL - (.., Some(a)) => bar(a),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:120:9
|
||||
--> tests/ui/match_same_arms2.rs:123:9
|
||||
|
|
||||
LL | (Ok(x), Some(_)) => println!("ok {}", x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -122,7 +122,7 @@ LL - (Ok(_), Some(x)) => println!("ok {}", x),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:136:9
|
||||
--> tests/ui/match_same_arms2.rs:139:9
|
||||
|
|
||||
LL | Ok(_) => println!("ok"),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -138,7 +138,7 @@ LL - Ok(3) => println!("ok"),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:163:9
|
||||
--> tests/ui/match_same_arms2.rs:166:9
|
||||
|
|
||||
LL | / 1 => {
|
||||
LL | | empty!(0);
|
||||
|
|
@ -158,7 +158,7 @@ LL - },
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:214:9
|
||||
--> tests/ui/match_same_arms2.rs:217:9
|
||||
|
|
||||
LL | Foo::X(0) => 1,
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -174,7 +174,7 @@ LL - Foo::Z(_) => 1,
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:224:9
|
||||
--> tests/ui/match_same_arms2.rs:227:9
|
||||
|
|
||||
LL | Foo::Z(_) => 1,
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -190,7 +190,7 @@ LL - Foo::X(0) => 1,
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:247:9
|
||||
--> tests/ui/match_same_arms2.rs:250:9
|
||||
|
|
||||
LL | Some(Bar { y: 0, x: 5, .. }) => 1,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -206,7 +206,7 @@ LL - Some(Bar { x: 0, y: 5, .. }) => 1,
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:261:9
|
||||
--> tests/ui/match_same_arms2.rs:264:9
|
||||
|
|
||||
LL | 1 => cfg!(not_enable),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -222,7 +222,7 @@ LL - 0 => cfg!(not_enable),
|
|||
|
|
||||
|
||||
error: this match arm has an identical body to another arm
|
||||
--> tests/ui/match_same_arms2.rs:277:17
|
||||
--> tests/ui/match_same_arms2.rs:280:17
|
||||
|
|
||||
LL | MaybeStaticStr::Borrowed(s) => s,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -193,11 +193,5 @@ error: this ident consists of a single char
|
|||
LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {
|
||||
| ^
|
||||
|
||||
error: this ident consists of a single char
|
||||
--> tests/ui/min_ident_chars.rs:93:41
|
||||
|
|
||||
LL | struct Array<T, const N: usize>([T; N]);
|
||||
| ^
|
||||
|
||||
error: aborting due to 33 previous errors
|
||||
error: aborting due to 32 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ mod with_ty_alias {
|
|||
}
|
||||
// NOTE: When checking the type of a function param, make sure it is not an alias with
|
||||
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
|
||||
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
|
||||
// is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated
|
||||
// in this test.
|
||||
const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ mod with_ty_alias {
|
|||
}
|
||||
// NOTE: When checking the type of a function param, make sure it is not an alias with
|
||||
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
|
||||
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
|
||||
// is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated
|
||||
// in this test.
|
||||
fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// unimplemented!();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// With an explicit return type it should lint too
|
||||
/// ```edition2015
|
||||
/// fn main() -> () {
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
/// unimplemented!();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// This should, too.
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
/// unimplemented!();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// This one too.
|
||||
/// ```no_run
|
||||
/// // the fn is not always the first line
|
||||
|
|
|
|||
|
|
@ -52,3 +52,21 @@ struct S<'a> {
|
|||
fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
|
||||
s.opt.as_deref_mut()
|
||||
}
|
||||
|
||||
mod issue_non_copy_13077 {
|
||||
pub fn something(mut maybe_side_effect: Option<&mut String>) {
|
||||
for _ in 0..10 {
|
||||
let _ = S {
|
||||
field: other(maybe_side_effect.as_deref_mut()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn other(_maybe_side_effect: Option<&mut String>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub struct S {
|
||||
pub field: (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,3 +52,21 @@ struct S<'a> {
|
|||
fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
|
||||
s.opt.as_deref_mut()
|
||||
}
|
||||
|
||||
mod issue_non_copy_13077 {
|
||||
pub fn something(mut maybe_side_effect: Option<&mut String>) {
|
||||
for _ in 0..10 {
|
||||
let _ = S {
|
||||
field: other(maybe_side_effect.as_deref_mut()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn other(_maybe_side_effect: Option<&mut String>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub struct S {
|
||||
pub field: (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,4 +318,51 @@ fn host_effect() {
|
|||
Add::<i32>::add(1, 1).add(i32::MIN);
|
||||
}
|
||||
|
||||
mod issue_10228 {
|
||||
struct Entry;
|
||||
|
||||
impl Entry {
|
||||
fn or_insert(self, _default: i32) {}
|
||||
fn or_default(self) {
|
||||
// Don't lint, suggested code is an infinite recursion
|
||||
self.or_insert(Default::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// issue #12973
|
||||
fn fn_call_in_nested_expr() {
|
||||
struct Foo {
|
||||
val: String,
|
||||
}
|
||||
|
||||
fn f() -> i32 {
|
||||
1
|
||||
}
|
||||
let opt: Option<i32> = Some(1);
|
||||
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or_else(f); // suggest `.unwrap_or_else(f)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or_else(|| f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or_else(|| {
|
||||
let x = f();
|
||||
x + 1
|
||||
});
|
||||
//~v ERROR: use of `map_or` followed by a function call
|
||||
let _ = opt.map_or_else(|| f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` to construct default value
|
||||
let _ = opt.unwrap_or_default();
|
||||
|
||||
let opt_foo = Some(Foo {
|
||||
val: String::from("123"),
|
||||
});
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt_foo.unwrap_or_else(|| Foo { val: String::default() });
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -318,4 +318,51 @@ fn host_effect() {
|
|||
Add::<i32>::add(1, 1).add(i32::MIN);
|
||||
}
|
||||
|
||||
mod issue_10228 {
|
||||
struct Entry;
|
||||
|
||||
impl Entry {
|
||||
fn or_insert(self, _default: i32) {}
|
||||
fn or_default(self) {
|
||||
// Don't lint, suggested code is an infinite recursion
|
||||
self.or_insert(Default::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// issue #12973
|
||||
fn fn_call_in_nested_expr() {
|
||||
struct Foo {
|
||||
val: String,
|
||||
}
|
||||
|
||||
fn f() -> i32 {
|
||||
1
|
||||
}
|
||||
let opt: Option<i32> = Some(1);
|
||||
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt.unwrap_or({
|
||||
let x = f();
|
||||
x + 1
|
||||
});
|
||||
//~v ERROR: use of `map_or` followed by a function call
|
||||
let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
|
||||
//
|
||||
//~v ERROR: use of `unwrap_or` to construct default value
|
||||
let _ = opt.unwrap_or({ i32::default() });
|
||||
|
||||
let opt_foo = Some(Foo {
|
||||
val: String::from("123"),
|
||||
});
|
||||
//~v ERROR: use of `unwrap_or` followed by a function call
|
||||
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -196,5 +196,53 @@ error: use of `unwrap_or_else` to construct default value
|
|||
LL | let _ = stringy.unwrap_or_else(String::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: aborting due to 32 previous errors
|
||||
error: use of `unwrap_or` followed by a function call
|
||||
--> tests/ui/or_fun_call.rs:345:17
|
||||
|
|
||||
LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)`
|
||||
|
||||
error: use of `unwrap_or` followed by a function call
|
||||
--> tests/ui/or_fun_call.rs:348:17
|
||||
|
|
||||
LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)`
|
||||
|
||||
error: use of `unwrap_or` followed by a function call
|
||||
--> tests/ui/or_fun_call.rs:351:17
|
||||
|
|
||||
LL | let _ = opt.unwrap_or({
|
||||
| _________________^
|
||||
LL | | let x = f();
|
||||
LL | | x + 1
|
||||
LL | | });
|
||||
| |______^
|
||||
|
|
||||
help: try
|
||||
|
|
||||
LL ~ let _ = opt.unwrap_or_else(|| {
|
||||
LL + let x = f();
|
||||
LL + x + 1
|
||||
LL ~ });
|
||||
|
|
||||
|
||||
error: use of `map_or` followed by a function call
|
||||
--> tests/ui/or_fun_call.rs:356:17
|
||||
|
|
||||
LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)`
|
||||
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> tests/ui/or_fun_call.rs:359:17
|
||||
|
|
||||
LL | let _ = opt.unwrap_or({ i32::default() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a function call
|
||||
--> tests/ui/or_fun_call.rs:365:21
|
||||
|
|
||||
LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`
|
||||
|
||||
error: aborting due to 38 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
#[warn(clippy::all, clippy::path_buf_push_overwrite)]
|
||||
#[warn(clippy::path_buf_push_overwrite)]
|
||||
#[allow(clippy::pathbuf_init_then_push)]
|
||||
fn main() {
|
||||
let mut x = PathBuf::from("/foo");
|
||||
x.push("bar");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
#[warn(clippy::all, clippy::path_buf_push_overwrite)]
|
||||
#[warn(clippy::path_buf_push_overwrite)]
|
||||
#[allow(clippy::pathbuf_init_then_push)]
|
||||
fn main() {
|
||||
let mut x = PathBuf::from("/foo");
|
||||
x.push("/bar");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: calling `push` with '/' or '\' (file system root) will overwrite the previous path definition
|
||||
--> tests/ui/path_buf_push_overwrite.rs:6:12
|
||||
--> tests/ui/path_buf_push_overwrite.rs:7:12
|
||||
|
|
||||
LL | x.push("/bar");
|
||||
| ^^^^^^ help: try: `"bar"`
|
||||
|
|
|
|||
22
tests/ui/pathbuf_init_then_push.fixed
Normal file
22
tests/ui/pathbuf_init_then_push.fixed
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#![warn(clippy::pathbuf_init_then_push)]
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut path_buf = PathBuf::from("foo");
|
||||
|
||||
path_buf = PathBuf::from("foo").join("bar");
|
||||
|
||||
let bar = "bar";
|
||||
path_buf = PathBuf::from("foo").join(bar);
|
||||
|
||||
let mut path_buf = PathBuf::from("foo").join("bar").join("buz");
|
||||
|
||||
let mut x = PathBuf::new();
|
||||
println!("{}", x.display());
|
||||
x.push("Duck");
|
||||
|
||||
let mut path_buf = PathBuf::new();
|
||||
#[cfg(cats)]
|
||||
path_buf.push("foo");
|
||||
}
|
||||
26
tests/ui/pathbuf_init_then_push.rs
Normal file
26
tests/ui/pathbuf_init_then_push.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#![warn(clippy::pathbuf_init_then_push)]
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut path_buf = PathBuf::new(); //~ ERROR: calls to `push` immediately after creation
|
||||
path_buf.push("foo");
|
||||
|
||||
path_buf = PathBuf::from("foo"); //~ ERROR: calls to `push` immediately after creation
|
||||
path_buf.push("bar");
|
||||
|
||||
let bar = "bar";
|
||||
path_buf = PathBuf::from("foo"); //~ ERROR: calls to `push` immediately after creation
|
||||
path_buf.push(bar);
|
||||
|
||||
let mut path_buf = PathBuf::from("foo").join("bar"); //~ ERROR: calls to `push` immediately after creation
|
||||
path_buf.push("buz");
|
||||
|
||||
let mut x = PathBuf::new();
|
||||
println!("{}", x.display());
|
||||
x.push("Duck");
|
||||
|
||||
let mut path_buf = PathBuf::new();
|
||||
#[cfg(cats)]
|
||||
path_buf.push("foo");
|
||||
}
|
||||
33
tests/ui/pathbuf_init_then_push.stderr
Normal file
33
tests/ui/pathbuf_init_then_push.stderr
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
error: calls to `push` immediately after creation
|
||||
--> tests/ui/pathbuf_init_then_push.rs:6:5
|
||||
|
|
||||
LL | / let mut path_buf = PathBuf::new();
|
||||
LL | | path_buf.push("foo");
|
||||
| |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo");`
|
||||
|
|
||||
= note: `-D clippy::pathbuf-init-then-push` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::pathbuf_init_then_push)]`
|
||||
|
||||
error: calls to `push` immediately after creation
|
||||
--> tests/ui/pathbuf_init_then_push.rs:9:5
|
||||
|
|
||||
LL | / path_buf = PathBuf::from("foo");
|
||||
LL | | path_buf.push("bar");
|
||||
| |_________________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join("bar");`
|
||||
|
||||
error: calls to `push` immediately after creation
|
||||
--> tests/ui/pathbuf_init_then_push.rs:13:5
|
||||
|
|
||||
LL | / path_buf = PathBuf::from("foo");
|
||||
LL | | path_buf.push(bar);
|
||||
| |_______________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join(bar);`
|
||||
|
||||
error: calls to `push` immediately after creation
|
||||
--> tests/ui/pathbuf_init_then_push.rs:16:5
|
||||
|
|
||||
LL | / let mut path_buf = PathBuf::from("foo").join("bar");
|
||||
LL | | path_buf.push("buz");
|
||||
| |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo").join("bar").join("buz");`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
@ -46,6 +46,10 @@ fn main() {
|
|||
let _ = external!($ptr as *const u32);
|
||||
}
|
||||
|
||||
fn lifetime_to_static(v: *mut &()) -> *const &'static () {
|
||||
v as _
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.64"]
|
||||
fn _msrv_1_64() {
|
||||
let ptr: *const u32 = &42_u32;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@ fn main() {
|
|||
let _ = external!($ptr as *const u32);
|
||||
}
|
||||
|
||||
fn lifetime_to_static(v: *mut &()) -> *const &'static () {
|
||||
v as _
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.64"]
|
||||
fn _msrv_1_64() {
|
||||
let ptr: *const u32 = &42_u32;
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ LL | let _ = mut_ptr as *const u32;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
|
||||
|
||||
error: `as` casting between raw pointers while changing only its constness
|
||||
--> tests/ui/ptr_cast_constness.rs:64:13
|
||||
--> tests/ui/ptr_cast_constness.rs:68:13
|
||||
|
|
||||
LL | let _ = ptr as *mut u32;
|
||||
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
|
||||
|
||||
error: `as` casting between raw pointers while changing only its constness
|
||||
--> tests/ui/ptr_cast_constness.rs:65:13
|
||||
--> tests/ui/ptr_cast_constness.rs:69:13
|
||||
|
|
||||
LL | let _ = mut_ptr as *const u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#![allow(
|
||||
clippy::drop_non_drop,
|
||||
clippy::implicit_clone,
|
||||
clippy::pathbuf_init_then_push,
|
||||
clippy::uninlined_format_args,
|
||||
clippy::unnecessary_literal_unwrap
|
||||
)]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#![allow(
|
||||
clippy::drop_non_drop,
|
||||
clippy::implicit_clone,
|
||||
clippy::pathbuf_init_then_push,
|
||||
clippy::uninlined_format_args,
|
||||
clippy::unnecessary_literal_unwrap
|
||||
)]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:14:42
|
||||
--> tests/ui/redundant_clone.rs:15:42
|
||||
|
|
||||
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
|
||||
| ^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:14:14
|
||||
--> tests/ui/redundant_clone.rs:15:14
|
||||
|
|
||||
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -13,169 +13,169 @@ LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
|
|||
= help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:17:15
|
||||
--> tests/ui/redundant_clone.rs:18:15
|
||||
|
|
||||
LL | let _s = s.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:17:14
|
||||
--> tests/ui/redundant_clone.rs:18:14
|
||||
|
|
||||
LL | let _s = s.clone();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:20:15
|
||||
--> tests/ui/redundant_clone.rs:21:15
|
||||
|
|
||||
LL | let _s = s.to_string();
|
||||
| ^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:20:14
|
||||
--> tests/ui/redundant_clone.rs:21:14
|
||||
|
|
||||
LL | let _s = s.to_string();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:23:15
|
||||
--> tests/ui/redundant_clone.rs:24:15
|
||||
|
|
||||
LL | let _s = s.to_owned();
|
||||
| ^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:23:14
|
||||
--> tests/ui/redundant_clone.rs:24:14
|
||||
|
|
||||
LL | let _s = s.to_owned();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:25:42
|
||||
--> tests/ui/redundant_clone.rs:26:42
|
||||
|
|
||||
LL | let _s = Path::new("/a/b/").join("c").to_owned();
|
||||
| ^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:25:14
|
||||
--> tests/ui/redundant_clone.rs:26:14
|
||||
|
|
||||
LL | let _s = Path::new("/a/b/").join("c").to_owned();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:27:42
|
||||
--> tests/ui/redundant_clone.rs:28:42
|
||||
|
|
||||
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
|
||||
| ^^^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:27:14
|
||||
--> tests/ui/redundant_clone.rs:28:14
|
||||
|
|
||||
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:29:29
|
||||
--> tests/ui/redundant_clone.rs:30:29
|
||||
|
|
||||
LL | let _s = OsString::new().to_owned();
|
||||
| ^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:29:14
|
||||
--> tests/ui/redundant_clone.rs:30:14
|
||||
|
|
||||
LL | let _s = OsString::new().to_owned();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:31:29
|
||||
--> tests/ui/redundant_clone.rs:32:29
|
||||
|
|
||||
LL | let _s = OsString::new().to_os_string();
|
||||
| ^^^^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:31:14
|
||||
--> tests/ui/redundant_clone.rs:32:14
|
||||
|
|
||||
LL | let _s = OsString::new().to_os_string();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:42:19
|
||||
--> tests/ui/redundant_clone.rs:43:19
|
||||
|
|
||||
LL | let _t = tup.0.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:42:14
|
||||
--> tests/ui/redundant_clone.rs:43:14
|
||||
|
|
||||
LL | let _t = tup.0.clone();
|
||||
| ^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:74:25
|
||||
--> tests/ui/redundant_clone.rs:75:25
|
||||
|
|
||||
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:74:24
|
||||
--> tests/ui/redundant_clone.rs:75:24
|
||||
|
|
||||
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:131:15
|
||||
|
|
||||
LL | let _s = s.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:131:14
|
||||
|
|
||||
LL | let _s = s.clone();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:132:15
|
||||
|
|
||||
LL | let _t = t.clone();
|
||||
LL | let _s = s.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:132:14
|
||||
|
|
||||
LL | let _s = s.clone();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:133:15
|
||||
|
|
||||
LL | let _t = t.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:133:14
|
||||
|
|
||||
LL | let _t = t.clone();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:142:19
|
||||
--> tests/ui/redundant_clone.rs:143:19
|
||||
|
|
||||
LL | let _f = f.clone();
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:142:18
|
||||
--> tests/ui/redundant_clone.rs:143:18
|
||||
|
|
||||
LL | let _f = f.clone();
|
||||
| ^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:154:14
|
||||
--> tests/ui/redundant_clone.rs:155:14
|
||||
|
|
||||
LL | let y = x.clone().join("matthias");
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: cloned value is neither consumed nor mutated
|
||||
--> tests/ui/redundant_clone.rs:154:13
|
||||
--> tests/ui/redundant_clone.rs:155:13
|
||||
|
|
||||
LL | let y = x.clone().join("matthias");
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/redundant_clone.rs:208:11
|
||||
--> tests/ui/redundant_clone.rs:209:11
|
||||
|
|
||||
LL | foo(&x.clone(), move || {
|
||||
| ^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/redundant_clone.rs:208:10
|
||||
--> tests/ui/redundant_clone.rs:209:10
|
||||
|
|
||||
LL | foo(&x.clone(), move || {
|
||||
| ^
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
#![warn(clippy::significant_drop_tightening)]
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub fn complex_return_triggers_the_lint() -> i32 {
|
||||
fn foo() -> i32 {
|
||||
1
|
||||
}
|
||||
let mutex = Mutex::new(1);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = *lock;
|
||||
let _ = *lock;
|
||||
drop(lock);
|
||||
foo()
|
||||
}
|
||||
|
||||
pub fn issue_10413() {
|
||||
let mutex = Mutex::new(Some(1));
|
||||
let opt = Some(1);
|
||||
if opt.is_some() {
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = *lock;
|
||||
if opt.is_some() {
|
||||
let _ = *lock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn issue_11128() {
|
||||
use std::mem::drop as unlock;
|
||||
|
||||
struct Foo {
|
||||
droppable: Option<Vec<i32>>,
|
||||
mutex: Mutex<Vec<i32>>,
|
||||
}
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&mut self) {
|
||||
if let Some(droppable) = self.droppable.take() {
|
||||
let lock = self.mutex.lock().unwrap();
|
||||
let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first());
|
||||
if let Some(idx) = idx_opt {
|
||||
let local_droppable = vec![lock.first().copied().unwrap_or_default()];
|
||||
unlock(lock);
|
||||
drop(local_droppable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn issue_11160() -> bool {
|
||||
let mutex = Mutex::new(1i32);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = lock.abs();
|
||||
true
|
||||
}
|
||||
|
||||
pub fn issue_11189() {
|
||||
struct Number {
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
fn do_something() -> Result<(), ()> {
|
||||
let number = Mutex::new(Number { value: 1 });
|
||||
let number2 = Mutex::new(Number { value: 2 });
|
||||
let number3 = Mutex::new(Number { value: 3 });
|
||||
let mut lock = number.lock().unwrap();
|
||||
let mut lock2 = number2.lock().unwrap();
|
||||
let mut lock3 = number3.lock().unwrap();
|
||||
lock.value += 1;
|
||||
lock2.value += 1;
|
||||
lock3.value += 1;
|
||||
drop((lock, lock2, lock3));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path_return_can_be_ignored() -> i32 {
|
||||
let mutex = Mutex::new(1);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let rslt = *lock;
|
||||
let _ = *lock;
|
||||
rslt
|
||||
}
|
||||
|
||||
pub fn post_bindings_can_be_ignored() {
|
||||
let mutex = Mutex::new(1);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let rslt = *lock;
|
||||
let another = rslt;
|
||||
let _ = another;
|
||||
}
|
||||
|
||||
pub fn unnecessary_contention_with_multiple_owned_results() {
|
||||
{
|
||||
let mutex = Mutex::new(1i32);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = lock.abs();
|
||||
let _ = lock.is_positive();
|
||||
}
|
||||
|
||||
{
|
||||
let mutex = Mutex::new(1i32);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let rslt0 = lock.abs();
|
||||
let rslt1 = lock.is_positive();
|
||||
drop(lock);
|
||||
do_heavy_computation_that_takes_time((rslt0, rslt1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unnecessary_contention_with_single_owned_results() {
|
||||
{
|
||||
let mutex = Mutex::new(1i32);
|
||||
let lock = mutex.lock().unwrap();
|
||||
let _ = lock.abs();
|
||||
}
|
||||
{
|
||||
let mutex = Mutex::new(vec![1i32]);
|
||||
let mut lock = mutex.lock().unwrap();
|
||||
lock.clear();
|
||||
}
|
||||
|
||||
{
|
||||
let mutex = Mutex::new(1i32);
|
||||
|
||||
let rslt0 = mutex.lock().unwrap().abs();
|
||||
|
||||
do_heavy_computation_that_takes_time(rslt0);
|
||||
}
|
||||
{
|
||||
let mutex = Mutex::new(vec![1i32]);
|
||||
|
||||
mutex.lock().unwrap().clear();
|
||||
|
||||
do_heavy_computation_that_takes_time(());
|
||||
}
|
||||
}
|
||||
|
||||
// Marker used for illustration purposes.
|
||||
pub fn do_heavy_computation_that_takes_time<T>(_: T) {}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#![warn(clippy::significant_drop_tightening)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub fn complex_return_triggers_the_lint() -> i32 {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:10:9
|
||||
--> tests/ui/significant_drop_tightening.rs:12:9
|
||||
|
|
||||
LL | pub fn complex_return_triggers_the_lint() -> i32 {
|
||||
| __________________________________________________-
|
||||
|
|
@ -24,7 +24,7 @@ LL + drop(lock);
|
|||
|
|
||||
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:104:13
|
||||
--> tests/ui/significant_drop_tightening.rs:106:13
|
||||
|
|
||||
LL | / {
|
||||
LL | | let mutex = Mutex::new(1i32);
|
||||
|
|
@ -44,7 +44,7 @@ LL + drop(lock);
|
|||
|
|
||||
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:125:13
|
||||
--> tests/ui/significant_drop_tightening.rs:127:13
|
||||
|
|
||||
LL | / {
|
||||
LL | | let mutex = Mutex::new(1i32);
|
||||
|
|
@ -67,7 +67,7 @@ LL - let rslt0 = lock.abs();
|
|||
|
|
||||
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:131:17
|
||||
--> tests/ui/significant_drop_tightening.rs:133:17
|
||||
|
|
||||
LL | / {
|
||||
LL | | let mutex = Mutex::new(vec![1i32]);
|
||||
|
|
|
|||
|
|
@ -57,4 +57,12 @@ fn main() {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Should lint with correct suggestion (issue #12782)
|
||||
let res_void: Result<bool, bool> = Ok(true);
|
||||
|
||||
{
|
||||
let (Ok(mut _x) | Err(mut _x)) = res_void;
|
||||
let ptr: *const bool = std::ptr::null();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,4 +54,11 @@ fn main() {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Should lint with correct suggestion (issue #12782)
|
||||
let res_void: Result<bool, bool> = Ok(true);
|
||||
|
||||
for (Ok(mut _x) | Err(mut _x)) in [res_void] {
|
||||
let ptr: *const bool = std::ptr::null();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,5 +83,21 @@ LL + };
|
|||
LL + }
|
||||
|
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: for loop over a single element
|
||||
--> tests/ui/single_element_loop.rs:61:5
|
||||
|
|
||||
LL | / for (Ok(mut _x) | Err(mut _x)) in [res_void] {
|
||||
LL | | let ptr: *const bool = std::ptr::null();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try
|
||||
|
|
||||
LL ~ {
|
||||
LL + let (Ok(mut _x) | Err(mut _x)) = res_void;
|
||||
LL + let ptr: *const bool = std::ptr::null();
|
||||
LL + }
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::temporary_assignment)]
|
||||
#![allow(const_item_mutation)]
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: assignment to temporary
|
||||
--> tests/ui/temporary_assignment.rs:48:5
|
||||
--> tests/ui/temporary_assignment.rs:47:5
|
||||
|
|
||||
LL | Struct { field: 0 }.field = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -8,7 +8,7 @@ LL | Struct { field: 0 }.field = 1;
|
|||
= help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]`
|
||||
|
||||
error: assignment to temporary
|
||||
--> tests/ui/temporary_assignment.rs:51:5
|
||||
--> tests/ui/temporary_assignment.rs:50:5
|
||||
|
|
||||
LL | / MultiStruct {
|
||||
LL | |
|
||||
|
|
@ -19,13 +19,13 @@ LL | | .field = 1;
|
|||
| |______________^
|
||||
|
||||
error: assignment to temporary
|
||||
--> tests/ui/temporary_assignment.rs:57:5
|
||||
--> tests/ui/temporary_assignment.rs:56:5
|
||||
|
|
||||
LL | ArrayStruct { array: [0] }.array[0] = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assignment to temporary
|
||||
--> tests/ui/temporary_assignment.rs:59:5
|
||||
--> tests/ui/temporary_assignment.rs:58:5
|
||||
|
|
||||
LL | (0, 0).0 = 1;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
|
|||
8
tests/ui/to_string_in_format_args_incremental.fixed
Normal file
8
tests/ui/to_string_in_format_args_incremental.fixed
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//@compile-flags: -C incremental=target/debug/test/incr
|
||||
|
||||
// see https://github.com/rust-lang/rust-clippy/issues/10969
|
||||
|
||||
fn main() {
|
||||
let s = "Hello, world!";
|
||||
println!("{}", s);
|
||||
}
|
||||
8
tests/ui/to_string_in_format_args_incremental.rs
Normal file
8
tests/ui/to_string_in_format_args_incremental.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//@compile-flags: -C incremental=target/debug/test/incr
|
||||
|
||||
// see https://github.com/rust-lang/rust-clippy/issues/10969
|
||||
|
||||
fn main() {
|
||||
let s = "Hello, world!";
|
||||
println!("{}", s.to_string());
|
||||
}
|
||||
11
tests/ui/to_string_in_format_args_incremental.stderr
Normal file
11
tests/ui/to_string_in_format_args_incremental.stderr
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
error: `to_string` applied to a type that implements `Display` in `println!` args
|
||||
--> tests/ui/to_string_in_format_args_incremental.rs:7:21
|
||||
|
|
||||
LL | println!("{}", s.to_string());
|
||||
| ^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -36,4 +36,6 @@ fn main() {
|
|||
|
||||
// do not lint in external macro
|
||||
external!(let ref _y = 42;);
|
||||
|
||||
fn f(#[allow(clippy::toplevel_ref_arg)] ref x: i32) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,6 @@ fn main() {
|
|||
|
||||
// do not lint in external macro
|
||||
external!(let ref _y = 42;);
|
||||
|
||||
fn f(#[allow(clippy::toplevel_ref_arg)] ref x: i32) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
#![warn(clippy::transmute_ptr_to_ptr)]
|
||||
#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
// Make sure we can modify lifetimes, which is one of the recommended uses
|
||||
// of transmute
|
||||
|
||||
// Make sure we can do static lifetime transmutes
|
||||
unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
|
||||
std::mem::transmute::<&'a T, &'static T>(t)
|
||||
transmute::<&'a T, &'static T>(t)
|
||||
}
|
||||
|
||||
// Make sure we can do non-static lifetime transmutes
|
||||
unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
|
||||
std::mem::transmute::<&'a T, &'b T>(t)
|
||||
transmute::<&'a T, &'b T>(t)
|
||||
}
|
||||
|
||||
struct LifetimeParam<'a> {
|
||||
|
|
@ -27,39 +29,40 @@ fn transmute_ptr_to_ptr() {
|
|||
let mut_ptr = &mut 1u32 as *mut u32;
|
||||
unsafe {
|
||||
// pointer-to-pointer transmutes; bad
|
||||
let _: *const f32 = ptr as *const f32;
|
||||
//~^ ERROR: transmute from a pointer to a pointer
|
||||
//~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
|
||||
let _: *mut f32 = mut_ptr as *mut f32;
|
||||
//~^ ERROR: transmute from a pointer to a pointer
|
||||
let _: *const f32 = ptr.cast::<f32>();
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *mut f32 = mut_ptr.cast::<f32>();
|
||||
//~^ transmute_ptr_to_ptr
|
||||
// ref-ref transmutes; bad
|
||||
let _: &f32 = &*(&1u32 as *const u32 as *const f32);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: &f32 = &*(&1f64 as *const f64 as *const f32);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
//~^ transmute_ptr_to_ptr
|
||||
//:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
|
||||
// the same type
|
||||
let _: &mut f32 = &mut *(&mut 1u32 as *mut u32 as *mut f32);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: &GenericParam<f32> = &*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let u64_ref: &u64 = &0u64;
|
||||
let u8_ref: &u8 = unsafe { &*(u64_ref as *const u64 as *const u8) };
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let u8_ref: &u8 = &*(u64_ref as *const u64 as *const u8);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *const u32 = mut_ptr.cast_const();
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *mut u32 = ptr.cast_mut();
|
||||
//~^ transmute_ptr_to_ptr
|
||||
}
|
||||
|
||||
// these are recommendations for solving the above; if these lint we need to update
|
||||
// those suggestions
|
||||
let _ = ptr as *const f32;
|
||||
let _ = mut_ptr as *mut f32;
|
||||
let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
|
||||
let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
|
||||
|
||||
// transmute internal lifetimes, should not lint
|
||||
let s = "hello world".to_owned();
|
||||
let lp = LifetimeParam { s: &s };
|
||||
let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
|
||||
let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
|
||||
let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };
|
||||
let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };
|
||||
}
|
||||
|
||||
fn lifetime_to_static(v: *mut &()) -> *const &'static () {
|
||||
unsafe { v as *const &() }
|
||||
//~^ transmute_ptr_to_ptr
|
||||
}
|
||||
|
||||
// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
|
||||
|
|
@ -67,7 +70,37 @@ const _: &() = {
|
|||
struct Zst;
|
||||
let zst = &Zst;
|
||||
|
||||
unsafe { std::mem::transmute::<&'static Zst, &'static ()>(zst) }
|
||||
unsafe { transmute::<&'static Zst, &'static ()>(zst) }
|
||||
};
|
||||
|
||||
#[clippy::msrv = "1.37"]
|
||||
fn msrv_1_37(ptr: *const u8) {
|
||||
unsafe {
|
||||
let _: *const i8 = ptr as *const i8;
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.38"]
|
||||
fn msrv_1_38(ptr: *const u8) {
|
||||
unsafe {
|
||||
let _: *const i8 = ptr.cast::<i8>();
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.64"]
|
||||
fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {
|
||||
unsafe {
|
||||
let _: *mut u8 = ptr as *mut u8;
|
||||
let _: *const u8 = mut_ptr as *const u8;
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.65"]
|
||||
fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
|
||||
unsafe {
|
||||
let _: *mut u8 = ptr.cast_mut();
|
||||
let _: *const u8 = mut_ptr.cast_const();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
#![warn(clippy::transmute_ptr_to_ptr)]
|
||||
#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
// Make sure we can modify lifetimes, which is one of the recommended uses
|
||||
// of transmute
|
||||
|
||||
// Make sure we can do static lifetime transmutes
|
||||
unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
|
||||
std::mem::transmute::<&'a T, &'static T>(t)
|
||||
transmute::<&'a T, &'static T>(t)
|
||||
}
|
||||
|
||||
// Make sure we can do non-static lifetime transmutes
|
||||
unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
|
||||
std::mem::transmute::<&'a T, &'b T>(t)
|
||||
transmute::<&'a T, &'b T>(t)
|
||||
}
|
||||
|
||||
struct LifetimeParam<'a> {
|
||||
|
|
@ -27,39 +29,40 @@ fn transmute_ptr_to_ptr() {
|
|||
let mut_ptr = &mut 1u32 as *mut u32;
|
||||
unsafe {
|
||||
// pointer-to-pointer transmutes; bad
|
||||
let _: *const f32 = std::mem::transmute(ptr);
|
||||
//~^ ERROR: transmute from a pointer to a pointer
|
||||
//~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
|
||||
let _: *mut f32 = std::mem::transmute(mut_ptr);
|
||||
//~^ ERROR: transmute from a pointer to a pointer
|
||||
let _: *const f32 = transmute(ptr);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *mut f32 = transmute(mut_ptr);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
// ref-ref transmutes; bad
|
||||
let _: &f32 = std::mem::transmute(&1u32);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let _: &f32 = std::mem::transmute(&1f64);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let _: &f32 = transmute(&1u32);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: &f32 = transmute(&1f64);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
//:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
|
||||
// the same type
|
||||
let _: &mut f32 = std::mem::transmute(&mut 1u32);
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let _: &mut f32 = transmute(&mut 1u32);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let u64_ref: &u64 = &0u64;
|
||||
let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) };
|
||||
//~^ ERROR: transmute from a reference to a reference
|
||||
let u8_ref: &u8 = transmute(u64_ref);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *const u32 = transmute(mut_ptr);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
let _: *mut u32 = transmute(ptr);
|
||||
//~^ transmute_ptr_to_ptr
|
||||
}
|
||||
|
||||
// these are recommendations for solving the above; if these lint we need to update
|
||||
// those suggestions
|
||||
let _ = ptr as *const f32;
|
||||
let _ = mut_ptr as *mut f32;
|
||||
let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
|
||||
let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
|
||||
|
||||
// transmute internal lifetimes, should not lint
|
||||
let s = "hello world".to_owned();
|
||||
let lp = LifetimeParam { s: &s };
|
||||
let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
|
||||
let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
|
||||
let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };
|
||||
let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };
|
||||
}
|
||||
|
||||
fn lifetime_to_static(v: *mut &()) -> *const &'static () {
|
||||
unsafe { transmute(v) }
|
||||
//~^ transmute_ptr_to_ptr
|
||||
}
|
||||
|
||||
// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
|
||||
|
|
@ -67,7 +70,37 @@ const _: &() = {
|
|||
struct Zst;
|
||||
let zst = &Zst;
|
||||
|
||||
unsafe { std::mem::transmute::<&'static Zst, &'static ()>(zst) }
|
||||
unsafe { transmute::<&'static Zst, &'static ()>(zst) }
|
||||
};
|
||||
|
||||
#[clippy::msrv = "1.37"]
|
||||
fn msrv_1_37(ptr: *const u8) {
|
||||
unsafe {
|
||||
let _: *const i8 = transmute(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.38"]
|
||||
fn msrv_1_38(ptr: *const u8) {
|
||||
unsafe {
|
||||
let _: *const i8 = transmute(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.64"]
|
||||
fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {
|
||||
unsafe {
|
||||
let _: *mut u8 = transmute(ptr);
|
||||
let _: *const u8 = transmute(mut_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.65"]
|
||||
fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
|
||||
unsafe {
|
||||
let _: *mut u8 = transmute(ptr);
|
||||
let _: *const u8 = transmute(mut_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,47 +1,155 @@
|
|||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:30:29
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:32:29
|
||||
|
|
||||
LL | let _: *const f32 = std::mem::transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr as *const f32`
|
||||
LL | let _: *const f32 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
|
||||
help: use `pointer::cast` instead
|
||||
|
|
||||
LL | let _: *const f32 = ptr.cast::<f32>();
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:33:27
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:34:27
|
||||
|
|
||||
LL | let _: *mut f32 = std::mem::transmute(mut_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `mut_ptr as *mut f32`
|
||||
LL | let _: *mut f32 = transmute(mut_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast` instead
|
||||
|
|
||||
LL | let _: *mut f32 = mut_ptr.cast::<f32>();
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a reference to a reference
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:36:23
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:37:23
|
||||
|
|
||||
LL | let _: &f32 = std::mem::transmute(&1u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`
|
||||
LL | let _: &f32 = transmute(&1u32);
|
||||
| ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`
|
||||
|
||||
error: transmute from a reference to a reference
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:38:23
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:39:23
|
||||
|
|
||||
LL | let _: &f32 = std::mem::transmute(&1f64);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`
|
||||
LL | let _: &f32 = transmute(&1f64);
|
||||
| ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`
|
||||
|
||||
error: transmute from a reference to a reference
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:42:27
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:43:27
|
||||
|
|
||||
LL | let _: &mut f32 = std::mem::transmute(&mut 1u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`
|
||||
LL | let _: &mut f32 = transmute(&mut 1u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`
|
||||
|
||||
error: transmute from a reference to a reference
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:44:37
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:45:37
|
||||
|
|
||||
LL | let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`
|
||||
LL | let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`
|
||||
|
||||
error: transmute from a reference to a reference
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:47:36
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:48:27
|
||||
|
|
||||
LL | let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`
|
||||
LL | let u8_ref: &u8 = transmute(u64_ref);
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:50:29
|
||||
|
|
||||
LL | let _: *const u32 = transmute(mut_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast_const` instead
|
||||
|
|
||||
LL | let _: *const u32 = mut_ptr.cast_const();
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:52:27
|
||||
|
|
||||
LL | let _: *mut u32 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast_mut` instead
|
||||
|
|
||||
LL | let _: *mut u32 = ptr.cast_mut();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:64:14
|
||||
|
|
||||
LL | unsafe { transmute(v) }
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: use an `as` cast instead
|
||||
|
|
||||
LL | unsafe { v as *const &() }
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:79:28
|
||||
|
|
||||
LL | let _: *const i8 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use an `as` cast instead
|
||||
|
|
||||
LL | let _: *const i8 = ptr as *const i8;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:86:28
|
||||
|
|
||||
LL | let _: *const i8 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast` instead
|
||||
|
|
||||
LL | let _: *const i8 = ptr.cast::<i8>();
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:93:26
|
||||
|
|
||||
LL | let _: *mut u8 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use an `as` cast instead
|
||||
|
|
||||
LL | let _: *mut u8 = ptr as *mut u8;
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:94:28
|
||||
|
|
||||
LL | let _: *const u8 = transmute(mut_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use an `as` cast instead
|
||||
|
|
||||
LL | let _: *const u8 = mut_ptr as *const u8;
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:101:26
|
||||
|
|
||||
LL | let _: *mut u8 = transmute(ptr);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast_mut` instead
|
||||
|
|
||||
LL | let _: *mut u8 = ptr.cast_mut();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmute_ptr_to_ptr.rs:102:28
|
||||
|
|
||||
LL | let _: *const u8 = transmute(mut_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use `pointer::cast_const` instead
|
||||
|
|
||||
LL | let _: *const u8 = mut_ptr.cast_const();
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fn main() {
|
|||
let ptr_i32 = usize::MAX as *const i32;
|
||||
|
||||
// e has type *T, U is *U_0, and either U_0: Sized ...
|
||||
let _ptr_i8_transmute = unsafe { ptr_i32 as *const i8 };
|
||||
let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
|
||||
let _ptr_i8 = ptr_i32 as *const i8;
|
||||
|
||||
let slice_ptr = &[0, 1, 2, 3] as *const [i32];
|
||||
|
|
|
|||
|
|
@ -11,16 +11,25 @@ error: transmute from a pointer to a pointer
|
|||
--> tests/ui/transmutes_expressible_as_ptr_casts.rs:21:38
|
||||
|
|
||||
LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as *const i8`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
|
||||
help: use `pointer::cast` instead
|
||||
|
|
||||
LL | let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from a pointer to a pointer
|
||||
--> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46
|
||||
|
|
||||
LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice_ptr as *const [u32]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use an `as` cast instead
|
||||
|
|
||||
LL | let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead
|
||||
--> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
#![allow(dead_code, unused_variables)]
|
||||
#![warn(clippy::cast_lossless)]
|
||||
|
||||
// should not warn on lossy casting in constant types
|
||||
// because not supported yet
|
||||
const C: i32 = 42;
|
||||
const C_I64: i64 = C as i64;
|
||||
|
||||
fn main() {
|
||||
// should suggest i64::from(c)
|
||||
let c: i32 = 42;
|
||||
let c_i64: i64 = i64::from(c);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#![allow(dead_code, unused_variables)]
|
||||
#![warn(clippy::cast_lossless)]
|
||||
|
||||
// should not warn on lossy casting in constant types
|
||||
// because not supported yet
|
||||
const C: i32 = 42;
|
||||
const C_I64: i64 = C as i64;
|
||||
|
||||
fn main() {
|
||||
// should suggest i64::from(c)
|
||||
let c: i32 = 42;
|
||||
let c_i64: i64 = c as i64;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
error: casting `i32` to `i64` may become silently lossy if you later change the type
|
||||
--> tests/ui/types.rs:12:22
|
||||
|
|
||||
LL | let c_i64: i64 = c as i64;
|
||||
| ^^^^^^^^ help: try: `i64::from(c)`
|
||||
|
|
||||
= note: `-D clippy::cast-lossless` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
#![allow(unused_assignments)]
|
||||
#![warn(clippy::unnecessary_to_owned)]
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Copy)]
|
||||
enum FileType {
|
||||
Account,
|
||||
PrivateKey,
|
||||
Certificate,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let path = std::path::Path::new("x");
|
||||
|
||||
let _ = check_files(&[(FileType::Account, path)]);
|
||||
let _ = check_files_vec(vec![(FileType::Account, path)]);
|
||||
|
||||
// negative tests
|
||||
let _ = check_files_ref(&[(FileType::Account, path)]);
|
||||
let _ = check_files_mut(&[(FileType::Account, path)]);
|
||||
let _ = check_files_ref_mut(&[(FileType::Account, path)]);
|
||||
let _ = check_files_self_and_arg(&[(FileType::Account, path)]);
|
||||
let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]);
|
||||
|
||||
check_mut_iteratee_and_modify_inner_variable();
|
||||
}
|
||||
|
||||
// `check_files` and its variants are based on:
|
||||
// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
|
||||
fn check_files(files: &[(FileType, &std::path::Path)]) -> bool {
|
||||
for (t, path) in files {
|
||||
let other = match get_file_path(t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool {
|
||||
for (t, path) in files.iter() {
|
||||
let other = match get_file_path(t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool {
|
||||
for (ref t, path) in files.iter().copied() {
|
||||
let other = match get_file_path(t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
fn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool {
|
||||
for (mut t, path) in files.iter().copied() {
|
||||
t = FileType::PrivateKey;
|
||||
let other = match get_file_path(&t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool {
|
||||
for (ref mut t, path) in files.iter().copied() {
|
||||
*t = FileType::PrivateKey;
|
||||
let other = match get_file_path(t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool {
|
||||
for (t, path) in files.iter().copied() {
|
||||
let other = match get_file_path(&t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.join(path).is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
fn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool {
|
||||
for (mut t, path) in files.iter().cloned() {
|
||||
t = FileType::PrivateKey;
|
||||
let other = match get_file_path(&t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() || !other.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
|
||||
Ok(std::path::PathBuf::new())
|
||||
}
|
||||
|
||||
// Issue 12098
|
||||
// https://github.com/rust-lang/rust-clippy/issues/12098
|
||||
// no message emits
|
||||
fn check_mut_iteratee_and_modify_inner_variable() {
|
||||
struct Test {
|
||||
list: Vec<String>,
|
||||
mut_this: bool,
|
||||
}
|
||||
|
||||
impl Test {
|
||||
fn list(&self) -> &[String] {
|
||||
&self.list
|
||||
}
|
||||
}
|
||||
|
||||
let mut test = Test {
|
||||
list: vec![String::from("foo"), String::from("bar")],
|
||||
mut_this: false,
|
||||
};
|
||||
|
||||
for _item in test.list().to_vec() {
|
||||
println!("{}", _item);
|
||||
|
||||
test.mut_this = true;
|
||||
{
|
||||
test.mut_this = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_12821 {
|
||||
fn foo() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
println!("{c}"); // should not suggest to remove `&`
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
let v: Vec<_> = "hello".chars().collect();
|
||||
for c in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = c; //~ HELP: remove any references to the binding
|
||||
println!("{ref_c}");
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
let v: Vec<_> = "hello".chars().enumerate().collect();
|
||||
for (i, c) in v.iter() {
|
||||
//~^ ERROR: unnecessary use of `cloned`
|
||||
let ref_c = c; //~ HELP: remove any references to the binding
|
||||
let ref_i = i;
|
||||
println!("{i} {ref_c}"); // should not suggest to remove `&` from `i`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![allow(unused_assignments)]
|
||||
#![warn(clippy::unnecessary_to_owned)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Copy)]
|
||||
enum FileType {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: unnecessary use of `copied`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:31:22
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:33:22
|
||||
|
|
||||
LL | for (t, path) in files.iter().copied() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -17,7 +17,7 @@ LL + let other = match get_file_path(t) {
|
|||
|
|
||||
|
||||
error: unnecessary use of `copied`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:46:22
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:48:22
|
||||
|
|
||||
LL | for (t, path) in files.iter().copied() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -33,13 +33,13 @@ LL + let other = match get_file_path(t) {
|
|||
|
|
||||
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:177:18
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:179:18
|
||||
|
|
||||
LL | for c in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `v.iter()`
|
||||
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:185:18
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:187:18
|
||||
|
|
||||
LL | for c in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -55,7 +55,7 @@ LL + let ref_c = c;
|
|||
|
|
||||
|
||||
error: unnecessary use of `cloned`
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:194:23
|
||||
--> tests/ui/unnecessary_iter_cloned.rs:196:23
|
||||
|
|
||||
LL | for (i, c) in v.iter().cloned() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ struct V {
|
|||
f: u32,
|
||||
}
|
||||
|
||||
struct W {
|
||||
f1: u32,
|
||||
f2: u32,
|
||||
}
|
||||
|
||||
impl Clone for V {
|
||||
fn clone(&self) -> Self {
|
||||
// Lint: `Self` implements `Copy`
|
||||
|
|
@ -68,4 +73,69 @@ fn main() {
|
|||
|
||||
// Should lint: the result of an expression is mutable and temporary
|
||||
let p = &mut *Box::new(T { f: 5 });
|
||||
|
||||
// Should lint: all fields of `q` would be consumed anyway
|
||||
let q = W { f1: 42, f2: 1337 };
|
||||
let r = q;
|
||||
|
||||
// Should not lint: not all fields of `t` from same source
|
||||
let s = W { f1: 1337, f2: 42 };
|
||||
let t = W { f1: s.f1, f2: r.f2 };
|
||||
|
||||
// Should not lint: different fields of `s` assigned
|
||||
let u = W { f1: s.f2, f2: s.f1 };
|
||||
|
||||
// Should lint: all fields of `v` would be consumed anyway
|
||||
let v = W { f1: 42, f2: 1337 };
|
||||
let w = v;
|
||||
|
||||
// Should not lint: source differs between fields and base
|
||||
let x = W { f1: 42, f2: 1337 };
|
||||
let y = W { f1: w.f1, ..x };
|
||||
|
||||
// Should lint: range desugars to struct
|
||||
let r1 = 0..5;
|
||||
let r2 = r1;
|
||||
|
||||
references();
|
||||
shorthand();
|
||||
}
|
||||
|
||||
fn references() {
|
||||
// Should not lint as `a` is not mutable
|
||||
let a = W { f1: 42, f2: 1337 };
|
||||
let b = &mut W { f1: a.f1, f2: a.f2 };
|
||||
|
||||
// Should lint as `d` is a shared reference
|
||||
let c = W { f1: 42, f2: 1337 };
|
||||
let d = &c;
|
||||
|
||||
// Should not lint as `e` is not mutable
|
||||
let e = W { f1: 42, f2: 1337 };
|
||||
let f = &mut W { f1: e.f1, ..e };
|
||||
|
||||
// Should lint as `h` is a shared reference
|
||||
let g = W { f1: 42, f2: 1337 };
|
||||
let h = &g;
|
||||
|
||||
// Should not lint as `j` is copy
|
||||
let i = V { f: 0x1701d };
|
||||
let j = &V { ..i };
|
||||
|
||||
// Should not lint as `k` is copy
|
||||
let k = V { f: 0x1701d };
|
||||
let l = &V { f: k.f };
|
||||
}
|
||||
|
||||
fn shorthand() {
|
||||
struct S1 {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
let a = 42;
|
||||
let s = S1 { a: 3, b: 4 };
|
||||
|
||||
// Should not lint: `a` is not from `s`
|
||||
let s = S1 { a, b: s.b };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ struct V {
|
|||
f: u32,
|
||||
}
|
||||
|
||||
struct W {
|
||||
f1: u32,
|
||||
f2: u32,
|
||||
}
|
||||
|
||||
impl Clone for V {
|
||||
fn clone(&self) -> Self {
|
||||
// Lint: `Self` implements `Copy`
|
||||
|
|
@ -72,4 +77,69 @@ fn main() {
|
|||
let p = &mut T {
|
||||
..*Box::new(T { f: 5 })
|
||||
};
|
||||
|
||||
// Should lint: all fields of `q` would be consumed anyway
|
||||
let q = W { f1: 42, f2: 1337 };
|
||||
let r = W { f1: q.f1, f2: q.f2 };
|
||||
|
||||
// Should not lint: not all fields of `t` from same source
|
||||
let s = W { f1: 1337, f2: 42 };
|
||||
let t = W { f1: s.f1, f2: r.f2 };
|
||||
|
||||
// Should not lint: different fields of `s` assigned
|
||||
let u = W { f1: s.f2, f2: s.f1 };
|
||||
|
||||
// Should lint: all fields of `v` would be consumed anyway
|
||||
let v = W { f1: 42, f2: 1337 };
|
||||
let w = W { f1: v.f1, ..v };
|
||||
|
||||
// Should not lint: source differs between fields and base
|
||||
let x = W { f1: 42, f2: 1337 };
|
||||
let y = W { f1: w.f1, ..x };
|
||||
|
||||
// Should lint: range desugars to struct
|
||||
let r1 = 0..5;
|
||||
let r2 = r1.start..r1.end;
|
||||
|
||||
references();
|
||||
shorthand();
|
||||
}
|
||||
|
||||
fn references() {
|
||||
// Should not lint as `a` is not mutable
|
||||
let a = W { f1: 42, f2: 1337 };
|
||||
let b = &mut W { f1: a.f1, f2: a.f2 };
|
||||
|
||||
// Should lint as `d` is a shared reference
|
||||
let c = W { f1: 42, f2: 1337 };
|
||||
let d = &W { f1: c.f1, f2: c.f2 };
|
||||
|
||||
// Should not lint as `e` is not mutable
|
||||
let e = W { f1: 42, f2: 1337 };
|
||||
let f = &mut W { f1: e.f1, ..e };
|
||||
|
||||
// Should lint as `h` is a shared reference
|
||||
let g = W { f1: 42, f2: 1337 };
|
||||
let h = &W { f1: g.f1, ..g };
|
||||
|
||||
// Should not lint as `j` is copy
|
||||
let i = V { f: 0x1701d };
|
||||
let j = &V { ..i };
|
||||
|
||||
// Should not lint as `k` is copy
|
||||
let k = V { f: 0x1701d };
|
||||
let l = &V { f: k.f };
|
||||
}
|
||||
|
||||
fn shorthand() {
|
||||
struct S1 {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
let a = 42;
|
||||
let s = S1 { a: 3, b: 4 };
|
||||
|
||||
// Should not lint: `a` is not from `s`
|
||||
let s = S1 { a, b: s.b };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:32:9
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:37:9
|
||||
|
|
||||
LL | Self { ..*self }
|
||||
| ^^^^^^^^^^^^^^^^ help: replace with: `*self`
|
||||
|
|
@ -8,25 +8,25 @@ LL | Self { ..*self }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_struct_initialization)]`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:39:17
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:44:17
|
||||
|
|
||||
LL | let mut b = S { ..a };
|
||||
| ^^^^^^^^^ help: replace with: `a`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:42:18
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:47:18
|
||||
|
|
||||
LL | let c = &mut S { ..b };
|
||||
| ^^^^^^^^^ help: replace with: `b`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:50:14
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:55:14
|
||||
|
|
||||
LL | let g = &S { ..f };
|
||||
| ^^^^^^^^^ help: replace with: `f`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:53:18
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:58:18
|
||||
|
|
||||
LL | let h = &mut S {
|
||||
| __________________^
|
||||
|
|
@ -35,7 +35,7 @@ LL | | };
|
|||
| |_____^ help: replace with: `*Box::new(S { f: String::from("foo") })`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:72:18
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:77:18
|
||||
|
|
||||
LL | let p = &mut T {
|
||||
| __________________^
|
||||
|
|
@ -43,5 +43,35 @@ LL | | ..*Box::new(T { f: 5 })
|
|||
LL | | };
|
||||
| |_____^ help: replace with: `*Box::new(T { f: 5 })`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:83:13
|
||||
|
|
||||
LL | let r = W { f1: q.f1, f2: q.f2 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `q`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:94:13
|
||||
|
|
||||
LL | let w = W { f1: v.f1, ..v };
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: replace with: `v`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:102:14
|
||||
|
|
||||
LL | let r2 = r1.start..r1.end;
|
||||
| ^^^^^^^^^^^^^^^^ help: replace with: `r1`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:115:14
|
||||
|
|
||||
LL | let d = &W { f1: c.f1, f2: c.f2 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `c`
|
||||
|
||||
error: unnecessary struct building
|
||||
--> tests/ui/unnecessary_struct_initialization.rs:123:14
|
||||
|
|
||||
LL | let h = &W { f1: g.f1, ..g };
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: replace with: `g`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,587 +0,0 @@
|
|||
#![allow(
|
||||
clippy::needless_borrow,
|
||||
clippy::needless_borrows_for_generic_args,
|
||||
clippy::ptr_arg,
|
||||
clippy::manual_async_fn,
|
||||
clippy::needless_lifetimes
|
||||
)]
|
||||
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::{CStr, CString, OsStr, OsString};
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct X(String);
|
||||
|
||||
impl Deref for X {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
self.0.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for X {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::to_string_trait_impl)]
|
||||
impl ToString for X {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl X {
|
||||
fn join(&self, other: impl AsRef<str>) -> Self {
|
||||
let mut s = self.0.clone();
|
||||
s.push_str(other.as_ref());
|
||||
Self(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone)]
|
||||
enum FileType {
|
||||
Account,
|
||||
PrivateKey,
|
||||
Certificate,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();
|
||||
let os_str = OsStr::new("x");
|
||||
let path = std::path::Path::new("x");
|
||||
let s = "x";
|
||||
let array = ["x"];
|
||||
let array_ref = &["x"];
|
||||
let slice = &["x"][..];
|
||||
let x = X(String::from("x"));
|
||||
let x_ref = &x;
|
||||
|
||||
require_c_str(&Cow::from(c_str));
|
||||
require_c_str(c_str);
|
||||
|
||||
require_os_str(os_str);
|
||||
require_os_str(&Cow::from(os_str));
|
||||
require_os_str(os_str);
|
||||
|
||||
require_path(path);
|
||||
require_path(&Cow::from(path));
|
||||
require_path(path);
|
||||
|
||||
require_str(s);
|
||||
require_str(&Cow::from(s));
|
||||
require_str(s);
|
||||
require_str(x_ref.as_ref());
|
||||
|
||||
require_slice(slice);
|
||||
require_slice(&Cow::from(slice));
|
||||
require_slice(array.as_ref());
|
||||
require_slice(array_ref.as_ref());
|
||||
require_slice(slice);
|
||||
require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.
|
||||
|
||||
require_x(&Cow::<X>::Owned(x.clone()));
|
||||
require_x(&x_ref.to_owned()); // No longer flagged because of #8759.
|
||||
|
||||
require_deref_c_str(c_str);
|
||||
require_deref_os_str(os_str);
|
||||
require_deref_path(path);
|
||||
require_deref_str(s);
|
||||
require_deref_slice(slice);
|
||||
|
||||
require_impl_deref_c_str(c_str);
|
||||
require_impl_deref_os_str(os_str);
|
||||
require_impl_deref_path(path);
|
||||
require_impl_deref_str(s);
|
||||
require_impl_deref_slice(slice);
|
||||
|
||||
require_deref_str_slice(s, slice);
|
||||
require_deref_slice_str(slice, s);
|
||||
|
||||
require_as_ref_c_str(c_str);
|
||||
require_as_ref_os_str(os_str);
|
||||
require_as_ref_path(path);
|
||||
require_as_ref_str(s);
|
||||
require_as_ref_str(&x);
|
||||
require_as_ref_slice(array);
|
||||
require_as_ref_slice(array_ref);
|
||||
require_as_ref_slice(slice);
|
||||
|
||||
require_impl_as_ref_c_str(c_str);
|
||||
require_impl_as_ref_os_str(os_str);
|
||||
require_impl_as_ref_path(path);
|
||||
require_impl_as_ref_str(s);
|
||||
require_impl_as_ref_str(&x);
|
||||
require_impl_as_ref_slice(array);
|
||||
require_impl_as_ref_slice(array_ref);
|
||||
require_impl_as_ref_slice(slice);
|
||||
|
||||
require_as_ref_str_slice(s, array);
|
||||
require_as_ref_str_slice(s, array_ref);
|
||||
require_as_ref_str_slice(s, slice);
|
||||
require_as_ref_slice_str(array, s);
|
||||
require_as_ref_slice_str(array_ref, s);
|
||||
require_as_ref_slice_str(slice, s);
|
||||
|
||||
let _ = x.join(x_ref);
|
||||
|
||||
let _ = slice.iter().copied();
|
||||
let _ = slice.iter().copied();
|
||||
let _ = [std::path::PathBuf::new()][..].iter().cloned();
|
||||
let _ = [std::path::PathBuf::new()][..].iter().cloned();
|
||||
|
||||
let _ = slice.iter().copied();
|
||||
let _ = slice.iter().copied();
|
||||
let _ = [std::path::PathBuf::new()][..].iter().cloned();
|
||||
let _ = [std::path::PathBuf::new()][..].iter().cloned();
|
||||
|
||||
let _ = check_files(&[FileType::Account]);
|
||||
|
||||
// negative tests
|
||||
require_string(&s.to_string());
|
||||
require_string(&Cow::from(s).into_owned());
|
||||
require_string(&s.to_owned());
|
||||
require_string(&x_ref.to_string());
|
||||
|
||||
// `X` isn't copy.
|
||||
require_slice(&x.to_owned());
|
||||
require_deref_slice(x.to_owned());
|
||||
|
||||
// The following should be flagged by `redundant_clone`, but not by this lint.
|
||||
require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap());
|
||||
require_os_str(&OsString::from("x"));
|
||||
require_path(&std::path::PathBuf::from("x"));
|
||||
require_str(&String::from("x"));
|
||||
require_slice(&[String::from("x")]);
|
||||
|
||||
let slice = [0u8; 1024];
|
||||
let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
|
||||
let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
|
||||
let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
|
||||
// Expression is of type `&String`, can't suggest `str::from_utf8` here
|
||||
let _ref_string = &String::from_utf8(b"foo".to_vec()).unwrap();
|
||||
macro_rules! arg_from_macro {
|
||||
() => {
|
||||
b"foo".to_vec()
|
||||
};
|
||||
}
|
||||
macro_rules! string_from_utf8_from_macro {
|
||||
() => {
|
||||
&String::from_utf8(b"foo".to_vec()).unwrap()
|
||||
};
|
||||
}
|
||||
let _ref_str: &str = &String::from_utf8(arg_from_macro!()).unwrap();
|
||||
let _ref_str: &str = string_from_utf8_from_macro!();
|
||||
}
|
||||
|
||||
fn require_c_str(_: &CStr) {}
|
||||
fn require_os_str(_: &OsStr) {}
|
||||
fn require_path(_: &std::path::Path) {}
|
||||
fn require_str(_: &str) {}
|
||||
fn require_slice<T>(_: &[T]) {}
|
||||
fn require_x(_: &X) {}
|
||||
|
||||
fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}
|
||||
fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}
|
||||
fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}
|
||||
fn require_deref_str<T: Deref<Target = str>>(_: T) {}
|
||||
fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}
|
||||
|
||||
fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}
|
||||
fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}
|
||||
fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}
|
||||
fn require_impl_deref_str(_: impl Deref<Target = str>) {}
|
||||
fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}
|
||||
|
||||
fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}
|
||||
fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}
|
||||
|
||||
fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}
|
||||
fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}
|
||||
fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}
|
||||
fn require_as_ref_str<T: AsRef<str>>(_: T) {}
|
||||
fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}
|
||||
|
||||
fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}
|
||||
fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}
|
||||
fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}
|
||||
fn require_impl_as_ref_str(_: impl AsRef<str>) {}
|
||||
fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}
|
||||
|
||||
fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}
|
||||
fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}
|
||||
|
||||
// `check_files` is based on:
|
||||
// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
|
||||
fn check_files(file_types: &[FileType]) -> bool {
|
||||
for t in file_types {
|
||||
let path = match get_file_path(t) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if !path.is_file() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
|
||||
Ok(std::path::PathBuf::new())
|
||||
}
|
||||
|
||||
fn require_string(_: &String) {}
|
||||
|
||||
#[clippy::msrv = "1.35"]
|
||||
fn _msrv_1_35() {
|
||||
// `copied` was stabilized in 1.36, so clippy should use `cloned`.
|
||||
let _ = &["x"][..].iter().cloned();
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.36"]
|
||||
fn _msrv_1_36() {
|
||||
let _ = &["x"][..].iter().copied();
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/8507
|
||||
mod issue_8507 {
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct Opaque<P>(P);
|
||||
|
||||
pub trait Abstracted {}
|
||||
|
||||
impl<P> Abstracted for Opaque<P> {}
|
||||
|
||||
fn build<P>(p: P) -> Opaque<P>
|
||||
where
|
||||
P: AsRef<str>,
|
||||
{
|
||||
Opaque(p)
|
||||
}
|
||||
|
||||
// Should not lint.
|
||||
fn test_str(s: &str) -> Box<dyn Abstracted> {
|
||||
Box::new(build(s.to_string()))
|
||||
}
|
||||
|
||||
// Should not lint.
|
||||
fn test_x(x: super::X) -> Box<dyn Abstracted> {
|
||||
Box::new(build(x))
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Y(&'static str);
|
||||
|
||||
impl AsRef<str> for Y {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::to_string_trait_impl)]
|
||||
impl ToString for Y {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
// Should lint because Y is copy.
|
||||
fn test_y(y: Y) -> Box<dyn Abstracted> {
|
||||
Box::new(build(y))
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/8759
|
||||
mod issue_8759 {
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct View {}
|
||||
|
||||
impl std::borrow::ToOwned for View {
|
||||
type Owned = View;
|
||||
fn to_owned(&self) -> Self::Owned {
|
||||
View {}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct RenderWindow {
|
||||
default_view: View,
|
||||
}
|
||||
|
||||
impl RenderWindow {
|
||||
fn default_view(&self) -> &View {
|
||||
&self.default_view
|
||||
}
|
||||
fn set_view(&mut self, _view: &View) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut rw = RenderWindow::default();
|
||||
rw.set_view(&rw.default_view().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_8759_variant {
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct View {}
|
||||
|
||||
#[derive(Default)]
|
||||
struct RenderWindow {
|
||||
default_view: View,
|
||||
}
|
||||
|
||||
impl RenderWindow {
|
||||
fn default_view(&self) -> &View {
|
||||
&self.default_view
|
||||
}
|
||||
fn set_view(&mut self, _view: &View) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut rw = RenderWindow::default();
|
||||
rw.set_view(&rw.default_view().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9317 {
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct Bytes {}
|
||||
|
||||
#[allow(clippy::to_string_trait_impl)]
|
||||
impl ToString for Bytes {
|
||||
fn to_string(&self) -> String {
|
||||
"123".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Bytes {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&[1, 2, 3]
|
||||
}
|
||||
}
|
||||
|
||||
fn consume<C: AsRef<[u8]>>(c: C) {
|
||||
let _ = c;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let b = Bytes {};
|
||||
// Should not lint.
|
||||
consume(b.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9351 {
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
|
||||
x
|
||||
}
|
||||
|
||||
fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
|
||||
|
||||
fn id<T: AsRef<str>>(x: T) -> T {
|
||||
x
|
||||
}
|
||||
|
||||
fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
|
||||
|
||||
// Should lint
|
||||
fn single_return() -> impl AsRef<str> {
|
||||
id("abc")
|
||||
}
|
||||
|
||||
// Should not lint
|
||||
fn multiple_returns(b: bool) -> impl AsRef<str> {
|
||||
if b {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
id("abc".to_string())
|
||||
}
|
||||
|
||||
struct S1(String);
|
||||
|
||||
// Should not lint
|
||||
fn fields1() -> S1 {
|
||||
S1(id("abc".to_string()))
|
||||
}
|
||||
|
||||
struct S2 {
|
||||
s: String,
|
||||
}
|
||||
|
||||
// Should not lint
|
||||
fn fields2() {
|
||||
let mut s = S2 { s: "abc".into() };
|
||||
s.s = id("abc".to_string());
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let path = std::path::Path::new("x");
|
||||
let path_buf = path.to_owned();
|
||||
|
||||
// Should not lint.
|
||||
let _x: PathBuf = require_deref_path(path.to_owned());
|
||||
generic_arg_used_elsewhere(path.to_owned(), path_buf);
|
||||
predicates_are_satisfied(id("abc".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9504 {
|
||||
#![allow(dead_code)]
|
||||
|
||||
async fn foo<S: AsRef<str>>(_: S) {}
|
||||
async fn bar() {
|
||||
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9771a {
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
|
||||
|
||||
impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
|
||||
pub fn new(key: K) -> Key<K, V> {
|
||||
Key(key, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
|
||||
Key::new([b"pkh-", pkh].concat().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9771b {
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub struct Key<K: AsRef<[u8]>>(K);
|
||||
|
||||
pub fn from(c: &[u8]) -> Key<Vec<u8>> {
|
||||
let v = [c].concat();
|
||||
Key(v.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
// This is a watered down version of the code in: https://github.com/oxigraph/rio
|
||||
// The ICE is triggered by the call to `to_owned` on this line:
|
||||
// https://github.com/oxigraph/rio/blob/66635b9ff8e5423e58932353fa40d6e64e4820f7/testsuite/src/parser_evaluator.rs#L116
|
||||
mod issue_10021 {
|
||||
#![allow(unused)]
|
||||
|
||||
pub struct Iri<T>(T);
|
||||
|
||||
impl<T: AsRef<str>> Iri<T> {
|
||||
pub fn parse(iri: T) -> Result<Self, ()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_w3c_rdf_test_file(url: &str) -> Result<(), ()> {
|
||||
let base_iri = Iri::parse(url.to_owned())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_10033 {
|
||||
#![allow(dead_code)]
|
||||
use std::fmt::Display;
|
||||
use std::ops::Deref;
|
||||
|
||||
fn _main() {
|
||||
let f = Foo;
|
||||
|
||||
// Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does
|
||||
// deref to `str`)
|
||||
foo(&f.to_string());
|
||||
}
|
||||
|
||||
fn foo(s: &str) {
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Deref for Foo {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
"str"
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Foo {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Foo")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_11952 {
|
||||
use core::future::{Future, IntoFuture};
|
||||
|
||||
fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
|
||||
async move {
|
||||
let _y = y;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
IntoFuture::into_future(foo([], &0));
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_checks() {
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn inner(a: &[&str]) {
|
||||
let mut s = HashSet::from([vec!["a"]]);
|
||||
s.remove(a); //~ ERROR: unnecessary use of `to_vec`
|
||||
}
|
||||
|
||||
let mut s = HashSet::from(["a".to_string()]);
|
||||
s.remove("b"); //~ ERROR: unnecessary use of `to_owned`
|
||||
s.remove("b"); //~ ERROR: unnecessary use of `to_string`
|
||||
// Should not warn.
|
||||
s.remove("b");
|
||||
|
||||
let mut s = HashSet::from([vec!["a"]]);
|
||||
s.remove(["b"].as_slice()); //~ ERROR: unnecessary use of `to_vec`
|
||||
s.remove((&["b"]).as_slice()); //~ ERROR: unnecessary use of `to_vec`
|
||||
|
||||
// Should not warn.
|
||||
s.remove(&["b"].to_vec().clone());
|
||||
s.remove(["a"].as_slice());
|
||||
|
||||
trait SetExt {
|
||||
fn foo<Q: Borrow<str>>(&self, _: &String);
|
||||
}
|
||||
|
||||
impl<K> SetExt for HashSet<K> {
|
||||
fn foo<Q: Borrow<str>>(&self, _: &String) {}
|
||||
}
|
||||
|
||||
// Should not lint!
|
||||
HashSet::<i32>::new().foo::<&str>(&"".to_owned());
|
||||
HashSet::<String>::new().get(&1.to_string());
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
)]
|
||||
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::{CStr, CString, OsStr, OsString};
|
||||
use std::ops::Deref;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: redundant clone
|
||||
--> tests/ui/unnecessary_to_owned.rs:155:64
|
||||
--> tests/ui/unnecessary_to_owned.rs:157:64
|
||||
|
|
||||
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
|
||||
| ^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/unnecessary_to_owned.rs:155:20
|
||||
--> tests/ui/unnecessary_to_owned.rs:157:20
|
||||
|
|
||||
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -13,55 +13,55 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
|
|||
= help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/unnecessary_to_owned.rs:156:40
|
||||
--> tests/ui/unnecessary_to_owned.rs:158:40
|
||||
|
|
||||
LL | require_os_str(&OsString::from("x").to_os_string());
|
||||
| ^^^^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/unnecessary_to_owned.rs:156:21
|
||||
--> tests/ui/unnecessary_to_owned.rs:158:21
|
||||
|
|
||||
LL | require_os_str(&OsString::from("x").to_os_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/unnecessary_to_owned.rs:157:48
|
||||
--> tests/ui/unnecessary_to_owned.rs:159:48
|
||||
|
|
||||
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
|
||||
| ^^^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/unnecessary_to_owned.rs:157:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:159:19
|
||||
|
|
||||
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/unnecessary_to_owned.rs:158:35
|
||||
--> tests/ui/unnecessary_to_owned.rs:160:35
|
||||
|
|
||||
LL | require_str(&String::from("x").to_string());
|
||||
| ^^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/unnecessary_to_owned.rs:158:18
|
||||
--> tests/ui/unnecessary_to_owned.rs:160:18
|
||||
|
|
||||
LL | require_str(&String::from("x").to_string());
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: redundant clone
|
||||
--> tests/ui/unnecessary_to_owned.rs:159:39
|
||||
--> tests/ui/unnecessary_to_owned.rs:161:39
|
||||
|
|
||||
LL | require_slice(&[String::from("x")].to_owned());
|
||||
| ^^^^^^^^^^^ help: remove this
|
||||
|
|
||||
note: this value is dropped without further use
|
||||
--> tests/ui/unnecessary_to_owned.rs:159:20
|
||||
--> tests/ui/unnecessary_to_owned.rs:161:20
|
||||
|
|
||||
LL | require_slice(&[String::from("x")].to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:64:36
|
||||
--> tests/ui/unnecessary_to_owned.rs:66:36
|
||||
|
|
||||
LL | require_c_str(&Cow::from(c_str).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
|
@ -70,415 +70,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned());
|
|||
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:65:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:67:19
|
||||
|
|
||||
LL | require_c_str(&c_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `c_str`
|
||||
|
||||
error: unnecessary use of `to_os_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:67:20
|
||||
--> tests/ui/unnecessary_to_owned.rs:69:20
|
||||
|
|
||||
LL | require_os_str(&os_str.to_os_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:68:38
|
||||
--> tests/ui/unnecessary_to_owned.rs:70:38
|
||||
|
|
||||
LL | require_os_str(&Cow::from(os_str).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:69:20
|
||||
--> tests/ui/unnecessary_to_owned.rs:71:20
|
||||
|
|
||||
LL | require_os_str(&os_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `to_path_buf`
|
||||
--> tests/ui/unnecessary_to_owned.rs:71:18
|
||||
--> tests/ui/unnecessary_to_owned.rs:73:18
|
||||
|
|
||||
LL | require_path(&path.to_path_buf());
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:72:34
|
||||
--> tests/ui/unnecessary_to_owned.rs:74:34
|
||||
|
|
||||
LL | require_path(&Cow::from(path).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:73:18
|
||||
--> tests/ui/unnecessary_to_owned.rs:75:18
|
||||
|
|
||||
LL | require_path(&path.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:75:17
|
||||
--> tests/ui/unnecessary_to_owned.rs:77:17
|
||||
|
|
||||
LL | require_str(&s.to_string());
|
||||
| ^^^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:76:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:78:30
|
||||
|
|
||||
LL | require_str(&Cow::from(s).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:77:17
|
||||
--> tests/ui/unnecessary_to_owned.rs:79:17
|
||||
|
|
||||
LL | require_str(&s.to_owned());
|
||||
| ^^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:78:17
|
||||
--> tests/ui/unnecessary_to_owned.rs:80:17
|
||||
|
|
||||
LL | require_str(&x_ref.to_string());
|
||||
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:80:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:82:19
|
||||
|
|
||||
LL | require_slice(&slice.to_vec());
|
||||
| ^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:81:36
|
||||
--> tests/ui/unnecessary_to_owned.rs:83:36
|
||||
|
|
||||
LL | require_slice(&Cow::from(slice).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:82:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:84:19
|
||||
|
|
||||
LL | require_slice(&array.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:83:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:85:19
|
||||
|
|
||||
LL | require_slice(&array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:84:19
|
||||
--> tests/ui/unnecessary_to_owned.rs:86:19
|
||||
|
|
||||
LL | require_slice(&slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `into_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:87:42
|
||||
--> tests/ui/unnecessary_to_owned.rs:89:42
|
||||
|
|
||||
LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned());
|
||||
| ^^^^^^^^^^^^^ help: remove this
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:90:25
|
||||
--> tests/ui/unnecessary_to_owned.rs:92:25
|
||||
|
|
||||
LL | require_deref_c_str(c_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:91:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:93:26
|
||||
|
|
||||
LL | require_deref_os_str(os_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:92:24
|
||||
--> tests/ui/unnecessary_to_owned.rs:94:24
|
||||
|
|
||||
LL | require_deref_path(path.to_owned());
|
||||
| ^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:93:23
|
||||
--> tests/ui/unnecessary_to_owned.rs:95:23
|
||||
|
|
||||
LL | require_deref_str(s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:94:25
|
||||
--> tests/ui/unnecessary_to_owned.rs:96:25
|
||||
|
|
||||
LL | require_deref_slice(slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:96:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:98:30
|
||||
|
|
||||
LL | require_impl_deref_c_str(c_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:97:31
|
||||
--> tests/ui/unnecessary_to_owned.rs:99:31
|
||||
|
|
||||
LL | require_impl_deref_os_str(os_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:98:29
|
||||
--> tests/ui/unnecessary_to_owned.rs:100:29
|
||||
|
|
||||
LL | require_impl_deref_path(path.to_owned());
|
||||
| ^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:99:28
|
||||
--> tests/ui/unnecessary_to_owned.rs:101:28
|
||||
|
|
||||
LL | require_impl_deref_str(s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:100:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:102:30
|
||||
|
|
||||
LL | require_impl_deref_slice(slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:102:29
|
||||
--> tests/ui/unnecessary_to_owned.rs:104:29
|
||||
|
|
||||
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:102:43
|
||||
--> tests/ui/unnecessary_to_owned.rs:104:43
|
||||
|
|
||||
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:103:29
|
||||
--> tests/ui/unnecessary_to_owned.rs:105:29
|
||||
|
|
||||
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:103:47
|
||||
--> tests/ui/unnecessary_to_owned.rs:105:47
|
||||
|
|
||||
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:105:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:107:26
|
||||
|
|
||||
LL | require_as_ref_c_str(c_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:106:27
|
||||
--> tests/ui/unnecessary_to_owned.rs:108:27
|
||||
|
|
||||
LL | require_as_ref_os_str(os_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:107:25
|
||||
--> tests/ui/unnecessary_to_owned.rs:109:25
|
||||
|
|
||||
LL | require_as_ref_path(path.to_owned());
|
||||
| ^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:108:24
|
||||
--> tests/ui/unnecessary_to_owned.rs:110:24
|
||||
|
|
||||
LL | require_as_ref_str(s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:109:24
|
||||
--> tests/ui/unnecessary_to_owned.rs:111:24
|
||||
|
|
||||
LL | require_as_ref_str(x.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `&x`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:110:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:112:26
|
||||
|
|
||||
LL | require_as_ref_slice(array.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `array`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:111:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:113:26
|
||||
|
|
||||
LL | require_as_ref_slice(array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:112:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:114:26
|
||||
|
|
||||
LL | require_as_ref_slice(slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:114:31
|
||||
--> tests/ui/unnecessary_to_owned.rs:116:31
|
||||
|
|
||||
LL | require_impl_as_ref_c_str(c_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:115:32
|
||||
--> tests/ui/unnecessary_to_owned.rs:117:32
|
||||
|
|
||||
LL | require_impl_as_ref_os_str(os_str.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:116:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:118:30
|
||||
|
|
||||
LL | require_impl_as_ref_path(path.to_owned());
|
||||
| ^^^^^^^^^^^^^^^ help: use: `path`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:117:29
|
||||
--> tests/ui/unnecessary_to_owned.rs:119:29
|
||||
|
|
||||
LL | require_impl_as_ref_str(s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:118:29
|
||||
--> tests/ui/unnecessary_to_owned.rs:120:29
|
||||
|
|
||||
LL | require_impl_as_ref_str(x.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `&x`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:119:31
|
||||
--> tests/ui/unnecessary_to_owned.rs:121:31
|
||||
|
|
||||
LL | require_impl_as_ref_slice(array.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `array`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:120:31
|
||||
--> tests/ui/unnecessary_to_owned.rs:122:31
|
||||
|
|
||||
LL | require_impl_as_ref_slice(array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:121:31
|
||||
--> tests/ui/unnecessary_to_owned.rs:123:31
|
||||
|
|
||||
LL | require_impl_as_ref_slice(slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:123:30
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:123:44
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `array`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:124:30
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:124:44
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:125:30
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:125:44
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `array`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:126:30
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:126:44
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:127:30
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:127:44
|
||||
|
|
||||
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:126:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:128:30
|
||||
|
|
||||
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `array`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:126:48
|
||||
--> tests/ui/unnecessary_to_owned.rs:128:48
|
||||
|
|
||||
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:127:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:129:30
|
||||
|
|
||||
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:127:52
|
||||
--> tests/ui/unnecessary_to_owned.rs:129:52
|
||||
|
|
||||
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:128:30
|
||||
--> tests/ui/unnecessary_to_owned.rs:130:30
|
||||
|
|
||||
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^ help: use: `slice`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:128:48
|
||||
--> tests/ui/unnecessary_to_owned.rs:130:48
|
||||
|
|
||||
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
|
||||
| ^^^^^^^^^^^^ help: use: `s`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:130:20
|
||||
--> tests/ui/unnecessary_to_owned.rs:132:20
|
||||
|
|
||||
LL | let _ = x.join(&x_ref.to_string());
|
||||
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:132:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:134:13
|
||||
|
|
||||
LL | let _ = slice.to_vec().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:133:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:135:13
|
||||
|
|
||||
LL | let _ = slice.to_owned().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:134:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:136:13
|
||||
|
|
||||
LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:135:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:137:13
|
||||
|
|
||||
LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:137:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:139:13
|
||||
|
|
||||
LL | let _ = IntoIterator::into_iter(slice.to_vec());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:138:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:140:13
|
||||
|
|
||||
LL | let _ = IntoIterator::into_iter(slice.to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:139:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:141:13
|
||||
|
|
||||
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:140:13
|
||||
--> tests/ui/unnecessary_to_owned.rs:142:13
|
||||
|
|
||||
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
|
||||
|
||||
error: allocating a new `String` only to create a temporary `&str` from it
|
||||
--> tests/ui/unnecessary_to_owned.rs:162:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:164:26
|
||||
|
|
||||
LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -490,7 +490,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
|
|||
|
|
||||
|
||||
error: allocating a new `String` only to create a temporary `&str` from it
|
||||
--> tests/ui/unnecessary_to_owned.rs:163:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:165:26
|
||||
|
|
||||
LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -502,7 +502,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
|
|||
|
|
||||
|
||||
error: allocating a new `String` only to create a temporary `&str` from it
|
||||
--> tests/ui/unnecessary_to_owned.rs:164:26
|
||||
--> tests/ui/unnecessary_to_owned.rs:166:26
|
||||
|
|
||||
LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -514,7 +514,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
|
|||
|
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:221:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:223:14
|
||||
|
|
||||
LL | for t in file_types.to_vec() {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -530,61 +530,61 @@ LL + let path = match get_file_path(t) {
|
|||
|
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:244:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:246:14
|
||||
|
|
||||
LL | let _ = &["x"][..].to_vec().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:249:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:251:14
|
||||
|
|
||||
LL | let _ = &["x"][..].to_vec().into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:297:24
|
||||
--> tests/ui/unnecessary_to_owned.rs:299:24
|
||||
|
|
||||
LL | Box::new(build(y.to_string()))
|
||||
| ^^^^^^^^^^^^^ help: use: `y`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:406:12
|
||||
--> tests/ui/unnecessary_to_owned.rs:408:12
|
||||
|
|
||||
LL | id("abc".to_string())
|
||||
| ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:549:37
|
||||
--> tests/ui/unnecessary_to_owned.rs:551:37
|
||||
|
|
||||
LL | IntoFuture::into_future(foo([].to_vec(), &0));
|
||||
| ^^^^^^^^^^^ help: use: `[]`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:559:18
|
||||
--> tests/ui/unnecessary_to_owned.rs:561:18
|
||||
|
|
||||
LL | s.remove(&a.to_vec());
|
||||
| ^^^^^^^^^^^ help: replace it with: `a`
|
||||
|
||||
error: unnecessary use of `to_owned`
|
||||
--> tests/ui/unnecessary_to_owned.rs:563:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:565:14
|
||||
|
|
||||
LL | s.remove(&"b".to_owned());
|
||||
| ^^^^^^^^^^^^^^^ help: replace it with: `"b"`
|
||||
|
||||
error: unnecessary use of `to_string`
|
||||
--> tests/ui/unnecessary_to_owned.rs:564:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:566:14
|
||||
|
|
||||
LL | s.remove(&"b".to_string());
|
||||
| ^^^^^^^^^^^^^^^^ help: replace it with: `"b"`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:569:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:571:14
|
||||
|
|
||||
LL | s.remove(&["b"].to_vec());
|
||||
| ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()`
|
||||
|
||||
error: unnecessary use of `to_vec`
|
||||
--> tests/ui/unnecessary_to_owned.rs:570:14
|
||||
--> tests/ui/unnecessary_to_owned.rs:572:14
|
||||
|
|
||||
LL | s.remove(&(&["b"]).to_vec());
|
||||
| ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()`
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue