mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-26 22:50:56 +00:00
Check .fixed
paths' existence in run_ui
This commit is contained in:
parent
a5ece8132f
commit
911eb1f4cd
49 changed files with 1478 additions and 127 deletions
|
@ -1,5 +1,6 @@
|
|||
#![feature(test)] // compiletest_rs requires this attribute
|
||||
#![feature(once_cell)]
|
||||
#![feature(is_sorted)]
|
||||
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||
|
||||
|
@ -162,8 +163,8 @@ fn base_config(test_dir: &str) -> compiletest::Config {
|
|||
}
|
||||
|
||||
fn run_ui() {
|
||||
let config = base_config("ui");
|
||||
// use tests/clippy.toml
|
||||
let mut config = base_config("ui");
|
||||
config.rustfix_coverage = true;
|
||||
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
|
||||
let _threads = VarGuard::set(
|
||||
"RUST_TEST_THREADS",
|
||||
|
@ -175,6 +176,7 @@ fn run_ui() {
|
|||
}),
|
||||
);
|
||||
compiletest::run_tests(&config);
|
||||
check_rustfix_coverage();
|
||||
}
|
||||
|
||||
fn run_internal_tests() {
|
||||
|
@ -337,6 +339,82 @@ fn compile_test() {
|
|||
run_internal_tests();
|
||||
}
|
||||
|
||||
const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
|
||||
"assign_ops2.rs",
|
||||
"cast_size_32bit.rs",
|
||||
"char_lit_as_u8.rs",
|
||||
"cmp_owned/without_suggestion.rs",
|
||||
"crashes/ice-6250.rs",
|
||||
"crashes/ice-6251.rs",
|
||||
"dbg_macro.rs",
|
||||
"deref_addrof_double_trigger.rs",
|
||||
"doc/unbalanced_ticks.rs",
|
||||
"eprint_with_newline.rs",
|
||||
"explicit_counter_loop.rs",
|
||||
"iter_skip_next_unfixable.rs",
|
||||
"let_and_return.rs",
|
||||
"literals.rs",
|
||||
"map_flatten.rs",
|
||||
"map_unwrap_or.rs",
|
||||
"match_bool.rs",
|
||||
"mem_replace_macro.rs",
|
||||
"needless_arbitrary_self_type_unfixable.rs",
|
||||
"needless_borrow_pat.rs",
|
||||
"needless_for_each_unfixable.rs",
|
||||
"nonminimal_bool.rs",
|
||||
"print_literal.rs",
|
||||
"print_with_newline.rs",
|
||||
"redundant_static_lifetimes_multiple.rs",
|
||||
"ref_binding_to_reference.rs",
|
||||
"repl_uninit.rs",
|
||||
"result_map_unit_fn_unfixable.rs",
|
||||
"search_is_some.rs",
|
||||
"single_component_path_imports_nested_first.rs",
|
||||
"string_add.rs",
|
||||
"toplevel_ref_arg_non_rustfix.rs",
|
||||
"unit_arg.rs",
|
||||
"unnecessary_clone.rs",
|
||||
"unnecessary_lazy_eval_unfixable.rs",
|
||||
"write_literal.rs",
|
||||
"write_literal_2.rs",
|
||||
"write_with_newline.rs",
|
||||
];
|
||||
|
||||
fn check_rustfix_coverage() {
|
||||
let missing_coverage_path = Path::new("target/debug/test/ui/rustfix_missing_coverage.txt");
|
||||
|
||||
if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
|
||||
assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.is_sorted());
|
||||
|
||||
for rs_path in missing_coverage_contents.lines() {
|
||||
let filename = rs_path.strip_prefix("tests/ui/").unwrap();
|
||||
assert!(
|
||||
RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.binary_search(&filename).is_ok(),
|
||||
"`{}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation",
|
||||
rs_path,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rustfix_coverage_known_exceptions_accuracy() {
|
||||
for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
|
||||
let rs_path = Path::new("tests/ui").join(filename);
|
||||
assert!(
|
||||
rs_path.exists(),
|
||||
"`{}` does not exists",
|
||||
rs_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
|
||||
);
|
||||
let fixed_path = rs_path.with_extension("fixed");
|
||||
assert!(
|
||||
!fixed_path.exists(),
|
||||
"`{}` exists",
|
||||
fixed_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores an env var on drop
|
||||
#[must_use]
|
||||
struct VarGuard {
|
||||
|
|
62
tests/ui/bind_instead_of_map_multipart.fixed
Normal file
62
tests/ui/bind_instead_of_map_multipart.fixed
Normal file
|
@ -0,0 +1,62 @@
|
|||
// run-rustfix
|
||||
#![deny(clippy::bind_instead_of_map)]
|
||||
#![allow(clippy::blocks_in_if_conditions)]
|
||||
|
||||
pub fn main() {
|
||||
let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
|
||||
let _ = Some("42").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) });
|
||||
|
||||
let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
|
||||
let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) });
|
||||
|
||||
let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });
|
||||
let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) });
|
||||
|
||||
hard_example();
|
||||
macro_example();
|
||||
}
|
||||
|
||||
fn hard_example() {
|
||||
Some("42").map(|s| {
|
||||
if {
|
||||
if s == "43" {
|
||||
return 43;
|
||||
}
|
||||
s == "42"
|
||||
} {
|
||||
return 45;
|
||||
}
|
||||
match s.len() {
|
||||
10 => 2,
|
||||
20 => {
|
||||
if foo() {
|
||||
return {
|
||||
if foo() {
|
||||
return 20;
|
||||
}
|
||||
println!("foo");
|
||||
3
|
||||
};
|
||||
}
|
||||
20
|
||||
},
|
||||
40 => 30,
|
||||
_ => 1,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn foo() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
macro_rules! m {
|
||||
() => {
|
||||
Some(10)
|
||||
};
|
||||
}
|
||||
|
||||
fn macro_example() {
|
||||
let _ = Some("").and_then(|s| if s.len() == 20 { m!() } else { Some(20) });
|
||||
let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) });
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
#![deny(clippy::bind_instead_of_map)]
|
||||
#![allow(clippy::blocks_in_if_conditions)]
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:5:13
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:6:13
|
||||
|
|
||||
LL | let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:1:9
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:2:9
|
||||
|
|
||||
LL | #![deny(clippy::bind_instead_of_map)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -15,7 +15,7 @@ LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
|
|||
| ~~~ ~ ~~~~~~~
|
||||
|
||||
error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:8:13
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:9:13
|
||||
|
|
||||
LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -26,7 +26,7 @@ LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len()
|
|||
| ~~~ ~ ~~~~~~~
|
||||
|
||||
error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:11:13
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:12:13
|
||||
|
|
||||
LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -37,7 +37,7 @@ LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 }
|
|||
| ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~
|
||||
|
||||
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:19:5
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:20:5
|
||||
|
|
||||
LL | / Some("42").and_then(|s| {
|
||||
LL | | if {
|
||||
|
@ -59,7 +59,7 @@ LL | s == "42"
|
|||
...
|
||||
|
||||
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:60:13
|
||||
--> $DIR/bind_instead_of_map_multipart.rs:61:13
|
||||
|
|
||||
LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
12
tests/ui/crashes/ice-7169.fixed
Normal file
12
tests/ui/crashes/ice-7169.fixed
Normal file
|
@ -0,0 +1,12 @@
|
|||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct A<T> {
|
||||
a: Vec<A<T>>,
|
||||
b: T,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if Ok::<_, ()>(A::<String>::default()).is_ok() {}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct A<T> {
|
||||
a: Vec<A<T>>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: redundant pattern matching, consider using `is_ok()`
|
||||
--> $DIR/ice-7169.rs:8:12
|
||||
--> $DIR/ice-7169.rs:11:12
|
||||
|
|
||||
LL | if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}
|
||||
| -------^^^^^-------------------------------------- help: try this: `if Ok::<_, ()>(A::<String>::default()).is_ok()`
|
||||
|
|
7
tests/ui/crashes/ice-8250.fixed
Normal file
7
tests/ui/crashes/ice-8250.fixed
Normal file
|
@ -0,0 +1,7 @@
|
|||
// run-rustfix
|
||||
fn _f(s: &str) -> Option<()> {
|
||||
let _ = s[1..].split('.').next()?;
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
fn _f(s: &str) -> Option<()> {
|
||||
let _ = s[1..].splitn(2, '.').next()?;
|
||||
Some(())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: unnecessary use of `splitn`
|
||||
--> $DIR/ice-8250.rs:2:13
|
||||
--> $DIR/ice-8250.rs:3:13
|
||||
|
|
||||
LL | let _ = s[1..].splitn(2, '.').next()?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s[1..].split('.')`
|
||||
|
|
9
tests/ui/crashes/ice-8821.fixed
Normal file
9
tests/ui/crashes/ice-8821.fixed
Normal file
|
@ -0,0 +1,9 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::let_unit_value)]
|
||||
|
||||
fn f() {}
|
||||
static FN: fn() = f;
|
||||
|
||||
fn main() {
|
||||
FN();
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::let_unit_value)]
|
||||
|
||||
fn f() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this let-binding has unit value
|
||||
--> $DIR/ice-8821.rs:7:5
|
||||
--> $DIR/ice-8821.rs:8:5
|
||||
|
|
||||
LL | let _: () = FN();
|
||||
| ^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `FN();`
|
||||
|
|
118
tests/ui/implicit_clone.fixed
Normal file
118
tests/ui/implicit_clone.fixed
Normal file
|
@ -0,0 +1,118 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::implicit_clone)]
|
||||
#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
|
||||
use std::borrow::Borrow;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn return_owned_from_slice(slice: &[u32]) -> Vec<u32> {
|
||||
slice.to_owned()
|
||||
}
|
||||
|
||||
pub fn own_same<T>(v: T) -> T
|
||||
where
|
||||
T: ToOwned<Owned = T>,
|
||||
{
|
||||
v.to_owned()
|
||||
}
|
||||
|
||||
pub fn own_same_from_ref<T>(v: &T) -> T
|
||||
where
|
||||
T: ToOwned<Owned = T>,
|
||||
{
|
||||
v.to_owned()
|
||||
}
|
||||
|
||||
pub fn own_different<T, U>(v: T) -> U
|
||||
where
|
||||
T: ToOwned<Owned = U>,
|
||||
{
|
||||
v.to_owned()
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Kitten;
|
||||
impl Kitten {
|
||||
// badly named method
|
||||
fn to_vec(self) -> Kitten {
|
||||
Kitten {}
|
||||
}
|
||||
}
|
||||
impl Borrow<BorrowedKitten> for Kitten {
|
||||
fn borrow(&self) -> &BorrowedKitten {
|
||||
static VALUE: BorrowedKitten = BorrowedKitten {};
|
||||
&VALUE
|
||||
}
|
||||
}
|
||||
|
||||
struct BorrowedKitten;
|
||||
impl ToOwned for BorrowedKitten {
|
||||
type Owned = Kitten;
|
||||
fn to_owned(&self) -> Kitten {
|
||||
Kitten {}
|
||||
}
|
||||
}
|
||||
|
||||
mod weird {
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn to_vec(v: &Vec<u32>) -> Vec<u32> {
|
||||
v.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let vec = vec![5];
|
||||
let _ = return_owned_from_slice(&vec);
|
||||
let _ = vec.clone();
|
||||
let _ = vec.clone();
|
||||
|
||||
let vec_ref = &vec;
|
||||
let _ = return_owned_from_slice(vec_ref);
|
||||
let _ = vec_ref.clone();
|
||||
let _ = vec_ref.clone();
|
||||
|
||||
// we expect no lint for this
|
||||
let _ = weird::to_vec(&vec);
|
||||
|
||||
// we expect no lints for this
|
||||
let slice: &[u32] = &[1, 2, 3, 4, 5];
|
||||
let _ = return_owned_from_slice(slice);
|
||||
let _ = slice.to_owned();
|
||||
let _ = slice.to_vec();
|
||||
|
||||
let str = "hello world".to_string();
|
||||
let _ = str.clone();
|
||||
|
||||
// testing w/ an arbitrary type
|
||||
let kitten = Kitten {};
|
||||
let _ = kitten.clone();
|
||||
let _ = own_same_from_ref(&kitten);
|
||||
// this shouln't lint
|
||||
let _ = kitten.to_vec();
|
||||
|
||||
// we expect no lints for this
|
||||
let borrowed = BorrowedKitten {};
|
||||
let _ = borrowed.to_owned();
|
||||
|
||||
let pathbuf = PathBuf::new();
|
||||
let _ = pathbuf.clone();
|
||||
let _ = pathbuf.clone();
|
||||
|
||||
let os_string = OsString::from("foo");
|
||||
let _ = os_string.clone();
|
||||
let _ = os_string.clone();
|
||||
|
||||
// we expect no lints for this
|
||||
let os_str = OsStr::new("foo");
|
||||
let _ = os_str.to_owned();
|
||||
let _ = os_str.to_os_string();
|
||||
|
||||
// issue #8227
|
||||
let pathbuf_ref = &pathbuf;
|
||||
let pathbuf_ref = &pathbuf_ref;
|
||||
let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf`
|
||||
let _ = (*pathbuf_ref).clone();
|
||||
let pathbuf_ref = &pathbuf_ref;
|
||||
let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf`
|
||||
let _ = (**pathbuf_ref).clone();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::implicit_clone)]
|
||||
#![allow(clippy::redundant_clone)]
|
||||
#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
|
||||
use std::borrow::Borrow;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::PathBuf;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:65:13
|
||||
--> $DIR/implicit_clone.rs:66:13
|
||||
|
|
||||
LL | let _ = vec.to_owned();
|
||||
| ^^^^^^^^^^^^^^ help: consider using: `vec.clone()`
|
||||
|
@ -7,67 +7,67 @@ LL | let _ = vec.to_owned();
|
|||
= note: `-D clippy::implicit-clone` implied by `-D warnings`
|
||||
|
||||
error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:66:13
|
||||
--> $DIR/implicit_clone.rs:67:13
|
||||
|
|
||||
LL | let _ = vec.to_vec();
|
||||
| ^^^^^^^^^^^^ help: consider using: `vec.clone()`
|
||||
|
||||
error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:70:13
|
||||
--> $DIR/implicit_clone.rs:71:13
|
||||
|
|
||||
LL | let _ = vec_ref.to_owned();
|
||||
| ^^^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
|
||||
|
||||
error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:71:13
|
||||
--> $DIR/implicit_clone.rs:72:13
|
||||
|
|
||||
LL | let _ = vec_ref.to_vec();
|
||||
| ^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
|
||||
|
||||
error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:83:13
|
||||
--> $DIR/implicit_clone.rs:84:13
|
||||
|
|
||||
LL | let _ = str.to_owned();
|
||||
| ^^^^^^^^^^^^^^ help: consider using: `str.clone()`
|
||||
|
||||
error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:87:13
|
||||
--> $DIR/implicit_clone.rs:88:13
|
||||
|
|
||||
LL | let _ = kitten.to_owned();
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()`
|
||||
|
||||
error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:97:13
|
||||
--> $DIR/implicit_clone.rs:98:13
|
||||
|
|
||||
LL | let _ = pathbuf.to_owned();
|
||||
| ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
|
||||
|
||||
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:98:13
|
||||
--> $DIR/implicit_clone.rs:99:13
|
||||
|
|
||||
LL | let _ = pathbuf.to_path_buf();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
|
||||
|
||||
error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:101:13
|
||||
--> $DIR/implicit_clone.rs:102:13
|
||||
|
|
||||
LL | let _ = os_string.to_owned();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
|
||||
|
||||
error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:102:13
|
||||
--> $DIR/implicit_clone.rs:103:13
|
||||
|
|
||||
LL | let _ = os_string.to_os_string();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
|
||||
|
||||
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:113:13
|
||||
--> $DIR/implicit_clone.rs:114:13
|
||||
|
|
||||
LL | let _ = pathbuf_ref.to_path_buf();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()`
|
||||
|
||||
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
|
||||
--> $DIR/implicit_clone.rs:116:13
|
||||
--> $DIR/implicit_clone.rs:117:13
|
||||
|
|
||||
LL | let _ = pathbuf_ref.to_path_buf();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`
|
||||
|
|
26
tests/ui/issue_2356.fixed
Normal file
26
tests/ui/issue_2356.fixed
Normal file
|
@ -0,0 +1,26 @@
|
|||
// run-rustfix
|
||||
#![deny(clippy::while_let_on_iterator)]
|
||||
#![allow(unused_mut)]
|
||||
|
||||
use std::iter::Iterator;
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo1<I: Iterator<Item = usize>>(mut it: I) {
|
||||
while let Some(_) = it.next() {
|
||||
println!("{:?}", it.size_hint());
|
||||
}
|
||||
}
|
||||
|
||||
fn foo2<I: Iterator<Item = usize>>(mut it: I) {
|
||||
for e in it {
|
||||
println!("{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Foo::foo1(vec![].into_iter());
|
||||
Foo::foo2(vec![].into_iter());
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
// run-rustfix
|
||||
#![deny(clippy::while_let_on_iterator)]
|
||||
#![allow(unused_mut)]
|
||||
|
||||
use std::iter::Iterator;
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: this loop could be written as a `for` loop
|
||||
--> $DIR/issue_2356.rs:15:9
|
||||
--> $DIR/issue_2356.rs:17:9
|
||||
|
|
||||
LL | while let Some(e) = it.next() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for e in it`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue_2356.rs:1:9
|
||||
--> $DIR/issue_2356.rs:2:9
|
||||
|
|
||||
LL | #![deny(clippy::while_let_on_iterator)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
118
tests/ui/match_ref_pats.fixed
Normal file
118
tests/ui/match_ref_pats.fixed
Normal file
|
@ -0,0 +1,118 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::match_ref_pats)]
|
||||
#![allow(dead_code, unused_variables, clippy::equatable_if_let, clippy::enum_variant_names)]
|
||||
|
||||
fn ref_pats() {
|
||||
{
|
||||
let v = &Some(0);
|
||||
match *v {
|
||||
Some(v) => println!("{:?}", v),
|
||||
None => println!("none"),
|
||||
}
|
||||
match v {
|
||||
// This doesn't trigger; we have a different pattern.
|
||||
&Some(v) => println!("some"),
|
||||
other => println!("other"),
|
||||
}
|
||||
}
|
||||
let tup = &(1, 2);
|
||||
match tup {
|
||||
&(v, 1) => println!("{}", v),
|
||||
_ => println!("none"),
|
||||
}
|
||||
// Special case: using `&` both in expr and pats.
|
||||
let w = Some(0);
|
||||
match w {
|
||||
Some(v) => println!("{:?}", v),
|
||||
None => println!("none"),
|
||||
}
|
||||
// False positive: only wildcard pattern.
|
||||
let w = Some(0);
|
||||
#[allow(clippy::match_single_binding)]
|
||||
match w {
|
||||
_ => println!("none"),
|
||||
}
|
||||
|
||||
let a = &Some(0);
|
||||
if a.is_none() {
|
||||
println!("none");
|
||||
}
|
||||
|
||||
let b = Some(0);
|
||||
if b.is_none() {
|
||||
println!("none");
|
||||
}
|
||||
}
|
||||
|
||||
mod ice_3719 {
|
||||
macro_rules! foo_variant(
|
||||
($idx:expr) => (Foo::get($idx).unwrap())
|
||||
);
|
||||
|
||||
enum Foo {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
fn get(idx: u8) -> Option<&'static Self> {
|
||||
match idx {
|
||||
0 => Some(&Foo::A),
|
||||
1 => Some(&Foo::B),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ice_3719() {
|
||||
// ICE #3719
|
||||
match foo_variant!(0) {
|
||||
&Foo::A => println!("A"),
|
||||
_ => println!("Wild"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_7740 {
|
||||
macro_rules! foobar_variant(
|
||||
($idx:expr) => (FooBar::get($idx).unwrap())
|
||||
);
|
||||
|
||||
enum FooBar {
|
||||
Foo,
|
||||
Bar,
|
||||
FooBar,
|
||||
BarFoo,
|
||||
}
|
||||
|
||||
impl FooBar {
|
||||
fn get(idx: u8) -> Option<&'static Self> {
|
||||
match idx {
|
||||
0 => Some(&FooBar::Foo),
|
||||
1 => Some(&FooBar::Bar),
|
||||
2 => Some(&FooBar::FooBar),
|
||||
3 => Some(&FooBar::BarFoo),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn issue_7740() {
|
||||
// Issue #7740
|
||||
match *foobar_variant!(0) {
|
||||
FooBar::Foo => println!("Foo"),
|
||||
FooBar::Bar => println!("Bar"),
|
||||
FooBar::FooBar => println!("FooBar"),
|
||||
_ => println!("Wild"),
|
||||
}
|
||||
|
||||
// This shouldn't trigger
|
||||
if let &FooBar::BarFoo = foobar_variant!(3) {
|
||||
println!("BarFoo");
|
||||
} else {
|
||||
println!("Wild");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,5 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::match_ref_pats)]
|
||||
#![allow(clippy::equatable_if_let, clippy::enum_variant_names)]
|
||||
#![allow(dead_code, unused_variables, clippy::equatable_if_let, clippy::enum_variant_names)]
|
||||
|
||||
fn ref_pats() {
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: you don't need to add `&` to all patterns
|
||||
--> $DIR/match_ref_pats.rs:7:9
|
||||
--> $DIR/match_ref_pats.rs:8:9
|
||||
|
|
||||
LL | / match v {
|
||||
LL | | &Some(v) => println!("{:?}", v),
|
||||
|
@ -16,7 +16,7 @@ LL ~ None => println!("none"),
|
|||
|
|
||||
|
||||
error: you don't need to add `&` to both the expression and the patterns
|
||||
--> $DIR/match_ref_pats.rs:24:5
|
||||
--> $DIR/match_ref_pats.rs:25:5
|
||||
|
|
||||
LL | / match &w {
|
||||
LL | | &Some(v) => println!("{:?}", v),
|
||||
|
@ -32,7 +32,7 @@ LL ~ None => println!("none"),
|
|||
|
|
||||
|
||||
error: redundant pattern matching, consider using `is_none()`
|
||||
--> $DIR/match_ref_pats.rs:36:12
|
||||
--> $DIR/match_ref_pats.rs:37:12
|
||||
|
|
||||
LL | if let &None = a {
|
||||
| -------^^^^^---- help: try this: `if a.is_none()`
|
||||
|
@ -40,13 +40,13 @@ LL | if let &None = a {
|
|||
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
|
||||
|
||||
error: redundant pattern matching, consider using `is_none()`
|
||||
--> $DIR/match_ref_pats.rs:41:12
|
||||
--> $DIR/match_ref_pats.rs:42:12
|
||||
|
|
||||
LL | if let &None = &b {
|
||||
| -------^^^^^----- help: try this: `if b.is_none()`
|
||||
|
||||
error: you don't need to add `&` to all patterns
|
||||
--> $DIR/match_ref_pats.rs:101:9
|
||||
--> $DIR/match_ref_pats.rs:102:9
|
||||
|
|
||||
LL | / match foobar_variant!(0) {
|
||||
LL | | &FooBar::Foo => println!("Foo"),
|
||||
|
|
186
tests/ui/match_str_case_mismatch.fixed
Normal file
186
tests/ui/match_str_case_mismatch.fixed
Normal file
|
@ -0,0 +1,186 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::match_str_case_mismatch)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Valid
|
||||
|
||||
fn as_str_match() {
|
||||
let var = "BAR";
|
||||
|
||||
match var.to_ascii_lowercase().as_str() {
|
||||
"foo" => {},
|
||||
"bar" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn non_alphabetic() {
|
||||
let var = "~!@#$%^&*()-_=+FOO";
|
||||
|
||||
match var.to_ascii_lowercase().as_str() {
|
||||
"1234567890" => {},
|
||||
"~!@#$%^&*()-_=+foo" => {},
|
||||
"\n\r\t\x7F" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn unicode_cased() {
|
||||
let var = "ВОДЫ";
|
||||
|
||||
match var.to_lowercase().as_str() {
|
||||
"水" => {},
|
||||
"νερό" => {},
|
||||
"воды" => {},
|
||||
"물" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn titlecase() {
|
||||
let var = "BarDz";
|
||||
|
||||
match var.to_lowercase().as_str() {
|
||||
"foolj" => {},
|
||||
"bardz" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn no_case_equivalent() {
|
||||
let var = "barʁ";
|
||||
|
||||
match var.to_uppercase().as_str() {
|
||||
"FOOɕ" => {},
|
||||
"BARʁ" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn addrof_unary_match() {
|
||||
let var = "BAR";
|
||||
|
||||
match &*var.to_ascii_lowercase() {
|
||||
"foo" => {},
|
||||
"bar" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn alternating_chain() {
|
||||
let var = "BAR";
|
||||
|
||||
match &*var
|
||||
.to_ascii_lowercase()
|
||||
.to_uppercase()
|
||||
.to_lowercase()
|
||||
.to_ascii_uppercase()
|
||||
{
|
||||
"FOO" => {},
|
||||
"BAR" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn unrelated_method() {
|
||||
struct Item {
|
||||
a: String,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn to_lowercase(self) -> String {
|
||||
self.a
|
||||
}
|
||||
}
|
||||
|
||||
let item = Item { a: String::from("BAR") };
|
||||
|
||||
match &*item.to_lowercase() {
|
||||
"FOO" => {},
|
||||
"BAR" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid
|
||||
|
||||
fn as_str_match_mismatch() {
|
||||
let var = "BAR";
|
||||
|
||||
match var.to_ascii_lowercase().as_str() {
|
||||
"foo" => {},
|
||||
"bar" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn non_alphabetic_mismatch() {
|
||||
let var = "~!@#$%^&*()-_=+FOO";
|
||||
|
||||
match var.to_ascii_lowercase().as_str() {
|
||||
"1234567890" => {},
|
||||
"~!@#$%^&*()-_=+foo" => {},
|
||||
"\n\r\t\x7F" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn unicode_cased_mismatch() {
|
||||
let var = "ВОДЫ";
|
||||
|
||||
match var.to_lowercase().as_str() {
|
||||
"水" => {},
|
||||
"νερό" => {},
|
||||
"воды" => {},
|
||||
"물" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn titlecase_mismatch() {
|
||||
let var = "BarDz";
|
||||
|
||||
match var.to_lowercase().as_str() {
|
||||
"foolj" => {},
|
||||
"bardz" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn no_case_equivalent_mismatch() {
|
||||
let var = "barʁ";
|
||||
|
||||
match var.to_uppercase().as_str() {
|
||||
"FOOɕ" => {},
|
||||
"BARʁ" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn addrof_unary_match_mismatch() {
|
||||
let var = "BAR";
|
||||
|
||||
match &*var.to_ascii_lowercase() {
|
||||
"foo" => {},
|
||||
"bar" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn alternating_chain_mismatch() {
|
||||
let var = "BAR";
|
||||
|
||||
match &*var
|
||||
.to_ascii_lowercase()
|
||||
.to_uppercase()
|
||||
.to_lowercase()
|
||||
.to_ascii_uppercase()
|
||||
{
|
||||
"FOO" => {},
|
||||
"BAR" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,4 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::match_str_case_mismatch)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Valid
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:111:9
|
||||
--> $DIR/match_str_case_mismatch.rs:113:9
|
||||
|
|
||||
LL | "Bar" => {},
|
||||
| ^^^^^
|
||||
|
@ -11,7 +11,7 @@ LL | "bar" => {},
|
|||
| ~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:121:9
|
||||
--> $DIR/match_str_case_mismatch.rs:123:9
|
||||
|
|
||||
LL | "~!@#$%^&*()-_=+Foo" => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -22,7 +22,7 @@ LL | "~!@#$%^&*()-_=+foo" => {},
|
|||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:133:9
|
||||
--> $DIR/match_str_case_mismatch.rs:135:9
|
||||
|
|
||||
LL | "Воды" => {},
|
||||
| ^^^^^^
|
||||
|
@ -33,7 +33,7 @@ LL | "воды" => {},
|
|||
| ~~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:144:9
|
||||
--> $DIR/match_str_case_mismatch.rs:146:9
|
||||
|
|
||||
LL | "barDz" => {},
|
||||
| ^^^^^^
|
||||
|
@ -44,7 +44,7 @@ LL | "bardz" => {},
|
|||
| ~~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:154:9
|
||||
--> $DIR/match_str_case_mismatch.rs:156:9
|
||||
|
|
||||
LL | "bARʁ" => {},
|
||||
| ^^^^^^
|
||||
|
@ -55,7 +55,7 @@ LL | "BARʁ" => {},
|
|||
| ~~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:164:9
|
||||
--> $DIR/match_str_case_mismatch.rs:166:9
|
||||
|
|
||||
LL | "Bar" => {},
|
||||
| ^^^^^
|
||||
|
@ -66,7 +66,7 @@ LL | "bar" => {},
|
|||
| ~~~~~
|
||||
|
||||
error: this `match` arm has a differing case than its expression
|
||||
--> $DIR/match_str_case_mismatch.rs:179:9
|
||||
--> $DIR/match_str_case_mismatch.rs:181:9
|
||||
|
|
||||
LL | "bAR" => {},
|
||||
| ^^^^^
|
||||
|
|
232
tests/ui/needless_late_init.fixed
Normal file
232
tests/ui/needless_late_init.fixed
Normal file
|
@ -0,0 +1,232 @@
|
|||
// run-rustfix
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused, clippy::nonminimal_bool, clippy::let_unit_value, clippy::let_and_return)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
struct SignificantDrop;
|
||||
impl std::ops::Drop for SignificantDrop {
|
||||
fn drop(&mut self) {
|
||||
println!("dropped");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let n = 1;
|
||||
let a = match n {
|
||||
1 => "one",
|
||||
_ => {
|
||||
"two"
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
let b = if n == 3 {
|
||||
"four"
|
||||
} else {
|
||||
"five"
|
||||
};
|
||||
|
||||
|
||||
let d = if true {
|
||||
let temp = 5;
|
||||
temp
|
||||
} else {
|
||||
15
|
||||
};
|
||||
|
||||
|
||||
let e = if true {
|
||||
format!("{} {}", a, b)
|
||||
} else {
|
||||
format!("{}", n)
|
||||
};
|
||||
|
||||
|
||||
let f = match 1 {
|
||||
1 => "three",
|
||||
_ => return,
|
||||
}; // has semi
|
||||
|
||||
|
||||
let g: usize = if true {
|
||||
5
|
||||
} else {
|
||||
panic!();
|
||||
};
|
||||
|
||||
// Drop order only matters if both are significant
|
||||
|
||||
let y = SignificantDrop;
|
||||
let x = 1;
|
||||
|
||||
|
||||
let y = 1;
|
||||
let x = SignificantDrop;
|
||||
|
||||
|
||||
// types that should be considered insignificant
|
||||
let y = 1;
|
||||
let y = "2";
|
||||
let y = String::new();
|
||||
let y = vec![3.0];
|
||||
let y = HashMap::<usize, usize>::new();
|
||||
let y = BTreeMap::<usize, usize>::new();
|
||||
let y = HashSet::<usize>::new();
|
||||
let y = BTreeSet::<usize>::new();
|
||||
let y = Box::new(4);
|
||||
let x = SignificantDrop;
|
||||
}
|
||||
|
||||
async fn in_async() -> &'static str {
|
||||
async fn f() -> &'static str {
|
||||
"one"
|
||||
}
|
||||
|
||||
|
||||
let n = 1;
|
||||
let a = match n {
|
||||
1 => f().await,
|
||||
_ => {
|
||||
"two"
|
||||
},
|
||||
};
|
||||
|
||||
a
|
||||
}
|
||||
|
||||
const fn in_const() -> &'static str {
|
||||
const fn f() -> &'static str {
|
||||
"one"
|
||||
}
|
||||
|
||||
|
||||
let n = 1;
|
||||
let a = match n {
|
||||
1 => f(),
|
||||
_ => {
|
||||
"two"
|
||||
},
|
||||
};
|
||||
|
||||
a
|
||||
}
|
||||
|
||||
fn does_not_lint() {
|
||||
let z;
|
||||
if false {
|
||||
z = 1;
|
||||
}
|
||||
|
||||
let x;
|
||||
let y;
|
||||
if true {
|
||||
x = 1;
|
||||
} else {
|
||||
y = 1;
|
||||
}
|
||||
|
||||
let mut x;
|
||||
if true {
|
||||
x = 5;
|
||||
x = 10 / x;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
let x;
|
||||
let _ = match 1 {
|
||||
1 => x = 10,
|
||||
_ => x = 20,
|
||||
};
|
||||
|
||||
// using tuples would be possible, but not always preferable
|
||||
let x;
|
||||
let y;
|
||||
if true {
|
||||
x = 1;
|
||||
y = 2;
|
||||
} else {
|
||||
x = 3;
|
||||
y = 4;
|
||||
}
|
||||
|
||||
// could match with a smarter heuristic to avoid multiple assignments
|
||||
let x;
|
||||
if true {
|
||||
let mut y = 5;
|
||||
y = 6;
|
||||
x = y;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
let (x, y);
|
||||
if true {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
y = 3;
|
||||
|
||||
macro_rules! assign {
|
||||
($i:ident) => {
|
||||
$i = 1;
|
||||
};
|
||||
}
|
||||
let x;
|
||||
assign!(x);
|
||||
|
||||
let x;
|
||||
if true {
|
||||
assign!(x);
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
macro_rules! in_macro {
|
||||
() => {
|
||||
let x;
|
||||
x = 1;
|
||||
|
||||
let x;
|
||||
if true {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
in_macro!();
|
||||
|
||||
// ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613
|
||||
let x;
|
||||
if let Some(n) = Some("v") {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
let x;
|
||||
if true && let Some(n) = Some("let chains too") {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
// ignore mut bindings
|
||||
// https://github.com/shepmaster/twox-hash/blob/b169c16d86eb8ea4a296b0acb9d00ca7e3c3005f/src/sixty_four.rs#L88-L93
|
||||
// https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/tests/test_generics.rs#L91-L100
|
||||
let mut x: usize;
|
||||
x = 1;
|
||||
x = 2;
|
||||
x = 3;
|
||||
|
||||
// should not move the declaration if `x` has a significant drop, and there
|
||||
// is another binding with a significant drop between it and the first usage
|
||||
let x;
|
||||
let y = SignificantDrop;
|
||||
x = SignificantDrop;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// run-rustfix
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused, clippy::nonminimal_bool, clippy::let_unit_value)]
|
||||
#![allow(unused, clippy::nonminimal_bool, clippy::let_unit_value, clippy::let_and_return)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:15:5
|
||||
--> $DIR/needless_late_init.rs:16:5
|
||||
|
|
||||
LL | let a;
|
||||
| ^^^^^^
|
||||
|
@ -21,7 +21,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:24:5
|
||||
--> $DIR/needless_late_init.rs:25:5
|
||||
|
|
||||
LL | let b;
|
||||
| ^^^^^^
|
||||
|
@ -42,7 +42,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:31:5
|
||||
--> $DIR/needless_late_init.rs:32:5
|
||||
|
|
||||
LL | let d;
|
||||
| ^^^^^^
|
||||
|
@ -63,7 +63,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:39:5
|
||||
--> $DIR/needless_late_init.rs:40:5
|
||||
|
|
||||
LL | let e;
|
||||
| ^^^^^^
|
||||
|
@ -84,7 +84,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:46:5
|
||||
--> $DIR/needless_late_init.rs:47:5
|
||||
|
|
||||
LL | let f;
|
||||
| ^^^^^^
|
||||
|
@ -100,7 +100,7 @@ LL + 1 => "three",
|
|||
|
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:52:5
|
||||
--> $DIR/needless_late_init.rs:53:5
|
||||
|
|
||||
LL | let g: usize;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
@ -120,7 +120,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:60:5
|
||||
--> $DIR/needless_late_init.rs:61:5
|
||||
|
|
||||
LL | let x;
|
||||
| ^^^^^^ created here
|
||||
|
@ -134,7 +134,7 @@ LL | let x = 1;
|
|||
| ~~~~~
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:64:5
|
||||
--> $DIR/needless_late_init.rs:65:5
|
||||
|
|
||||
LL | let x;
|
||||
| ^^^^^^ created here
|
||||
|
@ -148,7 +148,7 @@ LL | let x = SignificantDrop;
|
|||
| ~~~~~
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:68:5
|
||||
--> $DIR/needless_late_init.rs:69:5
|
||||
|
|
||||
LL | let x;
|
||||
| ^^^^^^ created here
|
||||
|
@ -162,7 +162,7 @@ LL | let x = SignificantDrop;
|
|||
| ~~~~~
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:87:5
|
||||
--> $DIR/needless_late_init.rs:88:5
|
||||
|
|
||||
LL | let a;
|
||||
| ^^^^^^
|
||||
|
@ -183,7 +183,7 @@ LL | };
|
|||
| +
|
||||
|
||||
error: unneeded late initialization
|
||||
--> $DIR/needless_late_init.rs:104:5
|
||||
--> $DIR/needless_late_init.rs:105:5
|
||||
|
|
||||
LL | let a;
|
||||
| ^^^^^^
|
||||
|
|
111
tests/ui/nonminimal_bool_methods.fixed
Normal file
111
tests/ui/nonminimal_bool_methods.fixed
Normal file
|
@ -0,0 +1,111 @@
|
|||
// run-rustfix
|
||||
#![allow(unused, clippy::diverging_sub_expression)]
|
||||
#![warn(clippy::nonminimal_bool)]
|
||||
|
||||
fn methods_with_negation() {
|
||||
let a: Option<i32> = unimplemented!();
|
||||
let b: Result<i32, i32> = unimplemented!();
|
||||
let _ = a.is_some();
|
||||
let _ = a.is_none();
|
||||
let _ = a.is_none();
|
||||
let _ = a.is_some();
|
||||
let _ = b.is_err();
|
||||
let _ = b.is_ok();
|
||||
let _ = b.is_ok();
|
||||
let _ = b.is_err();
|
||||
let c = false;
|
||||
let _ = a.is_none() || c;
|
||||
let _ = a.is_none() && c;
|
||||
let _ = !(!c ^ c) || a.is_none();
|
||||
let _ = (!c ^ c) || a.is_none();
|
||||
let _ = !c ^ c || a.is_none();
|
||||
}
|
||||
|
||||
// Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638
|
||||
// clippy::nonminimal_bool should only check the built-in Result and Some type, not
|
||||
// any other types like the following.
|
||||
enum CustomResultOk<E> {
|
||||
Ok,
|
||||
Err(E),
|
||||
}
|
||||
enum CustomResultErr<E> {
|
||||
Ok,
|
||||
Err(E),
|
||||
}
|
||||
enum CustomSomeSome<T> {
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
enum CustomSomeNone<T> {
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<E> CustomResultOk<E> {
|
||||
pub fn is_ok(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> CustomResultErr<E> {
|
||||
pub fn is_err(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CustomSomeSome<T> {
|
||||
pub fn is_some(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CustomSomeNone<T> {
|
||||
pub fn is_none(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn dont_warn_for_custom_methods_with_negation() {
|
||||
let res = CustomResultOk::Err("Error");
|
||||
// Should not warn and suggest 'is_err()' because the type does not
|
||||
// implement is_err().
|
||||
if !res.is_ok() {}
|
||||
|
||||
let res = CustomResultErr::Err("Error");
|
||||
// Should not warn and suggest 'is_ok()' because the type does not
|
||||
// implement is_ok().
|
||||
if !res.is_err() {}
|
||||
|
||||
let res = CustomSomeSome::Some("thing");
|
||||
// Should not warn and suggest 'is_none()' because the type does not
|
||||
// implement is_none().
|
||||
if !res.is_some() {}
|
||||
|
||||
let res = CustomSomeNone::Some("thing");
|
||||
// Should not warn and suggest 'is_some()' because the type does not
|
||||
// implement is_some().
|
||||
if !res.is_none() {}
|
||||
}
|
||||
|
||||
// Only Built-in Result and Some types should suggest the negated alternative
|
||||
fn warn_for_built_in_methods_with_negation() {
|
||||
let res: Result<usize, usize> = Ok(1);
|
||||
if res.is_err() {}
|
||||
if res.is_ok() {}
|
||||
|
||||
let res = Some(1);
|
||||
if res.is_none() {}
|
||||
if res.is_some() {}
|
||||
}
|
||||
|
||||
#[allow(clippy::neg_cmp_op_on_partial_ord)]
|
||||
fn dont_warn_for_negated_partial_ord_comparison() {
|
||||
let a: f64 = unimplemented!();
|
||||
let b: f64 = unimplemented!();
|
||||
let _ = !(a < b);
|
||||
let _ = !(a <= b);
|
||||
let _ = !(a > b);
|
||||
let _ = !(a >= b);
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
#![allow(unused, clippy::diverging_sub_expression)]
|
||||
#![warn(clippy::nonminimal_bool)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:8:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:9:13
|
||||
|
|
||||
LL | let _ = !a.is_some();
|
||||
| ^^^^^^^^^^^^ help: try: `a.is_none()`
|
||||
|
@ -7,73 +7,73 @@ LL | let _ = !a.is_some();
|
|||
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:10:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:11:13
|
||||
|
|
||||
LL | let _ = !a.is_none();
|
||||
| ^^^^^^^^^^^^ help: try: `a.is_some()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:12:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:13:13
|
||||
|
|
||||
LL | let _ = !b.is_err();
|
||||
| ^^^^^^^^^^^ help: try: `b.is_ok()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:14:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:15:13
|
||||
|
|
||||
LL | let _ = !b.is_ok();
|
||||
| ^^^^^^^^^^ help: try: `b.is_err()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:16:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:17:13
|
||||
|
|
||||
LL | let _ = !(a.is_some() && !c);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:17:13
|
||||
--> $DIR/nonminimal_bool_methods.rs:18:13
|
||||
|
|
||||
LL | let _ = !(a.is_some() || !c);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:18:26
|
||||
--> $DIR/nonminimal_bool_methods.rs:19:26
|
||||
|
|
||||
LL | let _ = !(!c ^ c) || !a.is_some();
|
||||
| ^^^^^^^^^^^^ help: try: `a.is_none()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:19:25
|
||||
--> $DIR/nonminimal_bool_methods.rs:20:25
|
||||
|
|
||||
LL | let _ = (!c ^ c) || !a.is_some();
|
||||
| ^^^^^^^^^^^^ help: try: `a.is_none()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:20:23
|
||||
--> $DIR/nonminimal_bool_methods.rs:21:23
|
||||
|
|
||||
LL | let _ = !c ^ c || !a.is_some();
|
||||
| ^^^^^^^^^^^^ help: try: `a.is_none()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:92:8
|
||||
--> $DIR/nonminimal_bool_methods.rs:93:8
|
||||
|
|
||||
LL | if !res.is_ok() {}
|
||||
| ^^^^^^^^^^^^ help: try: `res.is_err()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:93:8
|
||||
--> $DIR/nonminimal_bool_methods.rs:94:8
|
||||
|
|
||||
LL | if !res.is_err() {}
|
||||
| ^^^^^^^^^^^^^ help: try: `res.is_ok()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:96:8
|
||||
--> $DIR/nonminimal_bool_methods.rs:97:8
|
||||
|
|
||||
LL | if !res.is_some() {}
|
||||
| ^^^^^^^^^^^^^^ help: try: `res.is_none()`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool_methods.rs:97:8
|
||||
--> $DIR/nonminimal_bool_methods.rs:98:8
|
||||
|
|
||||
LL | if !res.is_none() {}
|
||||
| ^^^^^^^^^^^^^^ help: try: `res.is_some()`
|
||||
|
|
28
tests/ui/rc_buffer.fixed
Normal file
28
tests/ui/rc_buffer.fixed
Normal file
|
@ -0,0 +1,28 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::rc_buffer)]
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
struct S {
|
||||
// triggers lint
|
||||
bad1: Rc<str>,
|
||||
bad2: Rc<std::path::Path>,
|
||||
bad3: Rc<[u8]>,
|
||||
bad4: Rc<std::ffi::OsStr>,
|
||||
// does not trigger lint
|
||||
good1: Rc<RefCell<String>>,
|
||||
}
|
||||
|
||||
// triggers lint
|
||||
fn func_bad1(_: Rc<str>) {}
|
||||
fn func_bad2(_: Rc<std::path::Path>) {}
|
||||
fn func_bad3(_: Rc<[u8]>) {}
|
||||
fn func_bad4(_: Rc<std::ffi::OsStr>) {}
|
||||
// does not trigger lint
|
||||
fn func_good1(_: Rc<RefCell<String>>) {}
|
||||
|
||||
fn main() {}
|
|
@ -1,4 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::rc_buffer)]
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsString;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:10:11
|
||||
--> $DIR/rc_buffer.rs:12:11
|
||||
|
|
||||
LL | bad1: Rc<String>,
|
||||
| ^^^^^^^^^^ help: try: `Rc<str>`
|
||||
|
@ -7,43 +7,43 @@ LL | bad1: Rc<String>,
|
|||
= note: `-D clippy::rc-buffer` implied by `-D warnings`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:11:11
|
||||
--> $DIR/rc_buffer.rs:13:11
|
||||
|
|
||||
LL | bad2: Rc<PathBuf>,
|
||||
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:12:11
|
||||
--> $DIR/rc_buffer.rs:14:11
|
||||
|
|
||||
LL | bad3: Rc<Vec<u8>>,
|
||||
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:13:11
|
||||
--> $DIR/rc_buffer.rs:15:11
|
||||
|
|
||||
LL | bad4: Rc<OsString>,
|
||||
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:19:17
|
||||
--> $DIR/rc_buffer.rs:21:17
|
||||
|
|
||||
LL | fn func_bad1(_: Rc<String>) {}
|
||||
| ^^^^^^^^^^ help: try: `Rc<str>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:20:17
|
||||
--> $DIR/rc_buffer.rs:22:17
|
||||
|
|
||||
LL | fn func_bad2(_: Rc<PathBuf>) {}
|
||||
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:21:17
|
||||
--> $DIR/rc_buffer.rs:23:17
|
||||
|
|
||||
LL | fn func_bad3(_: Rc<Vec<u8>>) {}
|
||||
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
|
||||
|
||||
error: usage of `Rc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer.rs:22:17
|
||||
--> $DIR/rc_buffer.rs:24:17
|
||||
|
|
||||
LL | fn func_bad4(_: Rc<OsString>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
|
||||
|
|
27
tests/ui/rc_buffer_arc.fixed
Normal file
27
tests/ui/rc_buffer_arc.fixed
Normal file
|
@ -0,0 +1,27 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::rc_buffer)]
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
struct S {
|
||||
// triggers lint
|
||||
bad1: Arc<str>,
|
||||
bad2: Arc<std::path::Path>,
|
||||
bad3: Arc<[u8]>,
|
||||
bad4: Arc<std::ffi::OsStr>,
|
||||
// does not trigger lint
|
||||
good1: Arc<Mutex<String>>,
|
||||
}
|
||||
|
||||
// triggers lint
|
||||
fn func_bad1(_: Arc<str>) {}
|
||||
fn func_bad2(_: Arc<std::path::Path>) {}
|
||||
fn func_bad3(_: Arc<[u8]>) {}
|
||||
fn func_bad4(_: Arc<std::ffi::OsStr>) {}
|
||||
// does not trigger lint
|
||||
fn func_good1(_: Arc<Mutex<String>>) {}
|
||||
|
||||
fn main() {}
|
|
@ -1,4 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::rc_buffer)]
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:9:11
|
||||
--> $DIR/rc_buffer_arc.rs:11:11
|
||||
|
|
||||
LL | bad1: Arc<String>,
|
||||
| ^^^^^^^^^^^ help: try: `Arc<str>`
|
||||
|
@ -7,43 +7,43 @@ LL | bad1: Arc<String>,
|
|||
= note: `-D clippy::rc-buffer` implied by `-D warnings`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:10:11
|
||||
--> $DIR/rc_buffer_arc.rs:12:11
|
||||
|
|
||||
LL | bad2: Arc<PathBuf>,
|
||||
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:11:11
|
||||
--> $DIR/rc_buffer_arc.rs:13:11
|
||||
|
|
||||
LL | bad3: Arc<Vec<u8>>,
|
||||
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:12:11
|
||||
--> $DIR/rc_buffer_arc.rs:14:11
|
||||
|
|
||||
LL | bad4: Arc<OsString>,
|
||||
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:18:17
|
||||
--> $DIR/rc_buffer_arc.rs:20:17
|
||||
|
|
||||
LL | fn func_bad1(_: Arc<String>) {}
|
||||
| ^^^^^^^^^^^ help: try: `Arc<str>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:19:17
|
||||
--> $DIR/rc_buffer_arc.rs:21:17
|
||||
|
|
||||
LL | fn func_bad2(_: Arc<PathBuf>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:20:17
|
||||
--> $DIR/rc_buffer_arc.rs:22:17
|
||||
|
|
||||
LL | fn func_bad3(_: Arc<Vec<u8>>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
|
||||
|
||||
error: usage of `Arc<T>` when T is a buffer type
|
||||
--> $DIR/rc_buffer_arc.rs:21:17
|
||||
--> $DIR/rc_buffer_arc.rs:23:17
|
||||
|
|
||||
LL | fn func_bad4(_: Arc<OsString>) {}
|
||||
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
|
||||
|
|
209
tests/ui/suspicious_operation_groupings.fixed
Normal file
209
tests/ui/suspicious_operation_groupings.fixed
Normal file
|
@ -0,0 +1,209 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::suspicious_operation_groupings)]
|
||||
#![allow(dead_code, unused_parens, clippy::eq_op)]
|
||||
|
||||
struct Vec3 {
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
}
|
||||
|
||||
impl Eq for Vec3 {}
|
||||
|
||||
impl PartialEq for Vec3 {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// This should trigger the lint because `self.x` is compared to `other.y`
|
||||
self.x == other.x && self.y == other.y && self.z == other.z
|
||||
}
|
||||
}
|
||||
|
||||
struct S {
|
||||
a: i32,
|
||||
b: i32,
|
||||
c: i32,
|
||||
d: i32,
|
||||
}
|
||||
|
||||
fn buggy_ab_cmp(s1: &S, s2: &S) -> bool {
|
||||
// There's no `s1.b`
|
||||
s1.a < s2.a && s1.b < s2.b
|
||||
}
|
||||
|
||||
struct SaOnly {
|
||||
a: i32,
|
||||
}
|
||||
|
||||
impl S {
|
||||
fn a(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn do_not_give_bad_suggestions_for_this_unusual_expr(s1: &S, s2: &SaOnly) -> bool {
|
||||
// This is superficially similar to `buggy_ab_cmp`, but we should not suggest
|
||||
// `s2.b` since that is invalid.
|
||||
s1.a < s2.a && s1.a() < s1.b
|
||||
}
|
||||
|
||||
fn do_not_give_bad_suggestions_for_this_macro_expr(s1: &S, s2: &SaOnly) -> bool {
|
||||
macro_rules! s1 {
|
||||
() => {
|
||||
S {
|
||||
a: 1,
|
||||
b: 1,
|
||||
c: 1,
|
||||
d: 1,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// This is superficially similar to `buggy_ab_cmp`, but we should not suggest
|
||||
// `s2.b` since that is invalid.
|
||||
s1.a < s2.a && s1!().a < s1.b
|
||||
}
|
||||
|
||||
fn do_not_give_bad_suggestions_for_this_incorrect_expr(s1: &S, s2: &SaOnly) -> bool {
|
||||
// There's two `s1.b`, but we should not suggest `s2.b` since that is invalid
|
||||
s1.a < s2.a && s1.b < s1.b
|
||||
}
|
||||
|
||||
fn permissable(s1: &S, s2: &S) -> bool {
|
||||
// Something like this seems like it might actually be what is desired.
|
||||
s1.a == s2.b
|
||||
}
|
||||
|
||||
fn non_boolean_operators(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d
|
||||
}
|
||||
|
||||
fn odd_number_of_pairs(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.b`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
|
||||
}
|
||||
|
||||
fn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s1.b`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
|
||||
}
|
||||
|
||||
fn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.b`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
|
||||
}
|
||||
|
||||
fn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.a`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
|
||||
}
|
||||
|
||||
fn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
|
||||
}
|
||||
|
||||
fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) {
|
||||
(
|
||||
s1.b * s2.c - s1.c * s2.b,
|
||||
s1.c * s2.a - s1.a * s2.c,
|
||||
s1.a * s2.b - s1.b * s2.a,
|
||||
)
|
||||
}
|
||||
|
||||
fn outer_parens_simple(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.b`
|
||||
(s1.a * s2.a + s1.b * s2.b)
|
||||
}
|
||||
|
||||
fn outer_parens(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
(s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d)
|
||||
}
|
||||
|
||||
fn inner_parens(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
(s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)
|
||||
}
|
||||
|
||||
fn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d))
|
||||
}
|
||||
|
||||
fn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
(((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.c) + (s1.d * s2.d)))
|
||||
}
|
||||
|
||||
fn all_parens_left_tree(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
(((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c)) + (s1.d * s2.d))
|
||||
}
|
||||
|
||||
fn all_parens_right_tree(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)))
|
||||
}
|
||||
|
||||
fn inside_other_binop_expression(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s1.b`
|
||||
(s1.a * s2.a + s1.b * s2.b) / 2
|
||||
}
|
||||
|
||||
fn inside_function_call(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s1.b`
|
||||
i32::swap_bytes(s1.a * s2.a + s1.b * s2.b)
|
||||
}
|
||||
|
||||
fn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool {
|
||||
// There's no `s1.c`
|
||||
s1.a > 0 && s1.b > 0 && s1.c == s2.c && s1.d == s2.d
|
||||
}
|
||||
|
||||
fn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool {
|
||||
// There's no `s1.c`
|
||||
s1.a > 0 && s1.c == s2.c && s1.b > 0 && s1.d == s2.d
|
||||
}
|
||||
|
||||
struct Nested {
|
||||
inner: ((i32,), (i32,), (i32,)),
|
||||
}
|
||||
|
||||
fn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool {
|
||||
// There's no `n2.inner.2.0`
|
||||
(n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
|
||||
}
|
||||
|
||||
// `eq_op` should catch this one.
|
||||
fn changed_initial_ident(n1: &Nested, n2: &Nested) -> bool {
|
||||
// There's no `n2.inner.0.0`
|
||||
(n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
|
||||
}
|
||||
|
||||
fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool {
|
||||
if strict {
|
||||
s1.a < s2.a && s1.b < s2.b
|
||||
} else {
|
||||
// There's no `s1.b` in this subexpression
|
||||
s1.a <= s2.a && s1.b <= s2.b
|
||||
}
|
||||
}
|
||||
|
||||
fn inside_an_if_statement(s1: &mut S, s2: &S) {
|
||||
// There's no `s1.b`
|
||||
if s1.a < s2.a && s1.b < s2.b {
|
||||
s1.c = s2.c;
|
||||
}
|
||||
}
|
||||
|
||||
fn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s2.c`
|
||||
-(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.c) + -(-s1.d * -s2.d)))
|
||||
}
|
||||
|
||||
fn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 {
|
||||
// There's no `s1.b`
|
||||
-(if -s1.a < -s2.a && -s1.b < -s2.b { s1.c } else { s2.a })
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,5 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::suspicious_operation_groupings)]
|
||||
#![allow(clippy::eq_op)]
|
||||
#![allow(dead_code, unused_parens, clippy::eq_op)]
|
||||
|
||||
struct Vec3 {
|
||||
x: f64,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:15:9
|
||||
--> $DIR/suspicious_operation_groupings.rs:16:9
|
||||
|
|
||||
LL | self.x == other.y && self.y == other.y && self.z == other.z
|
||||
| ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`
|
||||
|
@ -7,151 +7,151 @@ LL | self.x == other.y && self.y == other.y && self.z == other.z
|
|||
= note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:28:20
|
||||
--> $DIR/suspicious_operation_groupings.rs:29:20
|
||||
|
|
||||
LL | s1.a < s2.a && s1.a < s2.b
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:76:33
|
||||
--> $DIR/suspicious_operation_groupings.rs:77:33
|
||||
|
|
||||
LL | s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:81:19
|
||||
--> $DIR/suspicious_operation_groupings.rs:82:19
|
||||
|
|
||||
LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:81:19
|
||||
--> $DIR/suspicious_operation_groupings.rs:82:19
|
||||
|
|
||||
LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:86:19
|
||||
--> $DIR/suspicious_operation_groupings.rs:87:19
|
||||
|
|
||||
LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:91:19
|
||||
--> $DIR/suspicious_operation_groupings.rs:92:19
|
||||
|
|
||||
LL | s1.a * s2.a + s1.b * s1.b + s1.c * s2.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:96:5
|
||||
--> $DIR/suspicious_operation_groupings.rs:97:5
|
||||
|
|
||||
LL | s1.a * s1.a + s1.b * s2.b + s1.c * s2.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:101:33
|
||||
--> $DIR/suspicious_operation_groupings.rs:102:33
|
||||
|
|
||||
LL | s1.a * s2.a + s1.b * s2.b + s1.c * s1.c
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:114:20
|
||||
--> $DIR/suspicious_operation_groupings.rs:115:20
|
||||
|
|
||||
LL | (s1.a * s2.a + s1.b * s1.b)
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:119:34
|
||||
--> $DIR/suspicious_operation_groupings.rs:120:34
|
||||
|
|
||||
LL | (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:124:38
|
||||
--> $DIR/suspicious_operation_groupings.rs:125:38
|
||||
|
|
||||
LL | (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:129:39
|
||||
--> $DIR/suspicious_operation_groupings.rs:130:39
|
||||
|
|
||||
LL | ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:134:42
|
||||
--> $DIR/suspicious_operation_groupings.rs:135:42
|
||||
|
|
||||
LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:134:42
|
||||
--> $DIR/suspicious_operation_groupings.rs:135:42
|
||||
|
|
||||
LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:139:40
|
||||
--> $DIR/suspicious_operation_groupings.rs:140:40
|
||||
|
|
||||
LL | (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:144:40
|
||||
--> $DIR/suspicious_operation_groupings.rs:145:40
|
||||
|
|
||||
LL | ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:149:20
|
||||
--> $DIR/suspicious_operation_groupings.rs:150:20
|
||||
|
|
||||
LL | (s1.a * s2.a + s2.b * s2.b) / 2
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:154:35
|
||||
--> $DIR/suspicious_operation_groupings.rs:155:35
|
||||
|
|
||||
LL | i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:159:29
|
||||
--> $DIR/suspicious_operation_groupings.rs:160:29
|
||||
|
|
||||
LL | s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d
|
||||
| ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:164:17
|
||||
--> $DIR/suspicious_operation_groupings.rs:165:17
|
||||
|
|
||||
LL | s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d
|
||||
| ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:173:77
|
||||
--> $DIR/suspicious_operation_groupings.rs:174:77
|
||||
|
|
||||
LL | (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:187:25
|
||||
--> $DIR/suspicious_operation_groupings.rs:188:25
|
||||
|
|
||||
LL | s1.a <= s2.a && s1.a <= s2.b
|
||||
| ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:193:23
|
||||
--> $DIR/suspicious_operation_groupings.rs:194:23
|
||||
|
|
||||
LL | if s1.a < s2.a && s1.a < s2.b {
|
||||
| ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:200:48
|
||||
--> $DIR/suspicious_operation_groupings.rs:201:48
|
||||
|
|
||||
LL | -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))
|
||||
| ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`
|
||||
|
||||
error: this sequence of operators looks suspiciously like a bug
|
||||
--> $DIR/suspicious_operation_groupings.rs:205:27
|
||||
--> $DIR/suspicious_operation_groupings.rs:206:27
|
||||
|
|
||||
LL | -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })
|
||||
| ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`
|
||||
|
|
36
tests/ui/unicode.fixed
Normal file
36
tests/ui/unicode.fixed
Normal file
|
@ -0,0 +1,36 @@
|
|||
// run-rustfix
|
||||
#[warn(clippy::invisible_characters)]
|
||||
fn zero() {
|
||||
print!("Here >\u{200B}< is a ZWS, and \u{200B}another");
|
||||
print!("This\u{200B}is\u{200B}fine");
|
||||
print!("Here >\u{AD}< is a SHY, and \u{AD}another");
|
||||
print!("This\u{ad}is\u{ad}fine");
|
||||
print!("Here >\u{2060}< is a WJ, and \u{2060}another");
|
||||
print!("This\u{2060}is\u{2060}fine");
|
||||
}
|
||||
|
||||
#[warn(clippy::unicode_not_nfc)]
|
||||
fn canon() {
|
||||
print!("̀àh?");
|
||||
print!("a\u{0300}h?"); // also ok
|
||||
}
|
||||
|
||||
#[warn(clippy::non_ascii_literal)]
|
||||
fn uni() {
|
||||
print!("\u{dc}ben!");
|
||||
print!("\u{DC}ben!"); // this is ok
|
||||
}
|
||||
|
||||
// issue 8013
|
||||
#[warn(clippy::non_ascii_literal)]
|
||||
fn single_quote() {
|
||||
const _EMPTY_BLOCK: char = '\u{25b1}';
|
||||
const _FULL_BLOCK: char = '\u{25b0}';
|
||||
}
|
||||
|
||||
fn main() {
|
||||
zero();
|
||||
uni();
|
||||
canon();
|
||||
single_quote();
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
#[warn(clippy::invisible_characters)]
|
||||
fn zero() {
|
||||
print!("Here >< is a ZWS, and another");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: invisible character detected
|
||||
--> $DIR/unicode.rs:3:12
|
||||
--> $DIR/unicode.rs:4:12
|
||||
|
|
||||
LL | print!("Here >< is a ZWS, and another");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"`
|
||||
|
@ -7,19 +7,19 @@ LL | print!("Here >< is a ZWS, and another");
|
|||
= note: `-D clippy::invisible-characters` implied by `-D warnings`
|
||||
|
||||
error: invisible character detected
|
||||
--> $DIR/unicode.rs:5:12
|
||||
--> $DIR/unicode.rs:6:12
|
||||
|
|
||||
LL | print!("Here >< is a SHY, and another");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"`
|
||||
|
||||
error: invisible character detected
|
||||
--> $DIR/unicode.rs:7:12
|
||||
--> $DIR/unicode.rs:8:12
|
||||
|
|
||||
LL | print!("Here >< is a WJ, and another");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"`
|
||||
|
||||
error: non-NFC Unicode sequence detected
|
||||
--> $DIR/unicode.rs:13:12
|
||||
--> $DIR/unicode.rs:14:12
|
||||
|
|
||||
LL | print!("̀àh?");
|
||||
| ^^^^^ help: consider replacing the string with: `"̀àh?"`
|
||||
|
@ -27,7 +27,7 @@ LL | print!("̀àh?");
|
|||
= note: `-D clippy::unicode-not-nfc` implied by `-D warnings`
|
||||
|
||||
error: literal non-ASCII character detected
|
||||
--> $DIR/unicode.rs:19:12
|
||||
--> $DIR/unicode.rs:20:12
|
||||
|
|
||||
LL | print!("Üben!");
|
||||
| ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
|
||||
|
@ -35,13 +35,13 @@ LL | print!("Üben!");
|
|||
= note: `-D clippy::non-ascii-literal` implied by `-D warnings`
|
||||
|
||||
error: literal non-ASCII character detected
|
||||
--> $DIR/unicode.rs:26:32
|
||||
--> $DIR/unicode.rs:27:32
|
||||
|
|
||||
LL | const _EMPTY_BLOCK: char = '▱';
|
||||
| ^^^ help: consider replacing the string with: `'/u{25b1}'`
|
||||
|
||||
error: literal non-ASCII character detected
|
||||
--> $DIR/unicode.rs:27:31
|
||||
--> $DIR/unicode.rs:28:31
|
||||
|
|
||||
LL | const _FULL_BLOCK: char = '▰';
|
||||
| ^^^ help: consider replacing the string with: `'/u{25b0}'`
|
||||
|
|
30
tests/ui/unit_arg_empty_blocks.fixed
Normal file
30
tests/ui/unit_arg_empty_blocks.fixed
Normal file
|
@ -0,0 +1,30 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::unit_arg)]
|
||||
#![allow(clippy::no_effect, unused_must_use, unused_variables)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn foo<T: Debug>(t: T) {
|
||||
println!("{:?}", t);
|
||||
}
|
||||
|
||||
fn foo3<T1: Debug, T2: Debug, T3: Debug>(t1: T1, t2: T2, t3: T3) {
|
||||
println!("{:?}, {:?}, {:?}", t1, t2, t3);
|
||||
}
|
||||
|
||||
fn bad() {
|
||||
foo(());
|
||||
foo3((), 2, 2);
|
||||
foo(0);
|
||||
taking_two_units((), ());
|
||||
foo(0);
|
||||
foo(1);
|
||||
taking_three_units((), (), ());
|
||||
}
|
||||
|
||||
fn taking_two_units(a: (), b: ()) {}
|
||||
fn taking_three_units(a: (), b: (), c: ()) {}
|
||||
|
||||
fn main() {
|
||||
bad();
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::unit_arg)]
|
||||
#![allow(clippy::no_effect, unused_must_use, unused_variables)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: passing a unit value to a function
|
||||
--> $DIR/unit_arg_empty_blocks.rs:15:5
|
||||
--> $DIR/unit_arg_empty_blocks.rs:16:5
|
||||
|
|
||||
LL | foo({});
|
||||
| ^^^^--^
|
||||
|
@ -9,7 +9,7 @@ LL | foo({});
|
|||
= note: `-D clippy::unit-arg` implied by `-D warnings`
|
||||
|
||||
error: passing a unit value to a function
|
||||
--> $DIR/unit_arg_empty_blocks.rs:16:5
|
||||
--> $DIR/unit_arg_empty_blocks.rs:17:5
|
||||
|
|
||||
LL | foo3({}, 2, 2);
|
||||
| ^^^^^--^^^^^^^
|
||||
|
@ -17,7 +17,7 @@ LL | foo3({}, 2, 2);
|
|||
| help: use a unit literal instead: `()`
|
||||
|
||||
error: passing unit values to a function
|
||||
--> $DIR/unit_arg_empty_blocks.rs:17:5
|
||||
--> $DIR/unit_arg_empty_blocks.rs:18:5
|
||||
|
|
||||
LL | taking_two_units({}, foo(0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -29,7 +29,7 @@ LL ~ taking_two_units((), ());
|
|||
|
|
||||
|
||||
error: passing unit values to a function
|
||||
--> $DIR/unit_arg_empty_blocks.rs:18:5
|
||||
--> $DIR/unit_arg_empty_blocks.rs:19:5
|
||||
|
|
||||
LL | taking_three_units({}, foo(0), foo(1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
40
tests/ui/unnecessary_cast.fixed
Normal file
40
tests/ui/unnecessary_cast.fixed
Normal file
|
@ -0,0 +1,40 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::unnecessary_cast)]
|
||||
#![allow(unused_must_use, clippy::no_effect)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn main() {
|
||||
// Test cast_unnecessary
|
||||
1_i32;
|
||||
1_f32;
|
||||
false;
|
||||
&1i32 as &i32;
|
||||
|
||||
-1_i32;
|
||||
- 1_i32;
|
||||
-1_f32;
|
||||
1_i32;
|
||||
1_f32;
|
||||
|
||||
// macro version
|
||||
macro_rules! foo {
|
||||
($a:ident, $b:ident) => {
|
||||
#[allow(unused)]
|
||||
pub fn $a() -> $b {
|
||||
1 as $b
|
||||
}
|
||||
};
|
||||
}
|
||||
foo!(a, i32);
|
||||
foo!(b, f32);
|
||||
foo!(c, f64);
|
||||
|
||||
// do not lint cast to cfg-dependant type
|
||||
1 as std::os::raw::c_char;
|
||||
|
||||
// do not lint cast to alias type
|
||||
1 as I32Alias;
|
||||
&1 as &I32Alias;
|
||||
}
|
||||
|
||||
type I32Alias = i32;
|
|
@ -1,5 +1,6 @@
|
|||
// run-rustfix
|
||||
#![warn(clippy::unnecessary_cast)]
|
||||
#![allow(clippy::no_effect)]
|
||||
#![allow(unused_must_use, clippy::no_effect)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: casting integer literal to `i32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:7:5
|
||||
--> $DIR/unnecessary_cast.rs:8:5
|
||||
|
|
||||
LL | 1i32 as i32;
|
||||
| ^^^^^^^^^^^ help: try: `1_i32`
|
||||
|
@ -7,43 +7,43 @@ LL | 1i32 as i32;
|
|||
= note: `-D clippy::unnecessary-cast` implied by `-D warnings`
|
||||
|
||||
error: casting float literal to `f32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:8:5
|
||||
--> $DIR/unnecessary_cast.rs:9:5
|
||||
|
|
||||
LL | 1f32 as f32;
|
||||
| ^^^^^^^^^^^ help: try: `1_f32`
|
||||
|
||||
error: casting to the same type is unnecessary (`bool` -> `bool`)
|
||||
--> $DIR/unnecessary_cast.rs:9:5
|
||||
--> $DIR/unnecessary_cast.rs:10:5
|
||||
|
|
||||
LL | false as bool;
|
||||
| ^^^^^^^^^^^^^ help: try: `false`
|
||||
|
||||
error: casting integer literal to `i32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:12:5
|
||||
--> $DIR/unnecessary_cast.rs:13:5
|
||||
|
|
||||
LL | -1_i32 as i32;
|
||||
| ^^^^^^^^^^^^^ help: try: `-1_i32`
|
||||
|
||||
error: casting integer literal to `i32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:13:5
|
||||
--> $DIR/unnecessary_cast.rs:14:5
|
||||
|
|
||||
LL | - 1_i32 as i32;
|
||||
| ^^^^^^^^^^^^^^ help: try: `- 1_i32`
|
||||
|
||||
error: casting float literal to `f32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:14:5
|
||||
--> $DIR/unnecessary_cast.rs:15:5
|
||||
|
|
||||
LL | -1f32 as f32;
|
||||
| ^^^^^^^^^^^^ help: try: `-1_f32`
|
||||
|
||||
error: casting integer literal to `i32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:15:5
|
||||
--> $DIR/unnecessary_cast.rs:16:5
|
||||
|
|
||||
LL | 1_i32 as i32;
|
||||
| ^^^^^^^^^^^^ help: try: `1_i32`
|
||||
|
||||
error: casting float literal to `f32` is unnecessary
|
||||
--> $DIR/unnecessary_cast.rs:16:5
|
||||
--> $DIR/unnecessary_cast.rs:17:5
|
||||
|
|
||||
LL | 1_f32 as f32;
|
||||
| ^^^^^^^^^^^^ help: try: `1_f32`
|
||||
|
|
Loading…
Reference in a new issue