diff options
| author | xFrednet <xFrednet@gmail.com> | 2022-05-20 20:37:38 +0200 |
|---|---|---|
| committer | xFrednet <xFrednet@gmail.com> | 2022-05-20 20:47:31 +0200 |
| commit | 4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf (patch) | |
| tree | c0de46a0482ccc460d4789e23b4d2abb5bf17787 /tests | |
| parent | 01421e0cbda66655e25d48c1c72c2dcbe77040c2 (diff) | |
| parent | 6f26383f8ec8dfe89858876eac127161d148eb13 (diff) | |
| download | rust-4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf.tar.gz rust-4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf.zip | |
Merge remote-tracking branch 'upstream/master' into rustup
Diffstat (limited to 'tests')
95 files changed, 2059 insertions, 337 deletions
diff --git a/tests/dogfood.rs b/tests/dogfood.rs index eb97d1933d5..9da80518ce9 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -21,7 +21,7 @@ fn dogfood_clippy() { // "" is the root package for package in &["", "clippy_dev", "clippy_lints", "clippy_utils", "rustc_tools_util"] { - run_clippy_for_package(package); + run_clippy_for_package(package, &[]); } } @@ -38,7 +38,7 @@ fn run_metadata_collection_lint() { // Run collection as is std::env::set_var("ENABLE_METADATA_COLLECTION", "1"); - run_clippy_for_package("clippy_lints"); + run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); // Check if cargo caching got in the way if let Ok(file) = File::open(metadata_output_path) { @@ -61,10 +61,10 @@ fn run_metadata_collection_lint() { .unwrap(); // Running the collection again - run_clippy_for_package("clippy_lints"); + run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); } -fn run_clippy_for_package(project: &str) { +fn run_clippy_for_package(project: &str, args: &[&str]) { let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut command = Command::new(&*test_utils::CARGO_CLIPPY_PATH); @@ -76,6 +76,7 @@ fn run_clippy_for_package(project: &str) { .arg("--all-targets") .arg("--all-features") .arg("--") + .args(args) .args(&["-D", "clippy::all"]) .args(&["-D", "clippy::pedantic"]) .arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir diff --git a/tests/ui-cargo/duplicate_mod/fail/Cargo.toml b/tests/ui-cargo/duplicate_mod/fail/Cargo.toml new file mode 100644 index 00000000000..bf3c817de1c --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "duplicate_mod" +edition = "2021" +publish = false +version = "0.1.0" diff --git a/tests/ui-cargo/duplicate_mod/fail/src/a.rs b/tests/ui-cargo/duplicate_mod/fail/src/a.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/a.rs @@ -0,0 +1 @@ + diff --git a/tests/ui-cargo/duplicate_mod/fail/src/b.rs b/tests/ui-cargo/duplicate_mod/fail/src/b.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/b.rs @@ -0,0 +1 @@ + diff --git a/tests/ui-cargo/duplicate_mod/fail/src/c.rs b/tests/ui-cargo/duplicate_mod/fail/src/c.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/c.rs @@ -0,0 +1 @@ + diff --git a/tests/ui-cargo/duplicate_mod/fail/src/from_other_module.rs b/tests/ui-cargo/duplicate_mod/fail/src/from_other_module.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/from_other_module.rs @@ -0,0 +1 @@ + diff --git a/tests/ui-cargo/duplicate_mod/fail/src/main.rs b/tests/ui-cargo/duplicate_mod/fail/src/main.rs new file mode 100644 index 00000000000..79b343da247 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/main.rs @@ -0,0 +1,16 @@ +mod a; + +mod b; +#[path = "b.rs"] +mod b2; + +mod c; +#[path = "c.rs"] +mod c2; +#[path = "c.rs"] +mod c3; + +mod from_other_module; +mod other_module; + +fn main() {} diff --git a/tests/ui-cargo/duplicate_mod/fail/src/main.stderr b/tests/ui-cargo/duplicate_mod/fail/src/main.stderr new file mode 100644 index 00000000000..00d7739c8a2 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/main.stderr @@ -0,0 +1,42 @@ +error: file is loaded as a module multiple times: `$DIR/b.rs` + --> $DIR/main.rs:3:1 + | +LL | mod b; + | ^^^^^^ first loaded here +LL | / #[path = "b.rs"] +LL | | mod b2; + | |_______^ loaded again here + | + = note: `-D clippy::duplicate-mod` implied by `-D warnings` + = help: replace all but one `mod` item with `use` items + +error: file is loaded as a module multiple times: `$DIR/c.rs` + --> $DIR/main.rs:7:1 + | +LL | mod c; + | ^^^^^^ first loaded here +LL | / #[path = "c.rs"] +LL | | mod c2; + | |_______^ loaded again here +LL | / #[path = "c.rs"] +LL | | mod c3; + | |_______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + +error: file is loaded as a module multiple times: `$DIR/from_other_module.rs` + --> $DIR/main.rs:13:1 + | +LL | mod from_other_module; + | ^^^^^^^^^^^^^^^^^^^^^^ first loaded here + | + ::: $DIR/other_module/mod.rs:1:1 + | +LL | / #[path = "../from_other_module.rs"] +LL | | mod m; + | |______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + +error: aborting due to 3 previous errors + diff --git a/tests/ui-cargo/duplicate_mod/fail/src/other_module/mod.rs b/tests/ui-cargo/duplicate_mod/fail/src/other_module/mod.rs new file mode 100644 index 00000000000..36ce7286ade --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/src/other_module/mod.rs @@ -0,0 +1,2 @@ +#[path = "../from_other_module.rs"] +mod m; diff --git a/tests/ui-toml/expect_used/clippy.toml b/tests/ui-toml/expect_used/clippy.toml new file mode 100644 index 00000000000..6933b816419 --- /dev/null +++ b/tests/ui-toml/expect_used/clippy.toml @@ -0,0 +1 @@ +allow-expect-in-tests = true diff --git a/tests/ui-toml/expect_used/expect_used.rs b/tests/ui-toml/expect_used/expect_used.rs new file mode 100644 index 00000000000..22dcd3ae9d6 --- /dev/null +++ b/tests/ui-toml/expect_used/expect_used.rs @@ -0,0 +1,29 @@ +// compile-flags: --test +#![warn(clippy::expect_used)] + +fn expect_option() { + let opt = Some(0); + let _ = opt.expect(""); +} + +fn expect_result() { + let res: Result<u8, ()> = Ok(0); + let _ = res.expect(""); +} + +fn main() { + expect_option(); + expect_result(); +} + +#[test] +fn test_expect_option() { + let opt = Some(0); + let _ = opt.expect(""); +} + +#[test] +fn test_expect_result() { + let res: Result<u8, ()> = Ok(0); + let _ = res.expect(""); +} diff --git a/tests/ui-toml/expect_used/expect_used.stderr b/tests/ui-toml/expect_used/expect_used.stderr new file mode 100644 index 00000000000..9cb2199ed21 --- /dev/null +++ b/tests/ui-toml/expect_used/expect_used.stderr @@ -0,0 +1,19 @@ +error: used `expect()` on `an Option` value + --> $DIR/expect_used.rs:6:13 + | +LL | let _ = opt.expect(""); + | ^^^^^^^^^^^^^^ + | + = note: `-D clippy::expect-used` implied by `-D warnings` + = help: if this value is an `None`, it will panic + +error: used `expect()` on `a Result` value + --> $DIR/expect_used.rs:11:13 + | +LL | let _ = res.expect(""); + | ^^^^^^^^^^^^^^ + | + = help: if this value is an `Err`, it will panic + +error: aborting due to 2 previous errors + diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 8701809b4da..92838aa57df 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,4 +1,43 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `third-party` at line 5 column 1 +error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of + allow-expect-in-tests + allow-unwrap-in-tests + allowed-scripts + array-size-threshold + avoid-breaking-exported-api + await-holding-invalid-types + blacklisted-names + cargo-ignore-publish + cognitive-complexity-threshold + cyclomatic-complexity-threshold + disallowed-methods + disallowed-types + doc-valid-idents + enable-raw-pointer-heuristic-for-send + enforced-import-renames + enum-variant-name-threshold + enum-variant-size-threshold + literal-representation-threshold + max-fn-params-bools + max-include-file-size + max-struct-bools + max-suggested-slice-pattern-length + max-trait-bounds + msrv + pass-by-value-size-limit + single-char-binding-names-threshold + standard-macro-braces + third-party + too-large-for-stack + too-many-arguments-threshold + too-many-lines-threshold + trivial-copy-size-limit + type-complexity-threshold + unreadable-literal-lint-fractions + upper-case-acronyms-aggressive + vec-box-size-threshold + verbose-bit-mask-threshold + warn-on-all-wildcard-imports + at line 5 column 1 error: aborting due to previous error diff --git a/tests/ui-toml/unwrap_used/clippy.toml b/tests/ui-toml/unwrap_used/clippy.toml new file mode 100644 index 00000000000..154626ef4e8 --- /dev/null +++ b/tests/ui-toml/unwrap_used/clippy.toml @@ -0,0 +1 @@ +allow-unwrap-in-tests = true diff --git a/tests/ui-toml/unwrap_used/unwrap_used.rs b/tests/ui-toml/unwrap_used/unwrap_used.rs new file mode 100644 index 00000000000..74d0d7c2650 --- /dev/null +++ b/tests/ui-toml/unwrap_used/unwrap_used.rs @@ -0,0 +1,73 @@ +// compile-flags: --test + +#![allow(unused_mut, clippy::from_iter_instead_of_collect)] +#![warn(clippy::unwrap_used)] +#![deny(clippy::get_unwrap)] + +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::collections::VecDeque; + +struct GetFalsePositive { + arr: [u32; 3], +} + +impl GetFalsePositive { + fn get(&self, pos: usize) -> Option<&u32> { + self.arr.get(pos) + } + fn get_mut(&mut self, pos: usize) -> Option<&mut u32> { + self.arr.get_mut(pos) + } +} + +fn main() { + let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let mut some_slice = &mut [0, 1, 2, 3]; + let mut some_vec = vec![0, 1, 2, 3]; + let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect(); + let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]); + let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]); + let mut false_positive = GetFalsePositive { arr: [0, 1, 2] }; + + { + // Test `get().unwrap()` + let _ = boxed_slice.get(1).unwrap(); + let _ = some_slice.get(0).unwrap(); + let _ = some_vec.get(0).unwrap(); + let _ = some_vecdeque.get(0).unwrap(); + let _ = some_hashmap.get(&1).unwrap(); + let _ = some_btreemap.get(&1).unwrap(); + #[allow(clippy::unwrap_used)] + let _ = false_positive.get(0).unwrap(); + // Test with deref + let _: u8 = *boxed_slice.get(1).unwrap(); + } + + { + // Test `get_mut().unwrap()` + *boxed_slice.get_mut(0).unwrap() = 1; + *some_slice.get_mut(0).unwrap() = 1; + *some_vec.get_mut(0).unwrap() = 1; + *some_vecdeque.get_mut(0).unwrap() = 1; + // Check false positives + #[allow(clippy::unwrap_used)] + { + *some_hashmap.get_mut(&1).unwrap() = 'b'; + *some_btreemap.get_mut(&1).unwrap() = 'b'; + *false_positive.get_mut(0).unwrap() = 1; + } + } + + { + // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()` + let _ = some_vec.get(0..1).unwrap().to_vec(); + let _ = some_vec.get_mut(0..1).unwrap().to_vec(); + } +} + +#[test] +fn test() { + let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let _ = boxed_slice.get(1).unwrap(); +} diff --git a/tests/ui-toml/unwrap_used/unwrap_used.stderr b/tests/ui-toml/unwrap_used/unwrap_used.stderr new file mode 100644 index 00000000000..6bcfa0a8b56 --- /dev/null +++ b/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -0,0 +1,197 @@ +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:35:17 + | +LL | let _ = boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + | +note: the lint level is defined here + --> $DIR/unwrap_used.rs:5:9 + | +LL | #![deny(clippy::get_unwrap)] + | ^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:35:17 + | +LL | let _ = boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unwrap-used` implied by `-D warnings` + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:36:17 + | +LL | let _ = some_slice.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:36:17 + | +LL | let _ = some_slice.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:37:17 + | +LL | let _ = some_vec.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:37:17 + | +LL | let _ = some_vec.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:38:17 + | +LL | let _ = some_vecdeque.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:38:17 + | +LL | let _ = some_vecdeque.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:39:17 + | +LL | let _ = some_hashmap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:39:17 + | +LL | let _ = some_hashmap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:40:17 + | +LL | let _ = some_btreemap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:40:17 + | +LL | let _ = some_btreemap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:44:21 + | +LL | let _: u8 = *boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:44:22 + | +LL | let _: u8 = *boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:49:9 + | +LL | *boxed_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:49:10 + | +LL | *boxed_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:50:9 + | +LL | *some_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:50:10 + | +LL | *some_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:51:9 + | +LL | *some_vec.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:51:10 + | +LL | *some_vec.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:52:9 + | +LL | *some_vecdeque.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:52:10 + | +LL | *some_vecdeque.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:64:17 + | +LL | let _ = some_vec.get(0..1).unwrap().to_vec(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:64:17 + | +LL | let _ = some_vec.get(0..1).unwrap().to_vec(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:65:17 + | +LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + +error: used `unwrap()` on `an Option` value + --> $DIR/unwrap_used.rs:65:17 + | +LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:72:13 + | +LL | let _ = boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + +error: aborting due to 27 previous errors + diff --git a/tests/ui/absurd-extreme-comparisons.rs b/tests/ui/absurd-extreme-comparisons.rs index d205b383d1f..f682b280c1b 100644 --- a/tests/ui/absurd-extreme-comparisons.rs +++ b/tests/ui/absurd-extreme-comparisons.rs @@ -37,7 +37,7 @@ fn main() { use std::cmp::{Ordering, PartialEq, PartialOrd}; -#[derive(PartialEq, PartialOrd)] +#[derive(PartialEq, Eq, PartialOrd)] pub struct U(u64); impl PartialEq<u32> for U { diff --git a/tests/ui/assign_ops2.rs b/tests/ui/assign_ops2.rs index 4703a8c7777..f6d3a8fa3f0 100644 --- a/tests/ui/assign_ops2.rs +++ b/tests/ui/assign_ops2.rs @@ -24,7 +24,7 @@ fn main() { use std::ops::{Mul, MulAssign}; -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Wrap(i64); impl Mul<i64> for Wrap { diff --git a/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs b/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs index 26c88489b03..a2ef0fe827c 100644 --- a/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs +++ b/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs @@ -5,7 +5,6 @@ extern crate proc_macro; use proc_macro::{token_stream, Delimiter, Group, Ident, Span, TokenStream, TokenTree}; -use std::iter::FromIterator; fn read_ident(iter: &mut token_stream::IntoIter) -> Ident { match iter.next() { diff --git a/tests/ui/blacklisted_name.rs b/tests/ui/blacklisted_name.rs index 57d7139fef5..27df732a088 100644 --- a/tests/ui/blacklisted_name.rs +++ b/tests/ui/blacklisted_name.rs @@ -46,10 +46,10 @@ fn issue_1647_ref_mut() { mod tests { fn issue_7305() { - // `blackisted_name` lint should not be triggered inside of the test code. + // `blacklisted_name` lint should not be triggered inside of the test code. let foo = 0; - // Check that even in nested functions warning is still not triggere. + // Check that even in nested functions warning is still not triggered. fn nested() { let foo = 0; } diff --git a/tests/ui/branches_sharing_code/shared_at_top.rs b/tests/ui/branches_sharing_code/shared_at_top.rs index 51a46481399..bdeb0a39558 100644 --- a/tests/ui/branches_sharing_code/shared_at_top.rs +++ b/tests/ui/branches_sharing_code/shared_at_top.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::eval_order_dependence)] +#![allow(dead_code, clippy::mixed_read_write_in_expression)] #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] // This tests the branches_sharing_code lint at the start of blocks diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs index 0c70e3748ec..a26141be237 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.rs +++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::eval_order_dependence)] +#![allow(dead_code, clippy::mixed_read_write_in_expression)] #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] // This tests valid if blocks that shouldn't trigger the lint diff --git a/tests/ui/cast_size_32bit.stderr b/tests/ui/cast_size_32bit.stderr index 140676a5ffc..7125f741c15 100644 --- a/tests/ui/cast_size_32bit.stderr +++ b/tests/ui/cast_size_32bit.stderr @@ -14,26 +14,12 @@ LL | x0 as f64; | = note: `-D clippy::cast-precision-loss` implied by `-D warnings` -error: casting `isize` to `f64` may become silently lossy if you later change the type - --> $DIR/cast_size_32bit.rs:15:5 - | -LL | x0 as f64; - | ^^^^^^^^^ help: try: `f64::from(x0)` - | - = note: `-D clippy::cast-lossless` implied by `-D warnings` - error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> $DIR/cast_size_32bit.rs:16:5 | LL | x1 as f64; | ^^^^^^^^^ -error: casting `usize` to `f64` may become silently lossy if you later change the type - --> $DIR/cast_size_32bit.rs:16:5 - | -LL | x1 as f64; - | ^^^^^^^^^ help: try: `f64::from(x1)` - error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> $DIR/cast_size_32bit.rs:17:5 | diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index 12290db3dcf..0983d393b56 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -7,8 +7,6 @@ )] #![warn(clippy::checked_conversions)] -use std::convert::TryFrom; - // Positive tests // Signed to unsigned diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 895a301e821..7d26ace47fd 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -7,8 +7,6 @@ )] #![warn(clippy::checked_conversions)] -use std::convert::TryFrom; - // Positive tests // Signed to unsigned diff --git a/tests/ui/checked_conversions.stderr b/tests/ui/checked_conversions.stderr index 18518def0ac..2e518040561 100644 --- a/tests/ui/checked_conversions.stderr +++ b/tests/ui/checked_conversions.stderr @@ -1,5 +1,5 @@ error: checked cast can be simplified - --> $DIR/checked_conversions.rs:17:13 + --> $DIR/checked_conversions.rs:15:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` @@ -7,91 +7,91 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0; = note: `-D clippy::checked-conversions` implied by `-D warnings` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:18:13 + --> $DIR/checked_conversions.rs:16:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:22:13 + --> $DIR/checked_conversions.rs:20:13 | LL | let _ = value <= i64::from(u16::max_value()) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:23:13 + --> $DIR/checked_conversions.rs:21:13 | LL | let _ = value <= i64::from(u16::MAX) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:27:13 + --> $DIR/checked_conversions.rs:25:13 | LL | let _ = value <= (u8::max_value() as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:28:13 + --> $DIR/checked_conversions.rs:26:13 | LL | let _ = value <= (u8::MAX as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:34:13 + --> $DIR/checked_conversions.rs:32:13 | LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:35:13 + --> $DIR/checked_conversions.rs:33:13 | LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:39:13 + --> $DIR/checked_conversions.rs:37:13 | LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:40:13 + --> $DIR/checked_conversions.rs:38:13 | LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:46:13 + --> $DIR/checked_conversions.rs:44:13 | LL | let _ = value <= i32::max_value() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:47:13 + --> $DIR/checked_conversions.rs:45:13 | LL | let _ = value <= i32::MAX as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:51:13 + --> $DIR/checked_conversions.rs:49:13 | LL | let _ = value <= isize::max_value() as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:52:13 + --> $DIR/checked_conversions.rs:50:13 | LL | let _ = value <= isize::MAX as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:56:13 + --> $DIR/checked_conversions.rs:54:13 | LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:57:13 + --> $DIR/checked_conversions.rs:55:13 | LL | let _ = value <= u16::MAX as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed index 3305ac9bf8b..abd059c2308 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, clippy::redundant_clone)] // See #5700 +#![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 // Define the types in each module to avoid trait impls leaking between modules. macro_rules! impl_types { diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/tests/ui/cmp_owned/asymmetric_partial_eq.rs index 88bc2f51dd6..020ef5f840b 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.rs +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.rs @@ -1,5 +1,5 @@ // run-rustfix -#![allow(unused, clippy::redundant_clone)] // See #5700 +#![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 // Define the types in each module to avoid trait impls leaking between modules. macro_rules! impl_types { diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index 05fb96339e3..b28c4378e33 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -45,7 +45,7 @@ impl ToOwned for Foo { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Bar; impl PartialEq<Foo> for Bar { @@ -61,7 +61,7 @@ impl std::borrow::Borrow<Foo> for Bar { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Baz; impl ToOwned for Baz { diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index 0a02825ed82..c1089010fe1 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -45,7 +45,7 @@ impl ToOwned for Foo { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Bar; impl PartialEq<Foo> for Bar { @@ -61,7 +61,7 @@ impl std::borrow::Borrow<Foo> for Bar { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Baz; impl ToOwned for Baz { diff --git a/tests/ui/cmp_owned/without_suggestion.rs b/tests/ui/cmp_owned/without_suggestion.rs index f44a3901fb4..d8a202cb6a1 100644 --- a/tests/ui/cmp_owned/without_suggestion.rs +++ b/tests/ui/cmp_owned/without_suggestion.rs @@ -9,6 +9,10 @@ fn main() { let x = &&Baz; let y = &Baz; y.to_owned() == **x; + + let x = 0u32; + let y = U32Wrapper(x); + let _ = U32Wrapper::from(x) == y; } struct Foo; @@ -26,7 +30,7 @@ impl ToOwned for Foo { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Baz; impl ToOwned for Baz { @@ -36,7 +40,7 @@ impl ToOwned for Baz { } } -#[derive(PartialEq)] +#[derive(PartialEq, Eq)] struct Bar; impl PartialEq<Foo> for Bar { @@ -51,3 +55,21 @@ impl std::borrow::Borrow<Foo> for Bar { &FOO } } + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +struct U32Wrapper(u32); +impl From<u32> for U32Wrapper { + fn from(x: u32) -> Self { + Self(x) + } +} +impl PartialEq<u32> for U32Wrapper { + fn eq(&self, other: &u32) -> bool { + self.0 == *other + } +} +impl PartialEq<U32Wrapper> for u32 { + fn eq(&self, other: &U32Wrapper) -> bool { + *self == other.0 + } +} diff --git a/tests/ui/cmp_owned/without_suggestion.stderr b/tests/ui/cmp_owned/without_suggestion.stderr index 2ea3d8fac0d..d2dd14d8edb 100644 --- a/tests/ui/cmp_owned/without_suggestion.stderr +++ b/tests/ui/cmp_owned/without_suggestion.stderr @@ -13,7 +13,7 @@ LL | y.to_owned() == **x; | ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating error: this creates an owned instance just for comparison - --> $DIR/without_suggestion.rs:18:9 + --> $DIR/without_suggestion.rs:22:9 | LL | self.to_owned() == *other | ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating diff --git a/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/tests/ui/crashes/auxiliary/proc_macro_crash.rs index ed8e7a708a5..5ff2af7cd82 100644 --- a/tests/ui/crashes/auxiliary/proc_macro_crash.rs +++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs @@ -12,7 +12,6 @@ extern crate proc_macro; use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; -use std::iter::FromIterator; #[proc_macro] pub fn macro_test(input_stream: TokenStream) -> TokenStream { diff --git a/tests/ui/crashes/ice-6254.rs b/tests/ui/crashes/ice-6254.rs index c19eca43884..a2a60a16915 100644 --- a/tests/ui/crashes/ice-6254.rs +++ b/tests/ui/crashes/ice-6254.rs @@ -2,6 +2,7 @@ // panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', // compiler/rustc_mir_build/src/thir/pattern/_match.rs:2030:5 +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(PartialEq)] struct Foo(i32); const FOO_REF_REF: &&Foo = &&Foo(42); diff --git a/tests/ui/crashes/ice-6254.stderr b/tests/ui/crashes/ice-6254.stderr index 95ebf23d818..f37ab2e9b0c 100644 --- a/tests/ui/crashes/ice-6254.stderr +++ b/tests/ui/crashes/ice-6254.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/ice-6254.rs:12:9 + --> $DIR/ice-6254.rs:13:9 | LL | FOO_REF_REF => {}, | ^^^^^^^^^^^ diff --git a/tests/ui/crashes/ice-8821.rs b/tests/ui/crashes/ice-8821.rs new file mode 100644 index 00000000000..fb87b79aeed --- /dev/null +++ b/tests/ui/crashes/ice-8821.rs @@ -0,0 +1,8 @@ +#![warn(clippy::let_unit_value)] + +fn f() {} +static FN: fn() = f; + +fn main() { + let _: () = FN(); +} diff --git a/tests/ui/crashes/ice-8821.stderr b/tests/ui/crashes/ice-8821.stderr new file mode 100644 index 00000000000..486096e0a06 --- /dev/null +++ b/tests/ui/crashes/ice-8821.stderr @@ -0,0 +1,10 @@ +error: this let-binding has unit value + --> $DIR/ice-8821.rs:7:5 + | +LL | let _: () = FN(); + | ^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `FN();` + | + = note: `-D clippy::let-unit-value` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/dbg_macro.rs b/tests/ui/dbg_macro.rs index baf01174b67..25294e8c766 100644 --- a/tests/ui/dbg_macro.rs +++ b/tests/ui/dbg_macro.rs @@ -46,3 +46,15 @@ mod issue7274 { pub fn issue8481() { dbg!(1); } + +#[cfg(test)] +fn foo2() { + dbg!(1); +} + +#[cfg(test)] +mod mod1 { + fn func() { + dbg!(1); + } +} diff --git a/tests/ui/derive_hash_xor_eq.rs b/tests/ui/derive_hash_xor_eq.rs index 10abe22d53e..813ddc56646 100644 --- a/tests/ui/derive_hash_xor_eq.rs +++ b/tests/ui/derive_hash_xor_eq.rs @@ -1,3 +1,5 @@ +#![allow(clippy::derive_partial_eq_without_eq)] + #[derive(PartialEq, Hash)] struct Foo; diff --git a/tests/ui/derive_hash_xor_eq.stderr b/tests/ui/derive_hash_xor_eq.stderr index b383072ca4d..e5184bd1407 100644 --- a/tests/ui/derive_hash_xor_eq.stderr +++ b/tests/ui/derive_hash_xor_eq.stderr @@ -1,12 +1,12 @@ error: you are deriving `Hash` but have implemented `PartialEq` explicitly - --> $DIR/derive_hash_xor_eq.rs:10:10 + --> $DIR/derive_hash_xor_eq.rs:12:10 | LL | #[derive(Hash)] | ^^^^ | = note: `#[deny(clippy::derive_hash_xor_eq)]` on by default note: `PartialEq` implemented here - --> $DIR/derive_hash_xor_eq.rs:13:1 + --> $DIR/derive_hash_xor_eq.rs:15:1 | LL | / impl PartialEq for Bar { LL | | fn eq(&self, _: &Bar) -> bool { @@ -17,13 +17,13 @@ LL | | } = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Hash` but have implemented `PartialEq` explicitly - --> $DIR/derive_hash_xor_eq.rs:19:10 + --> $DIR/derive_hash_xor_eq.rs:21:10 | LL | #[derive(Hash)] | ^^^^ | note: `PartialEq` implemented here - --> $DIR/derive_hash_xor_eq.rs:22:1 + --> $DIR/derive_hash_xor_eq.rs:24:1 | LL | / impl PartialEq<Baz> for Baz { LL | | fn eq(&self, _: &Baz) -> bool { @@ -34,7 +34,7 @@ LL | | } = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Hash` explicitly but have derived `PartialEq` - --> $DIR/derive_hash_xor_eq.rs:31:1 + --> $DIR/derive_hash_xor_eq.rs:33:1 | LL | / impl std::hash::Hash for Bah { LL | | fn hash<H: std::hash::Hasher>(&self, _: &mut H) {} @@ -42,14 +42,14 @@ LL | | } | |_^ | note: `PartialEq` implemented here - --> $DIR/derive_hash_xor_eq.rs:28:10 + --> $DIR/derive_hash_xor_eq.rs:30:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Hash` explicitly but have derived `PartialEq` - --> $DIR/derive_hash_xor_eq.rs:49:5 + --> $DIR/derive_hash_xor_eq.rs:51:5 | LL | / impl Hash for Foo3 { LL | | fn hash<H: std::hash::Hasher>(&self, _: &mut H) {} @@ -57,7 +57,7 @@ LL | | } | |_____^ | note: `PartialEq` implemented here - --> $DIR/derive_hash_xor_eq.rs:46:14 + --> $DIR/derive_hash_xor_eq.rs:48:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ diff --git a/tests/ui/derive_partial_eq_without_eq.fixed b/tests/ui/derive_partial_eq_without_eq.fixed new file mode 100644 index 00000000000..7d4d1b3b649 --- /dev/null +++ b/tests/ui/derive_partial_eq_without_eq.fixed @@ -0,0 +1,98 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::derive_partial_eq_without_eq)] + +// Don't warn on structs that aren't PartialEq +struct NotPartialEq { + foo: u32, + bar: String, +} + +// Eq can be derived but is missing +#[derive(Debug, PartialEq, Eq)] +struct MissingEq { + foo: u32, + bar: String, +} + +// Eq is derived +#[derive(PartialEq, Eq)] +struct NotMissingEq { + foo: u32, + bar: String, +} + +// Eq is manually implemented +#[derive(PartialEq)] +struct ManualEqImpl { + foo: u32, + bar: String, +} + +impl Eq for ManualEqImpl {} + +// Cannot be Eq because f32 isn't Eq +#[derive(PartialEq)] +struct CannotBeEq { + foo: u32, + bar: f32, +} + +// Don't warn if PartialEq is manually implemented +struct ManualPartialEqImpl { + foo: u32, + bar: String, +} + +impl PartialEq for ManualPartialEqImpl { + fn eq(&self, other: &Self) -> bool { + self.foo == other.foo && self.bar == other.bar + } +} + +// Generic fields should be properly checked for Eq-ness +#[derive(PartialEq)] +struct GenericNotEq<T: Eq, U: PartialEq> { + foo: T, + bar: U, +} + +#[derive(PartialEq, Eq)] +struct GenericEq<T: Eq, U: Eq> { + foo: T, + bar: U, +} + +#[derive(PartialEq, Eq)] +struct TupleStruct(u32); + +#[derive(PartialEq, Eq)] +struct GenericTupleStruct<T: Eq>(T); + +#[derive(PartialEq)] +struct TupleStructNotEq(f32); + +#[derive(PartialEq, Eq)] +enum Enum { + Foo(u32), + Bar { a: String, b: () }, +} + +#[derive(PartialEq, Eq)] +enum GenericEnum<T: Eq, U: Eq, V: Eq> { + Foo(T), + Bar { a: U, b: V }, +} + +#[derive(PartialEq)] +enum EnumNotEq { + Foo(u32), + Bar { a: String, b: f32 }, +} + +// Ensure that rustfix works properly when `PartialEq` has other derives on either side +#[derive(Debug, PartialEq, Eq, Clone)] +struct RustFixWithOtherDerives; + +fn main() {} diff --git a/tests/ui/derive_partial_eq_without_eq.rs b/tests/ui/derive_partial_eq_without_eq.rs new file mode 100644 index 00000000000..ab4e1df1ca4 --- /dev/null +++ b/tests/ui/derive_partial_eq_without_eq.rs @@ -0,0 +1,98 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::derive_partial_eq_without_eq)] + +// Don't warn on structs that aren't PartialEq +struct NotPartialEq { + foo: u32, + bar: String, +} + +// Eq can be derived but is missing +#[derive(Debug, PartialEq)] +struct MissingEq { + foo: u32, + bar: String, +} + +// Eq is derived +#[derive(PartialEq, Eq)] +struct NotMissingEq { + foo: u32, + bar: String, +} + +// Eq is manually implemented +#[derive(PartialEq)] +struct ManualEqImpl { + foo: u32, + bar: String, +} + +impl Eq for ManualEqImpl {} + +// Cannot be Eq because f32 isn't Eq +#[derive(PartialEq)] +struct CannotBeEq { + foo: u32, + bar: f32, +} + +// Don't warn if PartialEq is manually implemented +struct ManualPartialEqImpl { + foo: u32, + bar: String, +} + +impl PartialEq for ManualPartialEqImpl { + fn eq(&self, other: &Self) -> bool { + self.foo == other.foo && self.bar == other.bar + } +} + +// Generic fields should be properly checked for Eq-ness +#[derive(PartialEq)] +struct GenericNotEq<T: Eq, U: PartialEq> { + foo: T, + bar: U, +} + +#[derive(PartialEq)] +struct GenericEq<T: Eq, U: Eq> { + foo: T, + bar: U, +} + +#[derive(PartialEq)] +struct TupleStruct(u32); + +#[derive(PartialEq)] +struct GenericTupleStruct<T: Eq>(T); + +#[derive(PartialEq)] +struct TupleStructNotEq(f32); + +#[derive(PartialEq)] +enum Enum { + Foo(u32), + Bar { a: String, b: () }, +} + +#[derive(PartialEq)] +enum GenericEnum<T: Eq, U: Eq, V: Eq> { + Foo(T), + Bar { a: U, b: V }, +} + +#[derive(PartialEq)] +enum EnumNotEq { + Foo(u32), + Bar { a: String, b: f32 }, +} + +// Ensure that rustfix works properly when `PartialEq` has other derives on either side +#[derive(Debug, PartialEq, Clone)] +struct RustFixWithOtherDerives; + +fn main() {} diff --git a/tests/ui/derive_partial_eq_without_eq.stderr b/tests/ui/derive_partial_eq_without_eq.stderr new file mode 100644 index 00000000000..bf55165890a --- /dev/null +++ b/tests/ui/derive_partial_eq_without_eq.stderr @@ -0,0 +1,46 @@ +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:13:17 + | +LL | #[derive(Debug, PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + | + = note: `-D clippy::derive-partial-eq-without-eq` implied by `-D warnings` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:61:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:67:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:70:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:76:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:82:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> $DIR/derive_partial_eq_without_eq.rs:95:17 + | +LL | #[derive(Debug, PartialEq, Clone)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: aborting due to 7 previous errors + diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 88918d9671e..47bf25e409b 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused_variables, dead_code)] +#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] use std::cmp::Ordering; diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index 9a7ab75ef45..d498bca2455 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused_variables, dead_code)] +#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] use std::cmp::Ordering; diff --git a/tests/ui/expect_tool_lint_rfc_2383.rs b/tests/ui/expect_tool_lint_rfc_2383.rs index 28b37f96e91..985835ffa65 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.rs +++ b/tests/ui/expect_tool_lint_rfc_2383.rs @@ -22,9 +22,9 @@ mod rustc_ok { #[expect(illegal_floating_point_literal_pattern)] match x { - 5.0 => {} - 6.0 => {} - _ => {} + 5.0 => {}, + 6.0 => {}, + _ => {}, } } } @@ -38,9 +38,9 @@ mod rustc_warn { #[expect(illegal_floating_point_literal_pattern)] match x { - 5 => {} - 6 => {} - _ => {} + 5 => {}, + 6 => {}, + _ => {}, } } } diff --git a/tests/ui/from_iter_instead_of_collect.fixed b/tests/ui/from_iter_instead_of_collect.fixed index 12db43b5343..403c3b3e443 100644 --- a/tests/ui/from_iter_instead_of_collect.fixed +++ b/tests/ui/from_iter_instead_of_collect.fixed @@ -4,7 +4,6 @@ #![allow(unused_imports)] use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; -use std::iter::FromIterator; struct Foo(Vec<bool>); diff --git a/tests/ui/from_iter_instead_of_collect.rs b/tests/ui/from_iter_instead_of_collect.rs index f5ec190e0cd..fefc7b01a65 100644 --- a/tests/ui/from_iter_instead_of_collect.rs +++ b/tests/ui/from_iter_instead_of_collect.rs @@ -4,7 +4,6 @@ #![allow(unused_imports)] use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; -use std::iter::FromIterator; struct Foo(Vec<bool>); diff --git a/tests/ui/from_iter_instead_of_collect.stderr b/tests/ui/from_iter_instead_of_collect.stderr index 8f08ac8c3ff..8aa3c3c01f8 100644 --- a/tests/ui/from_iter_instead_of_collect.stderr +++ b/tests/ui/from_iter_instead_of_collect.stderr @@ -1,5 +1,5 @@ error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:19:9 + --> $DIR/from_iter_instead_of_collect.rs:18:9 | LL | <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.into_iter().copied().collect::<Self>()` @@ -7,85 +7,85 @@ LL | <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied()) = note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:25:13 + --> $DIR/from_iter_instead_of_collect.rs:24:13 | LL | let _ = Vec::from_iter(iter_expr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::<Vec<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:27:13 + --> $DIR/from_iter_instead_of_collect.rs:26:13 | LL | let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:32:19 + --> $DIR/from_iter_instead_of_collect.rs:31:19 | LL | assert_eq!(a, Vec::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:33:19 + --> $DIR/from_iter_instead_of_collect.rs:32:19 | LL | assert_eq!(a, Vec::<i32>::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<i32>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:35:17 + --> $DIR/from_iter_instead_of_collect.rs:34:17 | LL | let mut b = VecDeque::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:38:17 + --> $DIR/from_iter_instead_of_collect.rs:37:17 | LL | let mut b = VecDeque::<i32>::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<i32>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:43:21 + --> $DIR/from_iter_instead_of_collect.rs:42:21 | LL | let mut b = collections::VecDeque::<i32>::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::VecDeque<i32>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:48:14 + --> $DIR/from_iter_instead_of_collect.rs:47:14 | LL | let bm = BTreeMap::from_iter(values.iter().cloned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::<BTreeMap<_, _>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:49:19 + --> $DIR/from_iter_instead_of_collect.rs:48:19 | LL | let mut bar = BTreeMap::from_iter(bm.range(0..2)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::<BTreeMap<_, _>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:52:19 + --> $DIR/from_iter_instead_of_collect.rs:51:19 | LL | let mut bts = BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<BTreeSet<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:56:17 + --> $DIR/from_iter_instead_of_collect.rs:55:17 | LL | let _ = collections::BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:57:17 + --> $DIR/from_iter_instead_of_collect.rs:56:17 | LL | let _ = collections::BTreeSet::<u32>::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<u32>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:60:15 + --> $DIR/from_iter_instead_of_collect.rs:59:15 | LL | for _i in Vec::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<_>>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:61:15 + --> $DIR/from_iter_instead_of_collect.rs:60:15 | LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<&i32>>()` diff --git a/tests/ui/get_unwrap.fixed b/tests/ui/get_unwrap.fixed index c3a36dcabd1..8f165d67589 100644 --- a/tests/ui/get_unwrap.fixed +++ b/tests/ui/get_unwrap.fixed @@ -7,7 +7,6 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::collections::VecDeque; -use std::iter::FromIterator; struct GetFalsePositive { arr: [u32; 3], diff --git a/tests/ui/get_unwrap.rs b/tests/ui/get_unwrap.rs index d77a202aa39..786749daa74 100644 --- a/tests/ui/get_unwrap.rs +++ b/tests/ui/get_unwrap.rs @@ -7,7 +7,6 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::collections::VecDeque; -use std::iter::FromIterator; struct GetFalsePositive { arr: [u32; 3], diff --git a/tests/ui/get_unwrap.stderr b/tests/ui/get_unwrap.stderr index cb5f44fbd59..ea8fec52735 100644 --- a/tests/ui/get_unwrap.stderr +++ b/tests/ui/get_unwrap.stderr @@ -1,5 +1,5 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:36:17 + --> $DIR/get_unwrap.rs:35:17 | LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` @@ -11,7 +11,7 @@ LL | #![deny(clippy::get_unwrap)] | ^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:36:17 + --> $DIR/get_unwrap.rs:35:17 | LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,13 +20,13 @@ LL | let _ = boxed_slice.get(1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:37:17 + --> $DIR/get_unwrap.rs:36:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:37:17 + --> $DIR/get_unwrap.rs:36:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,13 +34,13 @@ LL | let _ = some_slice.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:38:17 + --> $DIR/get_unwrap.rs:37:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:38:17 + --> $DIR/get_unwrap.rs:37:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,13 +48,13 @@ LL | let _ = some_vec.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:39:17 + --> $DIR/get_unwrap.rs:38:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:39:17 + --> $DIR/get_unwrap.rs:38:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,13 +62,13 @@ LL | let _ = some_vecdeque.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:40:17 + --> $DIR/get_unwrap.rs:39:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:40:17 + --> $DIR/get_unwrap.rs:39:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,13 +76,13 @@ LL | let _ = some_hashmap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:41:17 + --> $DIR/get_unwrap.rs:40:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:41:17 + --> $DIR/get_unwrap.rs:40:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,13 +90,13 @@ LL | let _ = some_btreemap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:45:21 + --> $DIR/get_unwrap.rs:44:21 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:45:22 + --> $DIR/get_unwrap.rs:44:22 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,13 +104,13 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:50:9 + --> $DIR/get_unwrap.rs:49:9 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:50:10 + --> $DIR/get_unwrap.rs:49:10 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +118,13 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:51:9 + --> $DIR/get_unwrap.rs:50:9 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:51:10 + --> $DIR/get_unwrap.rs:50:10 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,13 +132,13 @@ LL | *some_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:52:9 + --> $DIR/get_unwrap.rs:51:9 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:52:10 + --> $DIR/get_unwrap.rs:51:10 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,13 +146,13 @@ LL | *some_vec.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:53:9 + --> $DIR/get_unwrap.rs:52:9 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:53:10 + --> $DIR/get_unwrap.rs:52:10 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,13 +160,13 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:65:17 + --> $DIR/get_unwrap.rs:64:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:65:17 + --> $DIR/get_unwrap.rs:64:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,13 +174,13 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:66:17 + --> $DIR/get_unwrap.rs:65:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` error: used `unwrap()` on `an Option` value - --> $DIR/get_unwrap.rs:66:17 + --> $DIR/get_unwrap.rs:65:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite_iter.rs b/tests/ui/infinite_iter.rs index 1fe68897765..a1e5fad0c62 100644 --- a/tests/ui/infinite_iter.rs +++ b/tests/ui/infinite_iter.rs @@ -51,7 +51,6 @@ fn main() { mod finite_collect { use std::collections::HashSet; - use std::iter::FromIterator; struct C; impl FromIterator<i32> for C { diff --git a/tests/ui/infinite_iter.stderr b/tests/ui/infinite_iter.stderr index 5f5e7ac9f25..ba277e36339 100644 --- a/tests/ui/infinite_iter.stderr +++ b/tests/ui/infinite_iter.stderr @@ -98,7 +98,7 @@ LL | (0..).all(|x| x == 24); // maybe infinite iter | ^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> $DIR/infinite_iter.rs:64:31 + --> $DIR/infinite_iter.rs:63:31 | LL | let _: HashSet<i32> = (0..).collect(); // Infinite iter | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_str_repeat.fixed b/tests/ui/manual_str_repeat.fixed index dc140257f32..0704ba2f933 100644 --- a/tests/ui/manual_str_repeat.fixed +++ b/tests/ui/manual_str_repeat.fixed @@ -4,7 +4,7 @@ #![warn(clippy::manual_str_repeat)] use std::borrow::Cow; -use std::iter::{repeat, FromIterator}; +use std::iter::repeat; fn main() { let _: String = "test".repeat(10); diff --git a/tests/ui/manual_str_repeat.rs b/tests/ui/manual_str_repeat.rs index 0d69c989b2e..f522be439aa 100644 --- a/tests/ui/manual_str_repeat.rs +++ b/tests/ui/manual_str_repeat.rs @@ -4,7 +4,7 @@ #![warn(clippy::manual_str_repeat)] use std::borrow::Cow; -use std::iter::{repeat, FromIterator}; +use std::iter::repeat; fn main() { let _: String = std::iter::repeat("test").take(10).collect(); diff --git a/tests/ui/map_err.rs b/tests/ui/map_err.rs index 00e037843f8..bb35ab1a14e 100644 --- a/tests/ui/map_err.rs +++ b/tests/ui/map_err.rs @@ -1,6 +1,5 @@ #![warn(clippy::map_err_ignore)] #![allow(clippy::unnecessary_wraps)] -use std::convert::TryFrom; use std::error::Error; use std::fmt; diff --git a/tests/ui/map_err.stderr b/tests/ui/map_err.stderr index 37e87e64de2..c035840521e 100644 --- a/tests/ui/map_err.stderr +++ b/tests/ui/map_err.stderr @@ -1,5 +1,5 @@ error: `map_err(|_|...` wildcard pattern discards the original error - --> $DIR/map_err.rs:23:32 + --> $DIR/map_err.rs:22:32 | LL | println!("{:?}", x.map_err(|_| Errors::Ignored)); | ^^^ diff --git a/tests/ui/match_single_binding.fixed b/tests/ui/match_single_binding.fixed index b8dc8179f7d..de46e6cff55 100644 --- a/tests/ui/match_single_binding.fixed +++ b/tests/ui/match_single_binding.fixed @@ -111,3 +111,16 @@ fn main() { let x = 1; println!("Not an array index start"); } + +#[allow(dead_code)] +fn issue_8723() { + let (mut val, idx) = ("a b", 1); + + let (pre, suf) = val.split_at(idx); + val = { + println!("{}", pre); + suf + }; + + let _ = val; +} diff --git a/tests/ui/match_single_binding.rs b/tests/ui/match_single_binding.rs index fe63dcd63f2..eea64fcb292 100644 --- a/tests/ui/match_single_binding.rs +++ b/tests/ui/match_single_binding.rs @@ -126,3 +126,17 @@ fn main() { _ => println!("Not an array index start"), } } + +#[allow(dead_code)] +fn issue_8723() { + let (mut val, idx) = ("a b", 1); + + val = match val.split_at(idx) { + (pre, suf) => { + println!("{}", pre); + suf + }, + }; + + let _ = val; +} diff --git a/tests/ui/match_single_binding.stderr b/tests/ui/match_single_binding.stderr index d939291f53c..5d4e7314b21 100644 --- a/tests/ui/match_single_binding.stderr +++ b/tests/ui/match_single_binding.stderr @@ -9,7 +9,7 @@ LL | | } | |_____^ | = note: `-D clippy::match-single-binding` implied by `-D warnings` -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let (x, y, z) = (a, b, c); LL + { @@ -25,7 +25,7 @@ LL | | (x, y, z) => println!("{} {} {}", x, y, z), LL | | } | |_____^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let (x, y, z) = (a, b, c); LL + println!("{} {} {}", x, y, z); @@ -88,7 +88,7 @@ LL | | Point { x, y } => println!("Coords: ({}, {})", x, y), LL | | } | |_____^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let Point { x, y } = p; LL + println!("Coords: ({}, {})", x, y); @@ -102,7 +102,7 @@ LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), LL | | } | |_____^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let Point { x: x1, y: y1 } = p; LL + println!("Coords: ({}, {})", x1, y1); @@ -116,7 +116,7 @@ LL | | ref r => println!("Got a reference to {}", r), LL | | } | |_____^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let ref r = x; LL + println!("Got a reference to {}", r); @@ -130,7 +130,7 @@ LL | | ref mut mr => println!("Got a mutable reference to {}", mr), LL | | } | |_____^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let ref mut mr = x; LL + println!("Got a mutable reference to {}", mr); @@ -144,7 +144,7 @@ LL | | Point { x, y } => x * y, LL | | }; | |______^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let Point { x, y } = coords(); LL + let product = x * y; @@ -159,7 +159,7 @@ LL | | unwrapped => unwrapped, LL | | }) | |_________^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ .map(|i| { LL + let unwrapped = i.unwrap(); @@ -176,5 +176,25 @@ LL | | _ => println!("Not an array index start"), LL | | } | |_____^ help: consider using the match body instead: `println!("Not an array index start");` -error: aborting due to 12 previous errors +error: this assignment could be simplified + --> $DIR/match_single_binding.rs:134:5 + | +LL | / val = match val.split_at(idx) { +LL | | (pre, suf) => { +LL | | println!("{}", pre); +LL | | suf +LL | | }, +LL | | }; + | |_____^ + | +help: consider removing the `match` expression + | +LL ~ let (pre, suf) = val.split_at(idx); +LL + val = { +LL + println!("{}", pre); +LL + suf +LL ~ }; + | + +error: aborting due to 13 previous errors diff --git a/tests/ui/match_single_binding2.stderr b/tests/ui/match_single_binding2.stderr index d3493319466..22bf7d8be4a 100644 --- a/tests/ui/match_single_binding2.stderr +++ b/tests/ui/match_single_binding2.stderr @@ -8,7 +8,7 @@ LL | | }, | |_____________^ | = note: `-D clippy::match-single-binding` implied by `-D warnings` -help: consider using `let` statement +help: consider using a `let` statement | LL ~ Some((iter, _item)) => { LL + let (min, max) = iter.size_hint(); @@ -24,7 +24,7 @@ LL | | (a, b) => println!("a {:?} and b {:?}", a, b), LL | | } | |_____________^ | -help: consider using `let` statement +help: consider using a `let` statement | LL ~ let (a, b) = get_tup(); LL + println!("a {:?} and b {:?}", a, b); diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index 977ce54327b..9805097084d 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -26,7 +26,6 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::collections::HashSet; use std::collections::VecDeque; -use std::iter::FromIterator; use std::ops::Mul; use std::rc::{self, Rc}; use std::sync::{self, Arc}; diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index b63672dd6fd..6be38b24fbd 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,5 +1,5 @@ error: methods called `new` usually return `Self` - --> $DIR/methods.rs:104:5 + --> $DIR/methods.rs:103:5 | LL | / fn new() -> i32 { LL | | 0 @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::new-ret-no-self` implied by `-D warnings` error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> $DIR/methods.rs:125:13 + --> $DIR/methods.rs:124:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ diff --git a/tests/ui/eval_order_dependence.rs b/tests/ui/mixed_read_write_in_expression.rs index aad78319d48..7640057ab6e 100644 --- a/tests/ui/eval_order_dependence.rs +++ b/tests/ui/mixed_read_write_in_expression.rs @@ -1,4 +1,4 @@ -#[warn(clippy::eval_order_dependence)] +#[warn(clippy::mixed_read_write_in_expression)] #[allow( unused_assignments, unused_variables, diff --git a/tests/ui/eval_order_dependence.stderr b/tests/ui/mixed_read_write_in_expression.stderr index 7c6265a0879..2e951cdbcbf 100644 --- a/tests/ui/eval_order_dependence.stderr +++ b/tests/ui/mixed_read_write_in_expression.stderr @@ -1,48 +1,48 @@ error: unsequenced read of `x` - --> $DIR/eval_order_dependence.rs:14:9 + --> $DIR/mixed_read_write_in_expression.rs:14:9 | LL | } + x; | ^ | - = note: `-D clippy::eval-order-dependence` implied by `-D warnings` + = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings` note: whether read occurs before this write depends on evaluation order - --> $DIR/eval_order_dependence.rs:12:9 + --> $DIR/mixed_read_write_in_expression.rs:12:9 | LL | x = 1; | ^^^^^ error: unsequenced read of `x` - --> $DIR/eval_order_dependence.rs:17:5 + --> $DIR/mixed_read_write_in_expression.rs:17:5 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> $DIR/eval_order_dependence.rs:18:9 + --> $DIR/mixed_read_write_in_expression.rs:18:9 | LL | x = 20; | ^^^^^^ error: unsequenced read of `x` - --> $DIR/eval_order_dependence.rs:30:12 + --> $DIR/mixed_read_write_in_expression.rs:30:12 | LL | a: x, | ^ | note: whether read occurs before this write depends on evaluation order - --> $DIR/eval_order_dependence.rs:32:13 + --> $DIR/mixed_read_write_in_expression.rs:32:13 | LL | x = 6; | ^^^^^ error: unsequenced read of `x` - --> $DIR/eval_order_dependence.rs:39:9 + --> $DIR/mixed_read_write_in_expression.rs:39:9 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> $DIR/eval_order_dependence.rs:40:13 + --> $DIR/mixed_read_write_in_expression.rs:40:13 | LL | x = 20; | ^^^^^^ diff --git a/tests/ui/range_contains.fixed b/tests/ui/range_contains.fixed index 47c974e614b..f4977199711 100644 --- a/tests/ui/range_contains.fixed +++ b/tests/ui/range_contains.fixed @@ -6,7 +6,7 @@ #[allow(clippy::short_circuit_statement)] #[allow(clippy::unnecessary_operation)] fn main() { - let x = 9_u32; + let x = 9_i32; // order shouldn't matter (8..12).contains(&x); @@ -43,6 +43,12 @@ fn main() { let y = 3.; (0. ..1.).contains(&y); !(0. ..=1.).contains(&y); + + // handle negatives #8721 + (-10..=10).contains(&x); + x >= 10 && x <= -10; + (-3. ..=3.).contains(&y); + y >= 3. && y <= -3.; } // Fix #6373 diff --git a/tests/ui/range_contains.rs b/tests/ui/range_contains.rs index 835deced5e4..9e2180b0c99 100644 --- a/tests/ui/range_contains.rs +++ b/tests/ui/range_contains.rs @@ -6,7 +6,7 @@ #[allow(clippy::short_circuit_statement)] #[allow(clippy::unnecessary_operation)] fn main() { - let x = 9_u32; + let x = 9_i32; // order shouldn't matter x >= 8 && x < 12; @@ -43,6 +43,12 @@ fn main() { let y = 3.; y >= 0. && y < 1.; y < 0. || y > 1.; + + // handle negatives #8721 + x >= -10 && x <= 10; + x >= 10 && x <= -10; + y >= -3. && y <= 3.; + y >= 3. && y <= -3.; } // Fix #6373 diff --git a/tests/ui/range_contains.stderr b/tests/ui/range_contains.stderr index bc79f1bca84..1817ee1715d 100644 --- a/tests/ui/range_contains.stderr +++ b/tests/ui/range_contains.stderr @@ -84,5 +84,17 @@ error: manual `!RangeInclusive::contains` implementation LL | y < 0. || y > 1.; | ^^^^^^^^^^^^^^^^ help: use: `!(0. ..=1.).contains(&y)` -error: aborting due to 14 previous errors +error: manual `RangeInclusive::contains` implementation + --> $DIR/range_contains.rs:48:5 + | +LL | x >= -10 && x <= 10; + | ^^^^^^^^^^^^^^^^^^^ help: use: `(-10..=10).contains(&x)` + +error: manual `RangeInclusive::contains` implementation + --> $DIR/range_contains.rs:50:5 + | +LL | y >= -3. && y <= 3.; + | ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)` + +error: aborting due to 16 previous errors diff --git a/tests/ui/rc_clone_in_vec_init/arc.rs b/tests/ui/rc_clone_in_vec_init/arc.rs new file mode 100644 index 00000000000..384060e6eae --- /dev/null +++ b/tests/ui/rc_clone_in_vec_init/arc.rs @@ -0,0 +1,68 @@ +#![warn(clippy::rc_clone_in_vec_init)] +use std::sync::{Arc, Mutex}; + +fn main() {} + +fn should_warn_simple_case() { + let v = vec![Arc::new("x".to_string()); 2]; +} + +fn should_warn_simple_case_with_big_indentation() { + if true { + let k = 1; + dbg!(k); + if true { + let v = vec![Arc::new("x".to_string()); 2]; + } + } +} + +fn should_warn_complex_case() { + let v = vec![ + std::sync::Arc::new(Mutex::new({ + let x = 1; + dbg!(x); + x + })); + 2 + ]; + + let v1 = vec![ + Arc::new(Mutex::new({ + let x = 1; + dbg!(x); + x + })); + 2 + ]; +} + +fn should_not_warn_custom_arc() { + #[derive(Clone)] + struct Arc; + + impl Arc { + fn new() -> Self { + Arc + } + } + + let v = vec![Arc::new(); 2]; +} + +fn should_not_warn_vec_from_elem_but_not_arc() { + let v = vec![String::new(); 2]; + let v1 = vec![1; 2]; + let v2 = vec![ + Box::new(std::sync::Arc::new({ + let y = 3; + dbg!(y); + y + })); + 2 + ]; +} + +fn should_not_warn_vec_macro_but_not_from_elem() { + let v = vec![Arc::new("x".to_string())]; +} diff --git a/tests/ui/rc_clone_in_vec_init/arc.stderr b/tests/ui/rc_clone_in_vec_init/arc.stderr new file mode 100644 index 00000000000..ce84186c8e3 --- /dev/null +++ b/tests/ui/rc_clone_in_vec_init/arc.stderr @@ -0,0 +1,109 @@ +error: calling `Arc::new` in `vec![elem; len]` + --> $DIR/arc.rs:7:13 + | +LL | let v = vec![Arc::new("x".to_string()); 2]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` + = note: each element will point to the same `Arc` instance +help: consider initializing each `Arc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Arc::new("x".to_string()))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Arc` initialization to a variable + | +LL ~ let v = { +LL + let data = Arc::new("x".to_string()); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Arc::new` in `vec![elem; len]` + --> $DIR/arc.rs:15:21 + | +LL | let v = vec![Arc::new("x".to_string()); 2]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each element will point to the same `Arc` instance +help: consider initializing each `Arc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Arc::new("x".to_string()))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Arc` initialization to a variable + | +LL ~ let v = { +LL + let data = Arc::new("x".to_string()); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Arc::new` in `vec![elem; len]` + --> $DIR/arc.rs:21:13 + | +LL | let v = vec![ + | _____________^ +LL | | std::sync::Arc::new(Mutex::new({ +LL | | let x = 1; +LL | | dbg!(x); +... | +LL | | 2 +LL | | ]; + | |_____^ + | + = note: each element will point to the same `Arc` instance +help: consider initializing each `Arc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(std::sync::Arc::new(..))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Arc` initialization to a variable + | +LL ~ let v = { +LL + let data = std::sync::Arc::new(..); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Arc::new` in `vec![elem; len]` + --> $DIR/arc.rs:30:14 + | +LL | let v1 = vec![ + | ______________^ +LL | | Arc::new(Mutex::new({ +LL | | let x = 1; +LL | | dbg!(x); +... | +LL | | 2 +LL | | ]; + | |_____^ + | + = note: each element will point to the same `Arc` instance +help: consider initializing each `Arc` element individually + | +LL ~ let v1 = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Arc::new(..))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Arc` initialization to a variable + | +LL ~ let v1 = { +LL + let data = Arc::new(..); +LL + vec![data; 2] +LL ~ }; + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/rc_clone_in_vec_init/rc.rs b/tests/ui/rc_clone_in_vec_init/rc.rs new file mode 100644 index 00000000000..0394457fe17 --- /dev/null +++ b/tests/ui/rc_clone_in_vec_init/rc.rs @@ -0,0 +1,69 @@ +#![warn(clippy::rc_clone_in_vec_init)] +use std::rc::Rc; +use std::sync::Mutex; + +fn main() {} + +fn should_warn_simple_case() { + let v = vec![Rc::new("x".to_string()); 2]; +} + +fn should_warn_simple_case_with_big_indentation() { + if true { + let k = 1; + dbg!(k); + if true { + let v = vec![Rc::new("x".to_string()); 2]; + } + } +} + +fn should_warn_complex_case() { + let v = vec![ + std::rc::Rc::new(Mutex::new({ + let x = 1; + dbg!(x); + x + })); + 2 + ]; + + let v1 = vec![ + Rc::new(Mutex::new({ + let x = 1; + dbg!(x); + x + })); + 2 + ]; +} + +fn should_not_warn_custom_arc() { + #[derive(Clone)] + struct Rc; + + impl Rc { + fn new() -> Self { + Rc + } + } + + let v = vec![Rc::new(); 2]; +} + +fn should_not_warn_vec_from_elem_but_not_rc() { + let v = vec![String::new(); 2]; + let v1 = vec![1; 2]; + let v2 = vec![ + Box::new(std::rc::Rc::new({ + let y = 3; + dbg!(y); + y + })); + 2 + ]; +} + +fn should_not_warn_vec_macro_but_not_from_elem() { + let v = vec![Rc::new("x".to_string())]; +} diff --git a/tests/ui/rc_clone_in_vec_init/rc.stderr b/tests/ui/rc_clone_in_vec_init/rc.stderr new file mode 100644 index 00000000000..0f5cc0cf98f --- /dev/null +++ b/tests/ui/rc_clone_in_vec_init/rc.stderr @@ -0,0 +1,109 @@ +error: calling `Rc::new` in `vec![elem; len]` + --> $DIR/rc.rs:8:13 + | +LL | let v = vec![Rc::new("x".to_string()); 2]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` + = note: each element will point to the same `Rc` instance +help: consider initializing each `Rc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Rc::new("x".to_string()))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Rc` initialization to a variable + | +LL ~ let v = { +LL + let data = Rc::new("x".to_string()); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Rc::new` in `vec![elem; len]` + --> $DIR/rc.rs:16:21 + | +LL | let v = vec![Rc::new("x".to_string()); 2]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each element will point to the same `Rc` instance +help: consider initializing each `Rc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Rc::new("x".to_string()))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Rc` initialization to a variable + | +LL ~ let v = { +LL + let data = Rc::new("x".to_string()); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Rc::new` in `vec![elem; len]` + --> $DIR/rc.rs:22:13 + | +LL | let v = vec![ + | _____________^ +LL | | std::rc::Rc::new(Mutex::new({ +LL | | let x = 1; +LL | | dbg!(x); +... | +LL | | 2 +LL | | ]; + | |_____^ + | + = note: each element will point to the same `Rc` instance +help: consider initializing each `Rc` element individually + | +LL ~ let v = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(std::rc::Rc::new(..))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Rc` initialization to a variable + | +LL ~ let v = { +LL + let data = std::rc::Rc::new(..); +LL + vec![data; 2] +LL ~ }; + | + +error: calling `Rc::new` in `vec![elem; len]` + --> $DIR/rc.rs:31:14 + | +LL | let v1 = vec![ + | ______________^ +LL | | Rc::new(Mutex::new({ +LL | | let x = 1; +LL | | dbg!(x); +... | +LL | | 2 +LL | | ]; + | |_____^ + | + = note: each element will point to the same `Rc` instance +help: consider initializing each `Rc` element individually + | +LL ~ let v1 = { +LL + let mut v = Vec::with_capacity(2); +LL + (0..2).for_each(|_| v.push(Rc::new(..))); +LL + v +LL ~ }; + | +help: or if this is intentional, consider extracting the `Rc` initialization to a variable + | +LL ~ let v1 = { +LL + let data = Rc::new(..); +LL + vec![data; 2] +LL ~ }; + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/recursive_format_impl.stderr b/tests/ui/recursive_format_impl.stderr index 6171696ed69..1a717ac92d8 100644 --- a/tests/ui/recursive_format_impl.stderr +++ b/tests/ui/recursive_format_impl.stderr @@ -6,15 +6,6 @@ LL | write!(f, "{}", self.to_string()) | = note: `-D clippy::recursive-format-impl` implied by `-D warnings` -error: unnecessary use of `to_string` - --> $DIR/recursive_format_impl.rs:61:50 - | -LL | Self::E(string) => write!(f, "E {}", string.to_string()), - | ^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings` - = note: this error originates in the macro `$crate::format_args` (in Nightly builds, run with -Z macro-backtrace for more info) - error: using `self` as `Display` in `impl Display` will cause infinite recursion --> $DIR/recursive_format_impl.rs:73:9 | @@ -87,5 +78,5 @@ LL | write!(f, "{}", &&**&&*self) | = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 11 previous errors +error: aborting due to 10 previous errors diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index 80f94e5f3cb..cf7d8c6e349 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -97,4 +97,39 @@ mod box_dyn { pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {} } +// https://github.com/rust-lang/rust-clippy/issues/8604 +mod box_fat_ptr { + use std::boxed::Box; + use std::path::Path; + use std::rc::Rc; + use std::sync::Arc; + + pub struct DynSized { + foo: [usize], + } + + struct S { + a: Box<Box<str>>, + b: Rc<Box<str>>, + c: Arc<Box<str>>, + + e: Box<Box<[usize]>>, + f: Box<Box<Path>>, + g: Box<Box<DynSized>>, + } + + pub fn test_box_str(_: Box<Box<str>>) {} + pub fn test_rc_str(_: Rc<Box<str>>) {} + pub fn test_arc_str(_: Arc<Box<str>>) {} + + pub fn test_box_slice(_: Box<Box<[usize]>>) {} + pub fn test_box_path(_: Box<Box<Path>>) {} + pub fn test_box_custom(_: Box<Box<DynSized>>) {} + + pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {} + pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {} + pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {} + pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {} +} + fn main() {} diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index c3b10e5f5e6..fab1b069fcb 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -143,5 +143,41 @@ LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {} = note: `Box<Box<dyn T>>` is already on the heap, `Rc<Box<Box<dyn T>>>` makes an extra allocation = help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>` -error: aborting due to 16 previous errors +error: usage of `Rc<Box<Box<str>>>` + --> $DIR/redundant_allocation.rs:129:31 + | +LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {} + | ^^^^^^^^^^^^^^^^^ + | + = note: `Box<Box<str>>` is already on the heap, `Rc<Box<Box<str>>>` makes an extra allocation + = help: consider using just `Rc<Box<str>>` or `Box<Box<str>>` + +error: usage of `Rc<Box<Box<[usize]>>>` + --> $DIR/redundant_allocation.rs:130:33 + | +LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {} + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Box<Box<[usize]>>` is already on the heap, `Rc<Box<Box<[usize]>>>` makes an extra allocation + = help: consider using just `Rc<Box<[usize]>>` or `Box<Box<[usize]>>` + +error: usage of `Rc<Box<Box<Path>>>` + --> $DIR/redundant_allocation.rs:131:32 + | +LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: `Box<Box<Path>>` is already on the heap, `Rc<Box<Box<Path>>>` makes an extra allocation + = help: consider using just `Rc<Box<Path>>` or `Box<Box<Path>>` + +error: usage of `Rc<Box<Box<DynSized>>>` + --> $DIR/redundant_allocation.rs:132:34 + | +LL | pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Box<Box<DynSized>>` is already on the heap, `Rc<Box<Box<DynSized>>>` makes an extra allocation + = help: consider using just `Rc<Box<DynSized>>` or `Box<Box<DynSized>>` + +error: aborting due to 20 previous errors diff --git a/tests/ui/rename.fixed b/tests/ui/rename.fixed index 9c4079ad6d3..53288be9404 100644 --- a/tests/ui/rename.fixed +++ b/tests/ui/rename.fixed @@ -10,6 +10,7 @@ #![allow(clippy::cognitive_complexity)] #![allow(clippy::disallowed_methods)] #![allow(clippy::disallowed_types)] +#![allow(clippy::mixed_read_write_in_expression)] #![allow(clippy::for_loops_over_fallibles)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] @@ -39,6 +40,7 @@ #![warn(clippy::cognitive_complexity)] #![warn(clippy::disallowed_methods)] #![warn(clippy::disallowed_types)] +#![warn(clippy::mixed_read_write_in_expression)] #![warn(clippy::for_loops_over_fallibles)] #![warn(clippy::for_loops_over_fallibles)] #![warn(clippy::useless_conversion)] diff --git a/tests/ui/rename.rs b/tests/ui/rename.rs index e83e66b7fbd..539f34f847a 100644 --- a/tests/ui/rename.rs +++ b/tests/ui/rename.rs @@ -10,6 +10,7 @@ #![allow(clippy::cognitive_complexity)] #![allow(clippy::disallowed_methods)] #![allow(clippy::disallowed_types)] +#![allow(clippy::mixed_read_write_in_expression)] #![allow(clippy::for_loops_over_fallibles)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] @@ -39,6 +40,7 @@ #![warn(clippy::cyclomatic_complexity)] #![warn(clippy::disallowed_method)] #![warn(clippy::disallowed_type)] +#![warn(clippy::eval_order_dependence)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::identity_conversion)] diff --git a/tests/ui/rename.stderr b/tests/ui/rename.stderr index f811b10d017..8ea46b580a8 100644 --- a/tests/ui/rename.stderr +++ b/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:35:9 + --> $DIR/rename.rs:36:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` @@ -7,202 +7,208 @@ LL | #![warn(clippy::block_in_if_condition_expr)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:36:9 + --> $DIR/rename.rs:37:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:37:9 + --> $DIR/rename.rs:38:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:38:9 + --> $DIR/rename.rs:39:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:39:9 + --> $DIR/rename.rs:40:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:40:9 + --> $DIR/rename.rs:41:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:41:9 + --> $DIR/rename.rs:42:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` +error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` + --> $DIR/rename.rs:43:9 + | +LL | #![warn(clippy::eval_order_dependence)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` + error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles` - --> $DIR/rename.rs:42:9 + --> $DIR/rename.rs:44:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles` - --> $DIR/rename.rs:43:9 + --> $DIR/rename.rs:45:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:44:9 + --> $DIR/rename.rs:46:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 34 previous errors +error: aborting due to 35 previous errors diff --git a/tests/ui/self_assignment.rs b/tests/ui/self_assignment.rs index a7cbb9cd78b..ef647622910 100644 --- a/tests/ui/self_assignment.rs +++ b/tests/ui/self_assignment.rs @@ -39,7 +39,7 @@ pub fn negatives_not_equal(mut a: usize, b: &mut usize, mut s: S) { t.0 = t.1; } -#[allow(clippy::eval_order_dependence)] +#[allow(clippy::mixed_read_write_in_expression)] pub fn negatives_side_effects() { let mut v = vec![1, 2, 3, 4, 5]; let mut i = 0; diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index c4a3301e722..f83a6dd0eb2 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -29,8 +29,8 @@ fn should_not_trigger_lint_with_mutex_guard_outside_match() { match is_foo { true => { mutex.lock().unwrap().bar(); - } - false => {} + }, + false => {}, }; } @@ -43,8 +43,8 @@ fn should_not_trigger_lint_with_mutex_guard_when_taking_ownership_in_match() { Ok(guard) => { guard.foo(); mutex.lock().unwrap().bar(); - } - _ => {} + }, + _ => {}, }; } @@ -57,8 +57,8 @@ fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() { match mutex.lock().unwrap().foo() { true => { mutex.lock().unwrap().bar(); - } - false => {} + }, + false => {}, }; } @@ -68,10 +68,10 @@ fn should_not_trigger_lint_for_insignificant_drop() { match 1u64.to_string().is_empty() { true => { println!("It was empty") - } + }, false => { println!("It was not empty") - } + }, } } @@ -131,12 +131,12 @@ fn should_trigger_lint_with_wrapped_mutex() { 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); - } + }, 2 => { println!("Got 2. Is it still 2?"); println!("{}", s.lock_m().get_the_value()); - } - _ => {} + }, + _ => {}, } println!("All done!"); } @@ -152,12 +152,12 @@ fn should_trigger_lint_with_double_wrapped_mutex() { 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); - } + }, 2 => { println!("Got 2. Is it still 2?"); println!("{}", s.lock_m().get_the_value()); - } - _ => {} + }, + _ => {}, } println!("All done!"); } @@ -201,10 +201,10 @@ fn should_trigger_lint_for_vec() { let current_count = counter.i.load(Ordering::Relaxed); println!("Current count {}", current_count); assert_eq!(current_count, 0); - } - 1 => {} - 3 => {} - _ => {} + }, + 1 => {}, + 3 => {}, + _ => {}, }; } @@ -224,8 +224,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { println!("started"); mutex1.lock().unwrap().s.len(); println!("done"); - } - (_, _) => {} + }, + (_, _) => {}, }; match (true, mutex1.lock().unwrap().s.len(), true) { @@ -233,8 +233,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { println!("started"); mutex1.lock().unwrap().s.len(); println!("done"); - } - (_, _, _) => {} + }, + (_, _, _) => {}, }; let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); @@ -244,8 +244,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { mutex1.lock().unwrap().s.len(); mutex2.lock().unwrap().s.len(); println!("done"); - } - (_, _, _) => {} + }, + (_, _, _) => {}, }; let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() }); @@ -255,19 +255,18 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { mutex1.lock().unwrap().s.len(); mutex2.lock().unwrap().s.len(); println!("done"); - } - _ => {} + }, + _ => {}, }; - match (true, mutex3.lock().unwrap().s.as_str()) { (_, "three") => { println!("started"); mutex1.lock().unwrap().s.len(); mutex2.lock().unwrap().s.len(); println!("done"); - } - (_, _) => {} + }, + (_, _) => {}, }; } } @@ -282,15 +281,15 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { match mutex.lock().unwrap().s.len() > 1 { true => { mutex.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; match 1 < mutex.lock().unwrap().s.len() { true => { mutex.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; } @@ -300,20 +299,30 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { // drop problem, the lint recommends moving the entire binary operation. fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op() { let mutex1 = Mutex::new(StateWithField { s: "state".to_owned() }); - let mutex2 = Mutex::new(StateWithField { s: "statewithfield".to_owned() }); + let mutex2 = Mutex::new(StateWithField { + s: "statewithfield".to_owned(), + }); match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { true => { - println!("{} < {}", mutex1.lock().unwrap().s.len(), mutex2.lock().unwrap().s.len()); - } - false => {} + println!( + "{} < {}", + mutex1.lock().unwrap().s.len(), + mutex2.lock().unwrap().s.len() + ); + }, + false => {}, }; match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { true => { - println!("{} >= {}", mutex1.lock().unwrap().s.len(), mutex2.lock().unwrap().s.len()); - } - false => {} + println!( + "{} >= {}", + mutex1.lock().unwrap().s.len(), + mutex2.lock().unwrap().s.len() + ); + }, + false => {}, }; } @@ -328,8 +337,8 @@ fn should_not_trigger_lint_for_closure_in_scrutinee() { match get_mutex_guard() > 1 { true => { mutex1.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; } @@ -343,8 +352,8 @@ fn should_trigger_lint_for_return_from_closure_in_scrutinee() { match get_mutex_guard().s.len() > 1 { true => { mutex1.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; } @@ -357,13 +366,20 @@ fn should_trigger_lint_for_return_from_match_in_scrutinee() { // Should trigger lint because the nested match within the scrutinee returns a temporary with a // significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. - match match i { 100 => mutex1.lock().unwrap(), _ => mutex2.lock().unwrap() }.s.len() > 1 { + match match i { + 100 => mutex1.lock().unwrap(), + _ => mutex2.lock().unwrap(), + } + .s + .len() + > 1 + { true => { mutex1.lock().unwrap().s.len(); - } + }, false => { println!("nothing to do here"); - } + }, }; } @@ -376,11 +392,19 @@ fn should_trigger_lint_for_return_from_if_in_scrutinee() { // Should trigger lint because the nested if-expression within the scrutinee returns a temporary // with a significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. - match if i > 1 { mutex1.lock().unwrap() } else { mutex2.lock().unwrap() }.s.len() > 1 { + match if i > 1 { + mutex1.lock().unwrap() + } else { + mutex2.lock().unwrap() + } + .s + .len() + > 1 + { true => { mutex1.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; } @@ -392,11 +416,15 @@ fn should_not_trigger_lint_for_if_in_scrutinee() { // Should not trigger the lint because the temporary with a significant drop *is* dropped within // the body of the if-expression nested within the match scrutinee, and therefore does not have // a potentially surprising lifetime. - match if i > 1 { mutex.lock().unwrap().s.len() > 1 } else { false } { + match if i > 1 { + mutex.lock().unwrap().s.len() > 1 + } else { + false + } { true => { mutex.lock().unwrap().s.len(); - } - false => {} + }, + false => {}, }; } @@ -430,7 +458,9 @@ struct StateStringWithBoxedMutexGuard { impl StateStringWithBoxedMutexGuard { fn new() -> StateStringWithBoxedMutexGuard { - StateStringWithBoxedMutexGuard { s: Mutex::new("A String".to_owned()) } + StateStringWithBoxedMutexGuard { + s: Mutex::new("A String".to_owned()), + } } fn lock(&self) -> Box<MutexGuard<String>> { Box::new(self.s.lock().unwrap()) @@ -450,7 +480,6 @@ fn should_trigger_lint_for_boxed_mutex_guard_holding_string() { }; } - struct StateWithIntField { i: u64, } @@ -467,36 +496,36 @@ fn should_trigger_lint_in_assign_expr() { match mutex.lock().unwrap().i = i { _ => { println!("{}", mutex.lock().unwrap().i); - } + }, }; match i = mutex.lock().unwrap().i { _ => { println!("{}", mutex.lock().unwrap().i); - } + }, }; match mutex.lock().unwrap().i += 1 { _ => { println!("{}", mutex.lock().unwrap().i); - } + }, }; match i += mutex.lock().unwrap().i { _ => { println!("{}", mutex.lock().unwrap().i); - } + }, }; } #[derive(Debug)] enum RecursiveEnum { - Foo(Option<Box<RecursiveEnum>>) + Foo(Option<Box<RecursiveEnum>>), } #[derive(Debug)] enum GenericRecursiveEnum<T> { - Foo(T, Option<Box<GenericRecursiveEnum<T>>>) + Foo(T, Option<Box<GenericRecursiveEnum<T>>>), } fn should_not_cause_stack_overflow() { @@ -506,20 +535,20 @@ fn should_not_cause_stack_overflow() { match f { RecursiveEnum::Foo(Some(f)) => { println!("{:?}", f) - } + }, RecursiveEnum::Foo(f) => { println!("{:?}", f) - } + }, } let f = GenericRecursiveEnum::Foo(1u64, Some(Box::new(GenericRecursiveEnum::Foo(2u64, None)))); match f { GenericRecursiveEnum::Foo(i, Some(f)) => { println!("{} {:?}", i, f) - } + }, GenericRecursiveEnum::Foo(i, f) => { println!("{} {:?}", i, f) - } + }, } } diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr index c442e93f539..af160564985 100644 --- a/tests/ui/significant_drop_in_scrutinee.stderr +++ b/tests/ui/significant_drop_in_scrutinee.stderr @@ -102,13 +102,13 @@ LL | match mutex3.lock().unwrap().s.as_str() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:263:22 + --> $DIR/significant_drop_in_scrutinee.rs:262:22 | LL | match (true, mutex3.lock().unwrap().s.as_str()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:282:11 + --> $DIR/significant_drop_in_scrutinee.rs:281:11 | LL | match mutex.lock().unwrap().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:289:11 + --> $DIR/significant_drop_in_scrutinee.rs:288:11 | LL | match 1 < mutex.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:305:11 + --> $DIR/significant_drop_in_scrutinee.rs:306:11 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:312:11 + --> $DIR/significant_drop_in_scrutinee.rs:317:11 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:343:11 + --> $DIR/significant_drop_in_scrutinee.rs:352:11 | LL | match get_mutex_guard().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,31 +168,53 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:360:11 - | -LL | match match i { 100 => mutex1.lock().unwrap(), _ => mutex2.lock().unwrap() }.s.len() > 1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/significant_drop_in_scrutinee.rs:369:11 + | +LL | match match i { + | ___________^ +LL | | 100 => mutex1.lock().unwrap(), +LL | | _ => mutex2.lock().unwrap(), +LL | | } +LL | | .s +LL | | .len() +LL | | > 1 + | |___________^ | help: try moving the temporary above the match | -LL ~ let value = match i { 100 => mutex1.lock().unwrap(), _ => mutex2.lock().unwrap() }.s.len() > 1; -LL ~ match value { - | +LL ~ let value = match i { +LL + 100 => mutex1.lock().unwrap(), +LL + _ => mutex2.lock().unwrap(), +LL + } +LL + .s +LL + .len() + ... error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:379:11 - | -LL | match if i > 1 { mutex1.lock().unwrap() } else { mutex2.lock().unwrap() }.s.len() > 1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/significant_drop_in_scrutinee.rs:395:11 + | +LL | match if i > 1 { + | ___________^ +LL | | mutex1.lock().unwrap() +LL | | } else { +LL | | mutex2.lock().unwrap() +... | +LL | | .len() +LL | | > 1 + | |___________^ | help: try moving the temporary above the match | -LL ~ let value = if i > 1 { mutex1.lock().unwrap() } else { mutex2.lock().unwrap() }.s.len() > 1; -LL ~ match value { - | +LL ~ let value = if i > 1 { +LL + mutex1.lock().unwrap() +LL + } else { +LL + mutex2.lock().unwrap() +LL + } +LL + .s + ... error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:421:11 + --> $DIR/significant_drop_in_scrutinee.rs:449:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,13 +226,13 @@ LL ~ match value { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:447:11 + --> $DIR/significant_drop_in_scrutinee.rs:477:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:467:11 + --> $DIR/significant_drop_in_scrutinee.rs:496:11 | LL | match mutex.lock().unwrap().i = i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +244,7 @@ LL ~ match () { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:473:11 + --> $DIR/significant_drop_in_scrutinee.rs:502:11 | LL | match i = mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +256,7 @@ LL ~ match () { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:479:11 + --> $DIR/significant_drop_in_scrutinee.rs:508:11 | LL | match mutex.lock().unwrap().i += 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -246,7 +268,7 @@ LL ~ match () { | error: temporary with significant drop in match scrutinee - --> $DIR/significant_drop_in_scrutinee.rs:485:11 + --> $DIR/significant_drop_in_scrutinee.rs:514:11 | LL | match i += mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/temporary_assignment.rs b/tests/ui/temporary_assignment.rs index b4a931043b0..ac4c1bc6597 100644 --- a/tests/ui/temporary_assignment.rs +++ b/tests/ui/temporary_assignment.rs @@ -1,5 +1,4 @@ #![warn(clippy::temporary_assignment)] -#![allow(const_item_mutation)] use std::ops::{Deref, DerefMut}; diff --git a/tests/ui/temporary_assignment.stderr b/tests/ui/temporary_assignment.stderr index 4cc32c79f05..7d79901a28d 100644 --- a/tests/ui/temporary_assignment.stderr +++ b/tests/ui/temporary_assignment.stderr @@ -1,5 +1,5 @@ error: assignment to temporary - --> $DIR/temporary_assignment.rs:48:5 + --> $DIR/temporary_assignment.rs:47:5 | LL | Struct { field: 0 }.field = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | Struct { field: 0 }.field = 1; = note: `-D clippy::temporary-assignment` implied by `-D warnings` error: assignment to temporary - --> $DIR/temporary_assignment.rs:49:5 + --> $DIR/temporary_assignment.rs:48:5 | LL | / MultiStruct { LL | | structure: Struct { field: 0 }, @@ -17,13 +17,13 @@ LL | | .field = 1; | |______________^ error: assignment to temporary - --> $DIR/temporary_assignment.rs:54:5 + --> $DIR/temporary_assignment.rs:53:5 | LL | ArrayStruct { array: [0] }.array[0] = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: assignment to temporary - --> $DIR/temporary_assignment.rs:55:5 + --> $DIR/temporary_assignment.rs:54:5 | LL | (0, 0).0 = 1; | ^^^^^^^^^^^^ diff --git a/tests/ui/undocumented_unsafe_blocks.rs b/tests/ui/undocumented_unsafe_blocks.rs index 7be15b0b2dd..33b6a82f9d2 100644 --- a/tests/ui/undocumented_unsafe_blocks.rs +++ b/tests/ui/undocumented_unsafe_blocks.rs @@ -1,7 +1,7 @@ // aux-build:proc_macro_unsafe.rs #![warn(clippy::undocumented_unsafe_blocks)] -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::missing_safety_doc)] extern crate proc_macro_unsafe; @@ -334,4 +334,155 @@ pub fn print_binary_tree() { println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); } +mod unsafe_impl_smoke_test { + unsafe trait A {} + + // error: no safety comment + unsafe impl A for () {} + + // Safety: ok + unsafe impl A for (i32) {} + + mod sub_mod { + // error: + unsafe impl B for (u32) {} + unsafe trait B {} + } + + #[rustfmt::skip] + mod sub_mod2 { + // + // SAFETY: ok + // + + unsafe impl B for (u32) {} + unsafe trait B {} + } +} + +mod unsafe_impl_from_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // ok + macro_rules! with_safety_comment { + ($t:ty) => { + // SAFETY: + unsafe impl T for $t {} + }; + } + + // ok + with_safety_comment!((i32)); +} + +mod unsafe_impl_macro_and_not_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // error + unsafe impl T for (i32) {} + + // ok + no_safety_comment!(u32); + + // error + unsafe impl T for (bool) {} +} + +#[rustfmt::skip] +mod unsafe_impl_valid_comment { + unsafe trait SaFety {} + // SaFety: + unsafe impl SaFety for () {} + + unsafe trait MultiLineComment {} + // The following impl is safe + // ... + // Safety: reason + unsafe impl MultiLineComment for () {} + + unsafe trait NoAscii {} + // 安全 SAFETY: 以下のコードは安全です + unsafe impl NoAscii for () {} + + unsafe trait InlineAndPrecedingComment {} + // SAFETY: + /* comment */ unsafe impl InlineAndPrecedingComment for () {} + + unsafe trait BuriedSafety {} + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe impl BuriedSafety for () {} + + unsafe trait MultiLineBlockComment {} + /* This is a description + * Safety: */ + unsafe impl MultiLineBlockComment for () {} +} + +#[rustfmt::skip] +mod unsafe_impl_invalid_comment { + unsafe trait NoComment {} + + unsafe impl NoComment for () {} + + unsafe trait InlineComment {} + + /* SAFETY: */ unsafe impl InlineComment for () {} + + unsafe trait TrailingComment {} + + unsafe impl TrailingComment for () {} // SAFETY: + + unsafe trait Interference {} + // SAFETY: + const BIG_NUMBER: i32 = 1000000; + unsafe impl Interference for () {} +} + +unsafe trait ImplInFn {} + +fn impl_in_fn() { + // error + unsafe impl ImplInFn for () {} + + // SAFETY: ok + unsafe impl ImplInFn for (i32) {} +} + +unsafe trait CrateRoot {} + +// error +unsafe impl CrateRoot for () {} + +// SAFETY: ok +unsafe impl CrateRoot for (i32) {} + fn main() {} diff --git a/tests/ui/undocumented_unsafe_blocks.stderr b/tests/ui/undocumented_unsafe_blocks.stderr index 87d445bd7b8..b79949e9d06 100644 --- a/tests/ui/undocumented_unsafe_blocks.stderr +++ b/tests/ui/undocumented_unsafe_blocks.stderr @@ -147,5 +147,121 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | = help: consider adding a safety comment on the preceding line -error: aborting due to 18 previous errors +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:341:5 + | +LL | unsafe impl A for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:348:9 + | +LL | unsafe impl B for (u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:369:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:394:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:402:5 + | +LL | unsafe impl T for (i32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:394:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(u32); + | ----------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:408:5 + | +LL | unsafe impl T for (bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:454:5 + | +LL | unsafe impl NoComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:458:19 + | +LL | /* SAFETY: */ unsafe impl InlineComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:462:5 + | +LL | unsafe impl TrailingComment for () {} // SAFETY: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:467:5 + | +LL | unsafe impl Interference for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:474:5 + | +LL | unsafe impl ImplInFn for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:483:1 + | +LL | unsafe impl CrateRoot for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: aborting due to 31 previous errors diff --git a/tests/ui/unit_cmp.rs b/tests/ui/unit_cmp.rs index 8d3a4eed82e..3d271104361 100644 --- a/tests/ui/unit_cmp.rs +++ b/tests/ui/unit_cmp.rs @@ -1,5 +1,9 @@ #![warn(clippy::unit_cmp)] -#![allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow( + clippy::no_effect, + clippy::unnecessary_operation, + clippy::derive_partial_eq_without_eq +)] #[derive(PartialEq)] pub struct ContainsUnit(()); // should be fine diff --git a/tests/ui/unit_cmp.stderr b/tests/ui/unit_cmp.stderr index 824506a4257..41cf19ae685 100644 --- a/tests/ui/unit_cmp.stderr +++ b/tests/ui/unit_cmp.stderr @@ -1,5 +1,5 @@ error: ==-comparison of unit values detected. This will always be true - --> $DIR/unit_cmp.rs:12:8 + --> $DIR/unit_cmp.rs:16:8 | LL | if { | ________^ @@ -12,7 +12,7 @@ LL | | } {} = note: `-D clippy::unit-cmp` implied by `-D warnings` error: >-comparison of unit values detected. This will always be false - --> $DIR/unit_cmp.rs:18:8 + --> $DIR/unit_cmp.rs:22:8 | LL | if { | ________^ @@ -23,7 +23,7 @@ LL | | } {} | |_____^ error: `assert_eq` of unit values detected. This will always succeed - --> $DIR/unit_cmp.rs:24:5 + --> $DIR/unit_cmp.rs:28:5 | LL | / assert_eq!( LL | | { @@ -35,7 +35,7 @@ LL | | ); | |_____^ error: `debug_assert_eq` of unit values detected. This will always succeed - --> $DIR/unit_cmp.rs:32:5 + --> $DIR/unit_cmp.rs:36:5 | LL | / debug_assert_eq!( LL | | { @@ -47,7 +47,7 @@ LL | | ); | |_____^ error: `assert_ne` of unit values detected. This will always fail - --> $DIR/unit_cmp.rs:41:5 + --> $DIR/unit_cmp.rs:45:5 | LL | / assert_ne!( LL | | { @@ -59,7 +59,7 @@ LL | | ); | |_____^ error: `debug_assert_ne` of unit values detected. This will always fail - --> $DIR/unit_cmp.rs:49:5 + --> $DIR/unit_cmp.rs:53:5 | LL | / debug_assert_ne!( LL | | { diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 7455e22d49b..f4f76cd3dd4 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -78,10 +78,10 @@ fn main() { require_slice(array.as_ref()); require_slice(array_ref.as_ref()); require_slice(slice); - require_slice(x_ref); + require_slice(&x_ref.to_owned()); // No longer flagged because of #8759. require_x(&Cow::<X>::Owned(x.clone())); - require_x(x_ref); + require_x(&x_ref.to_owned()); // No longer flagged because of #8759. require_deref_c_str(c_str); require_deref_os_str(os_str); @@ -152,6 +152,7 @@ fn main() { require_os_str(&OsString::from("x")); require_path(&std::path::PathBuf::from("x")); require_str(&String::from("x")); + require_slice(&[String::from("x")]); } fn require_c_str(_: &CStr) {} @@ -272,3 +273,59 @@ mod issue_8507 { 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()); + } +} diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index bbcd00ad220..fe09a489ab0 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -78,10 +78,10 @@ fn main() { require_slice(&array.to_owned()); require_slice(&array_ref.to_owned()); require_slice(&slice.to_owned()); - require_slice(&x_ref.to_owned()); + require_slice(&x_ref.to_owned()); // No longer flagged because of #8759. require_x(&Cow::<X>::Owned(x.clone()).into_owned()); - require_x(&x_ref.to_owned()); + require_x(&x_ref.to_owned()); // No longer flagged because of #8759. require_deref_c_str(c_str.to_owned()); require_deref_os_str(os_str.to_owned()); @@ -152,6 +152,7 @@ fn main() { require_os_str(&OsString::from("x").to_os_string()); require_path(&std::path::PathBuf::from("x").to_path_buf()); require_str(&String::from("x").to_string()); + require_slice(&[String::from("x")].to_owned()); } fn require_c_str(_: &CStr) {} @@ -272,3 +273,59 @@ mod issue_8507 { Box::new(build(y.to_string())) } } + +// 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()); + } +} diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index f9713559e4f..af7e7b41fb0 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -47,6 +47,18 @@ note: this value is dropped without further use LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ +error: redundant clone + --> $DIR/unnecessary_to_owned.rs:155:39 + | +LL | require_slice(&[String::from("x")].to_owned()); + | ^^^^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> $DIR/unnecessary_to_owned.rs:155:20 + | +LL | require_slice(&[String::from("x")].to_owned()); + | ^^^^^^^^^^^^^^^^^^^ + error: unnecessary use of `into_owned` --> $DIR/unnecessary_to_owned.rs:60:36 | @@ -151,12 +163,6 @@ error: unnecessary use of `to_owned` LL | require_slice(&slice.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `slice` -error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:81:19 - | -LL | require_slice(&x_ref.to_owned()); - | ^^^^^^^^^^^^^^^^^ help: use: `x_ref` - error: unnecessary use of `into_owned` --> $DIR/unnecessary_to_owned.rs:83:42 | @@ -164,12 +170,6 @@ LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:84:15 - | -LL | require_x(&x_ref.to_owned()); - | ^^^^^^^^^^^^^^^^^ help: use: `x_ref` - -error: unnecessary use of `to_owned` --> $DIR/unnecessary_to_owned.rs:86:25 | LL | require_deref_c_str(c_str.to_owned()); @@ -476,7 +476,7 @@ LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owne | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:197:14 + --> $DIR/unnecessary_to_owned.rs:198:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -492,22 +492,22 @@ LL + let path = match get_file_path(t) { | error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:220:14 + --> $DIR/unnecessary_to_owned.rs:221:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:225:14 + --> $DIR/unnecessary_to_owned.rs:226:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:272:24 + --> $DIR/unnecessary_to_owned.rs:273:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` -error: aborting due to 79 previous errors +error: aborting due to 78 previous errors diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index 3787ea99144..39f54c27bee 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -1,7 +1,5 @@ #![deny(clippy::useless_conversion)] -use std::convert::{TryFrom, TryInto}; - fn test_generic<T: Copy>(val: T) -> T { let _ = T::try_from(val).unwrap(); val.try_into().unwrap() diff --git a/tests/ui/useless_conversion_try.stderr b/tests/ui/useless_conversion_try.stderr index 2e0d9129bfb..b691c13f7db 100644 --- a/tests/ui/useless_conversion_try.stderr +++ b/tests/ui/useless_conversion_try.stderr @@ -1,5 +1,5 @@ error: useless conversion to the same type: `T` - --> $DIR/useless_conversion_try.rs:6:13 + --> $DIR/useless_conversion_try.rs:4:13 | LL | let _ = T::try_from(val).unwrap(); | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::useless_conversion)] = help: consider removing `T::try_from()` error: useless conversion to the same type: `T` - --> $DIR/useless_conversion_try.rs:7:5 + --> $DIR/useless_conversion_try.rs:5:5 | LL | val.try_into().unwrap() | ^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | val.try_into().unwrap() = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:29:21 + --> $DIR/useless_conversion_try.rs:27:21 | LL | let _: String = "foo".to_string().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:30:21 + --> $DIR/useless_conversion_try.rs:28:21 | LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); = help: consider removing `TryFrom::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:31:13 + --> $DIR/useless_conversion_try.rs:29:13 | LL | let _ = String::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:32:13 + --> $DIR/useless_conversion_try.rs:30:13 | LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:33:21 + --> $DIR/useless_conversion_try.rs:31:21 | LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:34:21 + --> $DIR/useless_conversion_try.rs:32:21 | LL | let _: String = "".to_owned().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | let _: String = "".to_owned().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:35:27 + --> $DIR/useless_conversion_try.rs:33:27 | LL | let _: String = match String::from("_").try_into() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/vec_init_then_push.rs b/tests/ui/vec_init_then_push.rs index 5099aad83bc..531745424a7 100644 --- a/tests/ui/vec_init_then_push.rs +++ b/tests/ui/vec_init_then_push.rs @@ -29,6 +29,12 @@ fn main() { // no lint vec.push(1); } + + let mut vec = Vec::with_capacity(5); + vec.push(1); + vec.push(2); + vec.push(3); + vec.push(4); } pub fn no_lint() -> Vec<i32> { @@ -44,3 +50,57 @@ pub fn no_lint() -> Vec<i32> { } } } + +fn _from_iter(items: impl Iterator<Item = u32>) -> Vec<u32> { + let mut v = Vec::new(); + v.push(0); + v.push(1); + v.extend(items); + v +} + +fn _cond_push(x: bool) -> Vec<u32> { + let mut v = Vec::new(); + v.push(0); + if x { + v.push(1); + } + v.push(2); + v +} + +fn _push_then_edit(x: u32) -> Vec<u32> { + let mut v = Vec::new(); + v.push(x); + v.push(1); + v[0] = v[1] + 5; + v +} + +fn _cond_push_with_large_start(x: bool) -> Vec<u32> { + let mut v = Vec::new(); + v.push(0); + v.push(1); + v.push(0); + v.push(1); + v.push(0); + v.push(0); + v.push(1); + v.push(0); + if x { + v.push(1); + } + + let mut v2 = Vec::new(); + v2.push(0); + v2.push(1); + v2.push(0); + v2.push(1); + v2.push(0); + v2.push(0); + v2.push(1); + v2.push(0); + v2.extend(&v); + + v2 +} diff --git a/tests/ui/vec_init_then_push.stderr b/tests/ui/vec_init_then_push.stderr index 9ec3e10e624..50b029fc337 100644 --- a/tests/ui/vec_init_then_push.stderr +++ b/tests/ui/vec_init_then_push.stderr @@ -3,7 +3,7 @@ error: calls to `push` immediately after creation | LL | / let mut def_err: Vec<u32> = Default::default(); LL | | def_err.push(0); - | |____________________^ help: consider using the `vec![]` macro: `let mut def_err: Vec<u32> = vec![..];` + | |____________________^ help: consider using the `vec![]` macro: `let def_err: Vec<u32> = vec![..];` | = note: `-D clippy::vec-init-then-push` implied by `-D warnings` @@ -30,5 +30,37 @@ LL | / new_err = Vec::new(); LL | | new_err.push(0); | |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];` -error: aborting due to 4 previous errors +error: calls to `push` immediately after creation + --> $DIR/vec_init_then_push.rs:73:5 + | +LL | / let mut v = Vec::new(); +LL | | v.push(x); +LL | | v.push(1); + | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` + +error: calls to `push` immediately after creation + --> $DIR/vec_init_then_push.rs:81:5 + | +LL | / let mut v = Vec::new(); +LL | | v.push(0); +LL | | v.push(1); +LL | | v.push(0); +... | +LL | | v.push(1); +LL | | v.push(0); + | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` + +error: calls to `push` immediately after creation + --> $DIR/vec_init_then_push.rs:94:5 + | +LL | / let mut v2 = Vec::new(); +LL | | v2.push(0); +LL | | v2.push(1); +LL | | v2.push(0); +... | +LL | | v2.push(1); +LL | | v2.push(0); + | |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];` + +error: aborting due to 7 previous errors |
