diff options
Diffstat (limited to 'src/tools/clippy/tests')
202 files changed, 4077 insertions, 1035 deletions
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index f340cf593..3b7c974b6 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -30,6 +30,7 @@ mod test_utils; /// All crates used in UI tests are listed here static TEST_DEPENDENCIES: &[&str] = &[ + "clippy_config", "clippy_lints", "clippy_utils", "futures", @@ -105,27 +106,20 @@ static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| { // whether to run internal tests or not const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal"); -fn canonicalize(path: impl AsRef<Path>) -> PathBuf { - let path = path.as_ref(); - fs::create_dir_all(path).unwrap(); - fs::canonicalize(path).unwrap_or_else(|err| panic!("{} cannot be canonicalized: {err}", path.display())) -} - fn base_config(test_dir: &str) -> (Config, Args) { let mut args = Args::test().unwrap(); args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0"); + let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())); let mut config = Config { mode: Mode::Yolo { rustfix: ui_test::RustfixMode::Everything, }, - stderr_filters: vec![(Match::PathBackslash, b"/")], - stdout_filters: vec![], filter_files: env::var("TESTNAME") .map(|filters| filters.split(',').map(str::to_string).collect()) .unwrap_or_default(), target: None, - out_dir: canonicalize(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())).join("ui_test"), + out_dir: target_dir.join("ui_test"), ..Config::rustc(Path::new("tests").join(test_dir)) }; config.with_args(&args, /* bless by default */ false); @@ -168,19 +162,13 @@ fn run_ui() { config .program .envs - .push(("CLIPPY_CONF_DIR".into(), Some(canonicalize("tests").into()))); - - let quiet = args.quiet; + .push(("CLIPPY_CONF_DIR".into(), Some("tests".into()))); ui_test::run_tests_generic( vec![config], ui_test::default_file_filter, ui_test::default_per_file_config, - if quiet { - status_emitter::Text::quiet() - } else { - status_emitter::Text::verbose() - }, + status_emitter::Text::from(args.format), ) .unwrap(); } @@ -194,17 +182,12 @@ fn run_internal_tests() { if let OutputConflictHandling::Error(err) = &mut config.output_conflict_handling { *err = "cargo uitest --features internal -- -- --bless".into(); } - let quiet = args.quiet; ui_test::run_tests_generic( vec![config], ui_test::default_file_filter, ui_test::default_per_file_config, - if quiet { - status_emitter::Text::quiet() - } else { - status_emitter::Text::verbose() - }, + status_emitter::Text::from(args.format), ) .unwrap(); } @@ -212,22 +195,9 @@ fn run_internal_tests() { fn run_ui_toml() { let (mut config, args) = base_config("ui-toml"); - config.stderr_filters = vec![ - ( - Match::Exact( - canonicalize("tests") - .parent() - .unwrap() - .to_string_lossy() - .as_bytes() - .to_vec(), - ), - b"$DIR", - ), - (Match::Exact(b"\\".to_vec()), b"/"), - ]; - - let quiet = args.quiet; + config + .stderr_filters + .push((Match::from(env::current_dir().unwrap().as_path()), b"$DIR")); ui_test::run_tests_generic( vec![config], @@ -238,11 +208,7 @@ fn run_ui_toml() { .envs .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into()))); }, - if quiet { - status_emitter::Text::quiet() - } else { - status_emitter::Text::verbose() - }, + status_emitter::Text::from(args.format), ) .unwrap(); } @@ -270,22 +236,9 @@ fn run_ui_cargo() { }); config.edition = None; - config.stderr_filters = vec![ - ( - Match::Exact( - canonicalize("tests") - .parent() - .unwrap() - .to_string_lossy() - .as_bytes() - .to_vec(), - ), - b"$DIR", - ), - (Match::Exact(b"\\".to_vec()), b"/"), - ]; - - let quiet = args.quiet; + config + .stderr_filters + .push((Match::from(env::current_dir().unwrap().as_path()), b"$DIR")); let ignored_32bit = |path: &Path| { // FIXME: for some reason the modules are linted in a different order for this test @@ -297,20 +250,8 @@ fn run_ui_cargo() { |path, config| { path.ends_with("Cargo.toml") && ui_test::default_any_file_filter(path, config) && !ignored_32bit(path) }, - |config, path, _file_contents| { - config.out_dir = canonicalize( - std::env::current_dir() - .unwrap() - .join("target") - .join("ui_test_cargo/") - .join(path.parent().unwrap()), - ); - }, - if quiet { - status_emitter::Text::quiet() - } else { - status_emitter::Text::verbose() - }, + |_config, _path, _file_contents| {}, + status_emitter::Text::from(args.format), ) .unwrap(); } diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index afde31fac..3f16c180e 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -28,6 +28,7 @@ fn dogfood_clippy() { "clippy_dev", "clippy_lints", "clippy_utils", + "clippy_config", "lintcheck", "rustc_tools_util", ] { @@ -56,7 +57,10 @@ fn run_metadata_collection_lint() { // Run collection as is std::env::set_var("ENABLE_METADATA_COLLECTION", "1"); - run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); + assert!(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) { @@ -79,9 +83,13 @@ fn run_metadata_collection_lint() { .unwrap(); // Running the collection again - run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); + assert!(run_clippy_for_package( + "clippy_lints", + &["-A", "unfulfilled_lint_expectations"] + )); } +#[must_use] fn run_clippy_for_package(project: &str, args: &[&str]) -> bool { let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed index 928596d08..9b5bf736f 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; +use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs index 50b28648c..c5bde47e4 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -8,8 +8,8 @@ extern crate rustc_lint; extern crate rustc_middle; #[macro_use] extern crate rustc_session; +use clippy_config::msrvs::Msrv; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs index b5ff3a542..f6abb3cc3 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs @@ -11,6 +11,6 @@ fn main() { const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"]; const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; - // Don't lint, not yet a diagnostic or language item - const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; + // Don't lint, not a diagnostic or language item + const OPS_MOD: [&str; 2] = ["core", "ops"]; } diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr index 58b1fd92b..076786329 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr @@ -19,8 +19,8 @@ LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"] error: hardcoded path to a diagnostic item --> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43 | -LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const OPS_MOD: [&str; 5] = ["core", "ops"]; + | ^^^^^^^^^^^^^^^ | = help: convert all references to use `sym::deref_method` diff --git a/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/clippy.toml b/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/clippy.toml new file mode 100644 index 000000000..34a1036e8 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/clippy.toml @@ -0,0 +1 @@ +ignore-interior-mutability = ["borrow_interior_mutable_const_ignore::Counted"]
\ No newline at end of file diff --git a/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/ignore.rs b/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/ignore.rs new file mode 100644 index 000000000..79c7cef6c --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/borrow_interior_mutable_const/ignore.rs @@ -0,0 +1,37 @@ +//@compile-flags: --crate-name borrow_interior_mutable_const_ignore + +#![warn(clippy::borrow_interior_mutable_const)] +#![allow(clippy::declare_interior_mutable_const)] + +use core::cell::Cell; +use std::cmp::{Eq, PartialEq}; +use std::collections::{HashMap, HashSet}; +use std::hash::{Hash, Hasher}; +use std::ops::Deref; +use std::sync::atomic::{AtomicUsize, Ordering}; + +struct Counted<T> { + count: AtomicUsize, + val: T, +} + +impl<T> Counted<T> { + const fn new(val: T) -> Self { + Self { + count: AtomicUsize::new(0), + val, + } + } +} + +enum OptionalCell { + Unfrozen(Counted<bool>), + Frozen, +} + +const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Counted::new(true)); +const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; + +fn main() { + let _ = &UNFROZEN_VARIANT; +} diff --git a/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/clippy.toml b/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/clippy.toml new file mode 100644 index 000000000..71d13212e --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/clippy.toml @@ -0,0 +1 @@ +ignore-interior-mutability = ["declare_interior_mutable_const_ignore::Counted"]
\ No newline at end of file diff --git a/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/ignore.rs b/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/ignore.rs new file mode 100644 index 000000000..6385cf4f8 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/declare_interior_mutable_const/ignore.rs @@ -0,0 +1,46 @@ +//@compile-flags: --crate-name declare_interior_mutable_const_ignore + +#![warn(clippy::declare_interior_mutable_const)] +#![allow(clippy::borrow_interior_mutable_const)] + +use core::cell::Cell; +use std::cmp::{Eq, PartialEq}; +use std::collections::{HashMap, HashSet}; +use std::hash::{Hash, Hasher}; +use std::ops::Deref; +use std::sync::atomic::{AtomicUsize, Ordering}; + +struct Counted<T> { + count: AtomicUsize, + val: T, +} + +impl<T> Counted<T> { + const fn new(val: T) -> Self { + Self { + count: AtomicUsize::new(0), + val, + } + } +} + +enum OptionalCell { + Unfrozen(Counted<bool>), + Frozen, +} + +const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Counted::new(true)); +const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; + +const fn unfrozen_variant() -> OptionalCell { + OptionalCell::Unfrozen(Counted::new(true)) +} + +const fn frozen_variant() -> OptionalCell { + OptionalCell::Frozen +} + +const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); +const FROZEN_VARIANT_FROM_FN: OptionalCell = frozen_variant(); + +fn main() {} diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs deleted file mode 100644 index 8f4e178cc..000000000 --- a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs +++ /dev/null @@ -1,16 +0,0 @@ -enum Foo { - AFoo, - BFoo, - CFoo, - DFoo, -} -enum Foo2 { - //~^ ERROR: all variants have the same postfix - AFoo, - BFoo, - CFoo, - DFoo, - EFoo, -} - -fn main() {} diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr deleted file mode 100644 index 11039b1db..000000000 --- a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: all variants have the same postfix: `Foo` - --> $DIR/enum_variant_names.rs:7:1 - | -LL | / enum Foo2 { -LL | | -LL | | AFoo, -LL | | BFoo, -... | -LL | | EFoo, -LL | | } - | |_^ - | - = help: remove the postfixes and use full paths to the variants instead of glob imports - = note: `-D clippy::enum-variant-names` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]` - -error: aborting due to previous error - diff --git a/src/tools/clippy/tests/ui-toml/impl_trait_in_params/clippy.toml b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/clippy.toml new file mode 100644 index 000000000..87e1f2357 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/clippy.toml @@ -0,0 +1 @@ +avoid-breaking-exported-api = false
\ No newline at end of file diff --git a/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.rs b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.rs new file mode 100644 index 000000000..08fc7edf1 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.rs @@ -0,0 +1,16 @@ +//! As avoid-breaking-exported-api is `false`, nothing here should lint +#![warn(clippy::impl_trait_in_params)] +#![no_main] +//@no-rustfix + +pub trait Trait {} + +trait Private { + fn t(_: impl Trait); + fn tt<T: Trait>(_: T); +} + +pub trait Public { + fn t(_: impl Trait); //~ ERROR: `impl Trait` used as a function parameter + fn tt<T: Trait>(_: T); +} diff --git a/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.stderr b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.stderr new file mode 100644 index 000000000..80c4f5ed4 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/impl_trait_in_params/impl_trait_in_params.stderr @@ -0,0 +1,15 @@ +error: `impl Trait` used as a function parameter + --> $DIR/impl_trait_in_params.rs:14:13 + | +LL | fn t(_: impl Trait); + | ^^^^^^^^^^ + | + = note: `-D clippy::impl-trait-in-params` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]` +help: add a type parameter + | +LL | fn t<{ /* Generic name */ }: Trait>(_: impl Trait); + | +++++++++++++++++++++++++++++++ + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs b/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs index 03fa71997..85e2fb8c7 100644 --- a/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs +++ b/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs @@ -1,4 +1,4 @@ -//@error-in-other-file: `invalid.version` is not a valid Rust version +//@error-in-other-file: not a valid Rust version #![allow(clippy::redundant_clone)] diff --git a/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.stderr b/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.stderr index e9d8fd2e0..f127c2408 100644 --- a/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.stderr +++ b/src/tools/clippy/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.stderr @@ -1,4 +1,8 @@ -error: error reading Clippy's configuration file. `invalid.version` is not a valid Rust version +error: error reading Clippy's configuration file: not a valid Rust version + --> $DIR/$DIR/clippy.toml:1:8 + | +LL | msrv = "invalid.version" + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold0/clippy.toml index f85aade6a..d41edbaf7 100644 --- a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml +++ b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold0/clippy.toml @@ -1 +1,2 @@ +struct-field-name-threshold = 0 enum-variant-name-threshold = 0 diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs index 6918d7528..b633dcbd1 100644 --- a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs +++ b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs @@ -1,3 +1,5 @@ +struct Data {} + enum Actions {} fn main() {} diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/clippy.toml index 0ad7a9799..028a62790 100644 --- a/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml +++ b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/clippy.toml @@ -1 +1,2 @@ enum-variant-name-threshold = 5 +struct-field-name-threshold = 5 diff --git a/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs new file mode 100644 index 000000000..d43731169 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs @@ -0,0 +1,32 @@ +#![warn(clippy::struct_field_names)] + +struct Data { + a_data: u8, + b_data: u8, + c_data: u8, + d_data: u8, +} +struct Data2 { + //~^ ERROR: all fields have the same postfix + a_data: u8, + b_data: u8, + c_data: u8, + d_data: u8, + e_data: u8, +} +enum Foo { + AFoo, + BFoo, + CFoo, + DFoo, +} +enum Foo2 { + //~^ ERROR: all variants have the same postfix + AFoo, + BFoo, + CFoo, + DFoo, + EFoo, +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.stderr b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.stderr new file mode 100644 index 000000000..33802c44b --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.stderr @@ -0,0 +1,34 @@ +error: all fields have the same postfix: `data` + --> $DIR/item_name_repetitions.rs:9:1 + | +LL | / struct Data2 { +LL | | +LL | | a_data: u8, +LL | | b_data: u8, +... | +LL | | e_data: u8, +LL | | } + | |_^ + | + = help: remove the postfixes + = note: `-D clippy::struct-field-names` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]` + +error: all variants have the same postfix: `Foo` + --> $DIR/item_name_repetitions.rs:23:1 + | +LL | / enum Foo2 { +LL | | +LL | | AFoo, +LL | | BFoo, +... | +LL | | EFoo, +LL | | } + | |_^ + | + = help: remove the postfixes and use full paths to the variants instead of glob imports + = note: `-D clippy::enum-variant-names` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs index 830d71f61..cd53f5044 100644 --- a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs +++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs @@ -1,5 +1,6 @@ //! this is crate #![allow(missing_docs)] +#![allow(clippy::struct_field_names)] #![warn(clippy::missing_docs_in_private_items)] /// this is mod diff --git a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr index 1ecdabbc0..2cf20b460 100644 --- a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr +++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr @@ -1,5 +1,5 @@ error: missing documentation for a function - --> $DIR/pub_crate_missing_doc.rs:12:5 + --> $DIR/pub_crate_missing_doc.rs:13:5 | LL | pub(crate) fn crate_no_docs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,25 +8,25 @@ LL | pub(crate) fn crate_no_docs() {} = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` error: missing documentation for a function - --> $DIR/pub_crate_missing_doc.rs:15:5 + --> $DIR/pub_crate_missing_doc.rs:16:5 | LL | pub(super) fn super_no_docs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/pub_crate_missing_doc.rs:23:9 + --> $DIR/pub_crate_missing_doc.rs:24:9 | LL | pub(crate) fn sub_crate_no_docs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> $DIR/pub_crate_missing_doc.rs:33:9 + --> $DIR/pub_crate_missing_doc.rs:34:9 | LL | pub(crate) crate_field_no_docs: (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct - --> $DIR/pub_crate_missing_doc.rs:39:5 + --> $DIR/pub_crate_missing_doc.rs:40:5 | LL | / pub(crate) struct CrateStructNoDocs { LL | | /// some docs @@ -38,13 +38,13 @@ LL | | } | |_____^ error: missing documentation for a struct field - --> $DIR/pub_crate_missing_doc.rs:42:9 + --> $DIR/pub_crate_missing_doc.rs:43:9 | LL | pub(crate) crate_field_no_docs: (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a type alias - --> $DIR/pub_crate_missing_doc.rs:51:1 + --> $DIR/pub_crate_missing_doc.rs:52:1 | LL | type CrateTypedefNoDocs = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 4bed5c149..2f9eaa517 100644 --- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -53,6 +53,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect single-char-binding-names-threshold stack-size-threshold standard-macro-braces + struct-field-name-threshold suppress-restriction-lint-in-const third-party too-large-for-stack @@ -126,6 +127,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect single-char-binding-names-threshold stack-size-threshold standard-macro-braces + struct-field-name-threshold suppress-restriction-lint-in-const third-party too-large-for-stack diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr index a52e1fcb9..8b9d159b5 100644 --- a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr +++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr @@ -2,7 +2,7 @@ error: this function has too many arguments (11/10) --> $DIR/too_many_arguments.rs:4:1 | LL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::too-many-arguments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout index eb3e5189c..140300a16 100644 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ b/src/tools/clippy/tests/ui/author/blocks.stdout @@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind { // report your lint here } -if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind +if let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl, body_id, _, None) = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output && expr1 = &cx.tcx.hir().body(body_id).value - && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind + && let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output && expr2 = &cx.tcx.hir().body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.rs b/src/tools/clippy/tests/ui/author/macro_in_closure.rs new file mode 100644 index 000000000..444e6a121 --- /dev/null +++ b/src/tools/clippy/tests/ui/author/macro_in_closure.rs @@ -0,0 +1,5 @@ +fn main() { + #[clippy::author] + let print_text = |x| println!("{}", x); + print_text("hello"); +} diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout new file mode 100644 index 000000000..9ab71986f --- /dev/null +++ b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout @@ -0,0 +1,39 @@ +if let StmtKind::Local(local) = stmt.kind + && let Some(init) = local.init + && let ExprKind::Closure(CaptureBy::Ref, fn_decl, body_id, _, None) = init.kind + && let FnRetTy::DefaultReturn(_) = fn_decl.output + && expr = &cx.tcx.hir().body(body_id).value + && let ExprKind::Block(block, None) = expr.kind + && block.stmts.len() == 1 + && let StmtKind::Semi(e) = block.stmts[0].kind + && let ExprKind::Call(func, args) = e.kind + && let ExprKind::Path(ref qpath) = func.kind + && match_qpath(qpath, &["$crate", "io", "_print"]) + && args.len() == 1 + && let ExprKind::Call(func1, args1) = args[0].kind + && let ExprKind::Path(ref qpath1) = func1.kind + && args1.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind + && let ExprKind::Array(elements) = inner.kind + && elements.len() == 2 + && let ExprKind::Lit(ref lit) = elements[0].kind + && let LitKind::Str(s, _) = lit.node + && s.as_str() == "" + && let ExprKind::Lit(ref lit1) = elements[1].kind + && let LitKind::Str(s1, _) = lit1.node + && s1.as_str() == "\n" + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind + && let ExprKind::Array(elements1) = inner1.kind + && elements1.len() == 1 + && let ExprKind::Call(func2, args2) = elements1[0].kind + && let ExprKind::Path(ref qpath2) = func2.kind + && args2.len() == 1 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind + && let ExprKind::Path(ref qpath3) = inner2.kind + && match_qpath(qpath3, &["x"]) + && block.expr.is_none() + && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind + && name.as_str() == "print_text" +{ + // report your lint here +} diff --git a/src/tools/clippy/tests/ui/author/macro_in_loop.rs b/src/tools/clippy/tests/ui/author/macro_in_loop.rs new file mode 100644 index 000000000..8a520501f --- /dev/null +++ b/src/tools/clippy/tests/ui/author/macro_in_loop.rs @@ -0,0 +1,8 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + #[clippy::author] + for i in 0..1 { + println!("{}", i); + } +} diff --git a/src/tools/clippy/tests/ui/author/macro_in_loop.stdout b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout new file mode 100644 index 000000000..bd054b6ab --- /dev/null +++ b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout @@ -0,0 +1,48 @@ +if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) + && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind + && name.as_str() == "i" + && let ExprKind::Struct(qpath, fields, None) = arg.kind + && matches!(qpath, QPath::LangItem(LangItem::Range, _)) + && fields.len() == 2 + && fields[0].ident.as_str() == "start" + && let ExprKind::Lit(ref lit) = fields[0].expr.kind + && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node + && fields[1].ident.as_str() == "end" + && let ExprKind::Lit(ref lit1) = fields[1].expr.kind + && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node + && let ExprKind::Block(block, None) = body.kind + && block.stmts.len() == 1 + && let StmtKind::Semi(e) = block.stmts[0].kind + && let ExprKind::Block(block1, None) = e.kind + && block1.stmts.len() == 1 + && let StmtKind::Semi(e1) = block1.stmts[0].kind + && let ExprKind::Call(func, args) = e1.kind + && let ExprKind::Path(ref qpath1) = func.kind + && match_qpath(qpath1, &["$crate", "io", "_print"]) + && args.len() == 1 + && let ExprKind::Call(func1, args1) = args[0].kind + && let ExprKind::Path(ref qpath2) = func1.kind + && args1.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind + && let ExprKind::Array(elements) = inner.kind + && elements.len() == 2 + && let ExprKind::Lit(ref lit2) = elements[0].kind + && let LitKind::Str(s, _) = lit2.node + && s.as_str() == "" + && let ExprKind::Lit(ref lit3) = elements[1].kind + && let LitKind::Str(s1, _) = lit3.node + && s1.as_str() == "\n" + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind + && let ExprKind::Array(elements1) = inner1.kind + && elements1.len() == 1 + && let ExprKind::Call(func2, args2) = elements1[0].kind + && let ExprKind::Path(ref qpath3) = func2.kind + && args2.len() == 1 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind + && let ExprKind::Path(ref qpath4) = inner2.kind + && match_qpath(qpath4, &["i"]) + && block1.expr.is_none() + && block.expr.is_none() +{ + // report your lint here +} diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs index 37f0ec2b3..79a95d775 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs @@ -21,6 +21,18 @@ pub fn derive(_: TokenStream) -> TokenStream { output } +#[proc_macro_derive(ImplStructWithStdDisplay)] +pub fn derive_std(_: TokenStream) -> TokenStream { + quote! { + struct A {} + impl ::std::fmt::Display for A { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "A") + } + } + } +} + #[proc_macro_derive(FieldReassignWithDefault)] pub fn derive_foo(_input: TokenStream) -> TokenStream { quote! { @@ -141,3 +153,19 @@ pub fn shadow_derive(_: TokenStream) -> TokenStream { .into(), ]) } + +#[proc_macro_derive(StructIgnoredUnitPattern)] +pub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream { + quote! { + struct A; + impl A { + fn a(&self) -> Result<(), ()> { + unimplemented!() + } + + pub fn b(&self) { + let _ = self.a().unwrap(); + } + } + } +} diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs index 43df65438..3303eb145 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs @@ -379,7 +379,8 @@ impl MacroArm { p.span(), )?; self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out); - self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) + self.args + .push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) } else { self.add_multi_arg_def(dollar_span, g.span(), out); self.args.push(TT::Group(g)); @@ -436,7 +437,12 @@ impl Expander { && p.as_char() == ESCAPE_CHAR && let Some(arm) = self.arm.as_mut() { - arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?; + arm.add_arg( + p.span(), + mem::replace(&mut input.tt, tt), + &mut input.iter, + &mut self.expn, + )?; if input.next().is_none() { return Ok(()); } diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed index 44d7f6e6d..167263d31 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed @@ -80,9 +80,7 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/10452 let should_not_lint = [(); if true { 1 } else { 0 }]; - let should_not_lint = const { - if true { 1 } else { 0 } - }; + let should_not_lint = const { if true { 1 } else { 0 } }; some_fn(a); } @@ -110,7 +108,9 @@ fn if_let(a: Enum, b: Enum) { 0 }; - if let Enum::A = a && let Enum::B = b { + if let Enum::A = a + && let Enum::B = b + { 1 } else { 0 diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs index 7d989ae4b..f3f055eb7 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs @@ -112,9 +112,7 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/10452 let should_not_lint = [(); if true { 1 } else { 0 }]; - let should_not_lint = const { - if true { 1 } else { 0 } - }; + let should_not_lint = const { if true { 1 } else { 0 } }; some_fn(a); } @@ -142,7 +140,9 @@ fn if_let(a: Enum, b: Enum) { 0 }; - if let Enum::A = a && let Enum::B = b { + if let Enum::A = a + && let Enum::B = b + { 1 } else { 0 diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr index 837ed05d3..714da8a41 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr @@ -99,7 +99,7 @@ LL | | }; = note: `!b as i32` or `(!b).into()` can also be valid options error: boolean to int conversion using if - --> $DIR/bool_to_int_with_if.rs:124:5 + --> $DIR/bool_to_int_with_if.rs:122:5 | LL | if a { 1 } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` diff --git a/src/tools/clippy/tests/ui/builtin_type_shadow.stderr b/src/tools/clippy/tests/ui/builtin_type_shadow.stderr index cb8462182..e051c00eb 100644 --- a/src/tools/clippy/tests/ui/builtin_type_shadow.stderr +++ b/src/tools/clippy/tests/ui/builtin_type_shadow.stderr @@ -13,7 +13,7 @@ error[E0308]: mismatched types LL | fn foo<u32>(a: u32) -> u32 { | --- --- expected `u32` because of return type | | - | this type parameter + | expected this type parameter LL | 42 | ^^ expected type parameter `u32`, found integer | diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.fixed b/src/tools/clippy/tests/ui/comparison_to_empty.fixed index 90eb50715..e102b13a7 100644 --- a/src/tools/clippy/tests/ui/comparison_to_empty.fixed +++ b/src/tools/clippy/tests/ui/comparison_to_empty.fixed @@ -15,7 +15,9 @@ fn main() { let s = [0].as_slice(); if s.is_empty() {} if s.is_empty() {} - if s.is_empty() && s.is_empty() {} + if s.is_empty() + && s.is_empty() + {} // Allow comparisons to non-empty let s = String::new(); @@ -28,5 +30,7 @@ fn main() { if let [0] = &*v {} let s = [0].as_slice(); if let [0] = s {} - if let [0] = &*s && s == [0] {} + if let [0] = &*s + && s == [0] + {} } diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.rs b/src/tools/clippy/tests/ui/comparison_to_empty.rs index 0964c4a20..69a6c967d 100644 --- a/src/tools/clippy/tests/ui/comparison_to_empty.rs +++ b/src/tools/clippy/tests/ui/comparison_to_empty.rs @@ -15,7 +15,9 @@ fn main() { let s = [0].as_slice(); if let [] = s {} if let [] = &*s {} - if let [] = &*s && s == [] {} + if let [] = &*s + && s == [] + {} // Allow comparisons to non-empty let s = String::new(); @@ -28,5 +30,7 @@ fn main() { if let [0] = &*v {} let s = [0].as_slice(); if let [0] = s {} - if let [0] = &*s && s == [0] {} + if let [0] = &*s + && s == [0] + {} } diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.stderr b/src/tools/clippy/tests/ui/comparison_to_empty.stderr index b97ab4c3c..83d431fd5 100644 --- a/src/tools/clippy/tests/ui/comparison_to_empty.stderr +++ b/src/tools/clippy/tests/ui/comparison_to_empty.stderr @@ -46,14 +46,14 @@ LL | if let [] = &*s {} error: comparison to empty slice using `if let` --> $DIR/comparison_to_empty.rs:18:8 | -LL | if let [] = &*s && s == [] {} +LL | if let [] = &*s | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:18:24 + --> $DIR/comparison_to_empty.rs:19:12 | -LL | if let [] = &*s && s == [] {} - | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` +LL | && s == [] + | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr index fc5347c86..7fc62d4fc 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr @@ -1,8 +1,8 @@ warning: future cannot be sent between threads safely - --> $DIR/ice-10645.rs:5:35 + --> $DIR/ice-10645.rs:5:1 | LL | pub async fn bar<'a, T: 'a>(_: T) {} - | ^ future returned by `bar` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `bar` is not `Send` | note: captured value is not `Send` --> $DIR/ice-10645.rs:5:29 diff --git a/src/tools/clippy/tests/ui/crashes/ice-11230.rs b/src/tools/clippy/tests/ui/crashes/ice-11230.rs new file mode 100644 index 000000000..576188227 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-11230.rs @@ -0,0 +1,6 @@ +/// Test for https://github.com/rust-lang/rust-clippy/issues/11230 + +fn main() { + const A: &[for<'a> fn(&'a ())] = &[]; + for v in A.iter() {} +} diff --git a/src/tools/clippy/tests/ui/crashes/ice-11755.rs b/src/tools/clippy/tests/ui/crashes/ice-11755.rs new file mode 100644 index 000000000..367cb6998 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-11755.rs @@ -0,0 +1,5 @@ +#![warn(clippy::unused_enumerate_index)] + +fn main() { + for () in [()].iter() {} +} diff --git a/src/tools/clippy/tests/ui/crashes/ice-5238.rs b/src/tools/clippy/tests/ui/crashes/ice-5238.rs index 989eb6d44..b1fc3fb9d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5238.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-5238.rs @@ -1,6 +1,6 @@ // Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562 -#![feature(generators, generator_trait)] +#![feature(coroutines, coroutine_trait)] fn main() { let _ = || { diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index cb65360d1..f929bec95 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -31,7 +31,7 @@ LL | const VAL: T; | ------------ `VAL` from trait ... LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index 47b56960a..aee897197 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { } } } + +/// this checks if the lowerCamelCase issue is fixed +fn issue_11568() {} diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index 4d9a4eafa..b6346b881 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { } } } + +/// this checks if the lowerCamelCase issue is fixed +fn issue_11568() {} diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs index 0c8eac5cc..f7f41c915 100644 --- a/src/tools/clippy/tests/ui/doc_unsafe.rs +++ b/src/tools/clippy/tests/ui/doc_unsafe.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)] extern crate proc_macros; use proc_macros::external; diff --git a/src/tools/clippy/tests/ui/enum_glob_use.fixed b/src/tools/clippy/tests/ui/enum_glob_use.fixed index 9044e8026..3c0db9beb 100644 --- a/src/tools/clippy/tests/ui/enum_glob_use.fixed +++ b/src/tools/clippy/tests/ui/enum_glob_use.fixed @@ -19,6 +19,7 @@ mod in_fn_test { } mod blurg { + #[allow(unused_imports)] pub use std::cmp::Ordering::*; // ok, re-export } diff --git a/src/tools/clippy/tests/ui/enum_glob_use.rs b/src/tools/clippy/tests/ui/enum_glob_use.rs index 4f157a97c..2538477f7 100644 --- a/src/tools/clippy/tests/ui/enum_glob_use.rs +++ b/src/tools/clippy/tests/ui/enum_glob_use.rs @@ -19,6 +19,7 @@ mod in_fn_test { } mod blurg { + #[allow(unused_imports)] pub use std::cmp::Ordering::*; // ok, re-export } diff --git a/src/tools/clippy/tests/ui/enum_variants.rs b/src/tools/clippy/tests/ui/enum_variants.rs index 85df852f7..ddf2dfdae 100644 --- a/src/tools/clippy/tests/ui/enum_variants.rs +++ b/src/tools/clippy/tests/ui/enum_variants.rs @@ -204,4 +204,21 @@ mod allow_attributes_on_variants { } } +mod issue11494 { + // variant order should not affect lint + enum Data { + Valid, + Invalid, + DataDependent, + //~^ ERROR: variant name starts with the enum's name + } + + enum Datas { + DatasDependent, + //~^ ERROR: variant name starts with the enum's name + Valid, + Invalid, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/enum_variants.stderr b/src/tools/clippy/tests/ui/enum_variants.stderr index 9ea80b635..b1e88de0f 100644 --- a/src/tools/clippy/tests/ui/enum_variants.stderr +++ b/src/tools/clippy/tests/ui/enum_variants.stderr @@ -158,5 +158,17 @@ LL | | } | = help: remove the postfixes and use full paths to the variants instead of glob imports -error: aborting due to 14 previous errors +error: variant name starts with the enum's name + --> $DIR/enum_variants.rs:212:9 + | +LL | DataDependent, + | ^^^^^^^^^^^^^ + +error: variant name starts with the enum's name + --> $DIR/enum_variants.rs:217:9 + | +LL | DatasDependent, + | ^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed index c23f4d7c4..a4d6d49e5 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed @@ -33,6 +33,9 @@ fn main() { let _ = a.mul_add(a, b).sqrt(); + let u = 1usize; + let _ = b.mul_add(-(u as f64), a); + // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs index 431badc8d..262a20f0f 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs @@ -33,6 +33,9 @@ fn main() { let _ = (a * a + b).sqrt(); + let u = 1usize; + let _ = a - (b * u as f64); + // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr index 81b7126db..38dbefbe1 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr @@ -73,5 +73,11 @@ error: multiply and add expressions can be calculated more efficiently and accur LL | let _ = (a * a + b).sqrt(); | ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)` -error: aborting due to 12 previous errors +error: multiply and add expressions can be calculated more efficiently and accurately + --> $DIR/floating_point_mul_add.rs:37:13 + | +LL | let _ = a - (b * u as f64); + | ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)` + +error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/functions.stderr b/src/tools/clippy/tests/ui/functions.stderr index 371ea1612..4b06cd038 100644 --- a/src/tools/clippy/tests/ui/functions.stderr +++ b/src/tools/clippy/tests/ui/functions.stderr @@ -2,7 +2,7 @@ error: this function has too many arguments (8/7) --> $DIR/functions.rs:8:1 | LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::too-many-arguments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` @@ -17,7 +17,7 @@ LL | | two: u32, ... | LL | | eight: () LL | | ) { - | |__^ + | |_^ error: this function has too many arguments (8/7) --> $DIR/functions.rs:48:5 @@ -29,7 +29,7 @@ error: this function has too many arguments (8/7) --> $DIR/functions.rs:58:5 | LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this public function might dereference a raw pointer but is not marked `unsafe` --> $DIR/functions.rs:68:34 diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index f43e3c8ff..7ef4947f1 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:7:62 + --> $DIR/future_not_send.rs:7:1 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { - | ^^^^ future returned by `private_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:9:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:12:42 + --> $DIR/future_not_send.rs:12:1 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^ future returned by `public_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:14:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:21:63 + --> $DIR/future_not_send.rs:21:1 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { - | ^^^^ future returned by `private_future2` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:21:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:26:43 + --> $DIR/future_not_send.rs:26:1 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^ future returned by `public_future2` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:26:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:38:39 + --> $DIR/future_not_send.rs:38:5 | LL | async fn private_future(&self) -> usize { - | ^^^^^ future returned by `private_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:40:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:44:39 + --> $DIR/future_not_send.rs:44:5 | LL | pub async fn public_future(&self) { - | ^ future returned by `public_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/future_not_send.rs:44:32 @@ -100,10 +100,13 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:55:37 + --> $DIR/future_not_send.rs:55:1 | -LL | async fn generic_future<T>(t: T) -> T - | ^ future returned by `generic_future` is not `Send` +LL | / async fn generic_future<T>(t: T) -> T +LL | | +LL | | where +LL | | T: Send, + | |____________^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:61:20 @@ -115,10 +118,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:73:34 + --> $DIR/future_not_send.rs:73:1 | LL | async fn unclear_future<T>(t: T) {} - | ^ future returned by `unclear_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `unclear_future` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:73:28 diff --git a/src/tools/clippy/tests/ui/get_first.fixed b/src/tools/clippy/tests/ui/get_first.fixed index b1a597fc4..710ebab1e 100644 --- a/src/tools/clippy/tests/ui/get_first.fixed +++ b/src/tools/clippy/tests/ui/get_first.fixed @@ -14,27 +14,37 @@ impl Bar { fn main() { let x = vec![2, 3, 5]; - let _ = x.first(); // Use x.first() + let _ = x.first(); + //~^ ERROR: accessing first element with `x.get(0)` let _ = x.get(1); let _ = x[0]; let y = [2, 3, 5]; - let _ = y.first(); // Use y.first() + let _ = y.first(); + //~^ ERROR: accessing first element with `y.get(0)` let _ = y.get(1); let _ = y[0]; let z = &[2, 3, 5]; - let _ = z.first(); // Use z.first() + let _ = z.first(); + //~^ ERROR: accessing first element with `z.get(0)` let _ = z.get(1); let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); + let _ = vecdeque.front(); + //~^ ERROR: accessing first element with `vecdeque.get(0)` + let _ = vecdeque.get(1); + let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); - let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. let bar = Bar { arr: [0, 1, 2] }; let _ = bar.get(0); // Do not lint, because Bar is struct. + + let non_primitives = [vec![1, 2], vec![3, 4]]; + let _ = non_primitives.first(); + //~^ ERROR: accessing first element with `non_primitives.get(0)` } diff --git a/src/tools/clippy/tests/ui/get_first.rs b/src/tools/clippy/tests/ui/get_first.rs index e27ee4be8..ad2ba6ce2 100644 --- a/src/tools/clippy/tests/ui/get_first.rs +++ b/src/tools/clippy/tests/ui/get_first.rs @@ -14,27 +14,37 @@ impl Bar { fn main() { let x = vec![2, 3, 5]; - let _ = x.get(0); // Use x.first() + let _ = x.get(0); + //~^ ERROR: accessing first element with `x.get(0)` let _ = x.get(1); let _ = x[0]; let y = [2, 3, 5]; - let _ = y.get(0); // Use y.first() + let _ = y.get(0); + //~^ ERROR: accessing first element with `y.get(0)` let _ = y.get(1); let _ = y[0]; let z = &[2, 3, 5]; - let _ = z.get(0); // Use z.first() + let _ = z.get(0); + //~^ ERROR: accessing first element with `z.get(0)` let _ = z.get(1); let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); + let _ = vecdeque.get(0); + //~^ ERROR: accessing first element with `vecdeque.get(0)` + let _ = vecdeque.get(1); + let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); - let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. let bar = Bar { arr: [0, 1, 2] }; let _ = bar.get(0); // Do not lint, because Bar is struct. + + let non_primitives = [vec![1, 2], vec![3, 4]]; + let _ = non_primitives.get(0); + //~^ ERROR: accessing first element with `non_primitives.get(0)` } diff --git a/src/tools/clippy/tests/ui/get_first.stderr b/src/tools/clippy/tests/ui/get_first.stderr index 56b4c29a3..7474a2ada 100644 --- a/src/tools/clippy/tests/ui/get_first.stderr +++ b/src/tools/clippy/tests/ui/get_first.stderr @@ -1,23 +1,35 @@ error: accessing first element with `x.get(0)` --> $DIR/get_first.rs:17:13 | -LL | let _ = x.get(0); // Use x.first() +LL | let _ = x.get(0); | ^^^^^^^^ help: try: `x.first()` | = note: `-D clippy::get-first` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::get_first)]` error: accessing first element with `y.get(0)` - --> $DIR/get_first.rs:22:13 + --> $DIR/get_first.rs:23:13 | -LL | let _ = y.get(0); // Use y.first() +LL | let _ = y.get(0); | ^^^^^^^^ help: try: `y.first()` error: accessing first element with `z.get(0)` - --> $DIR/get_first.rs:27:13 + --> $DIR/get_first.rs:29:13 | -LL | let _ = z.get(0); // Use z.first() +LL | let _ = z.get(0); | ^^^^^^^^ help: try: `z.first()` -error: aborting due to 3 previous errors +error: accessing first element with `vecdeque.get(0)` + --> $DIR/get_first.rs:35:13 + | +LL | let _ = vecdeque.get(0); + | ^^^^^^^^^^^^^^^ help: try: `vecdeque.front()` + +error: accessing first element with `non_primitives.get(0)` + --> $DIR/get_first.rs:48:13 + | +LL | let _ = non_primitives.get(0); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()` + +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/if_not_else_bittest.rs b/src/tools/clippy/tests/ui/if_not_else_bittest.rs new file mode 100644 index 000000000..586ce6ce1 --- /dev/null +++ b/src/tools/clippy/tests/ui/if_not_else_bittest.rs @@ -0,0 +1,11 @@ +#![deny(clippy::if_not_else)] + +fn show_permissions(flags: u32) { + if flags & 0x0F00 != 0 { + println!("Has the 0x0F00 permission."); + } else { + println!("The 0x0F00 permission is missing."); + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed index 6c6f21fee..707a0e76e 100644 --- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed +++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed @@ -1,3 +1,4 @@ +//@aux-build:proc_macro_derive.rs #![warn(clippy::ignored_unit_patterns)] #![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)] @@ -14,8 +15,22 @@ fn main() { //~^ ERROR: matching over `()` is more explicit let _ = foo().map_err(|()| todo!()); //~^ ERROR: matching over `()` is more explicit + + println!( + "{:?}", + match foo() { + Ok(()) => {}, + //~^ ERROR: matching over `()` is more explicit + Err(()) => {}, + //~^ ERROR: matching over `()` is more explicit + } + ); } +// ignored_unit_patterns in derive macro should be ok +#[derive(proc_macro_derive::StructIgnoredUnitPattern)] +pub struct B; + #[allow(unused)] pub fn moo(_: ()) { let () = foo().unwrap(); @@ -23,3 +38,19 @@ pub fn moo(_: ()) { let _: () = foo().unwrap(); let _: () = (); } + +fn test_unit_ref_1() { + let x: (usize, &&&&&()) = (1, &&&&&&()); + match x { + (1, ()) => unimplemented!(), + //~^ ERROR: matching over `()` is more explicit + _ => unimplemented!(), + }; +} + +fn test_unit_ref_2(v: &[(usize, ())]) { + for (x, ()) in v { + //~^ ERROR: matching over `()` is more explicit + let _ = x; + } +} diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs index 5e8c2e03b..544f2b8f6 100644 --- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs +++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs @@ -1,3 +1,4 @@ +//@aux-build:proc_macro_derive.rs #![warn(clippy::ignored_unit_patterns)] #![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)] @@ -14,8 +15,22 @@ fn main() { //~^ ERROR: matching over `()` is more explicit let _ = foo().map_err(|_| todo!()); //~^ ERROR: matching over `()` is more explicit + + println!( + "{:?}", + match foo() { + Ok(_) => {}, + //~^ ERROR: matching over `()` is more explicit + Err(_) => {}, + //~^ ERROR: matching over `()` is more explicit + } + ); } +// ignored_unit_patterns in derive macro should be ok +#[derive(proc_macro_derive::StructIgnoredUnitPattern)] +pub struct B; + #[allow(unused)] pub fn moo(_: ()) { let _ = foo().unwrap(); @@ -23,3 +38,19 @@ pub fn moo(_: ()) { let _: () = foo().unwrap(); let _: () = (); } + +fn test_unit_ref_1() { + let x: (usize, &&&&&()) = (1, &&&&&&()); + match x { + (1, _) => unimplemented!(), + //~^ ERROR: matching over `()` is more explicit + _ => unimplemented!(), + }; +} + +fn test_unit_ref_2(v: &[(usize, ())]) { + for (x, _) in v { + //~^ ERROR: matching over `()` is more explicit + let _ = x; + } +} diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr index df5e1d89e..05c8f281e 100644 --- a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr +++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr @@ -1,5 +1,5 @@ error: matching over `()` is more explicit - --> $DIR/ignored_unit_patterns.rs:10:12 + --> $DIR/ignored_unit_patterns.rs:11:12 | LL | Ok(_) => {}, | ^ help: use `()` instead of `_`: `()` @@ -8,28 +8,52 @@ LL | Ok(_) => {}, = help: to override `-D warnings` add `#[allow(clippy::ignored_unit_patterns)]` error: matching over `()` is more explicit - --> $DIR/ignored_unit_patterns.rs:11:13 + --> $DIR/ignored_unit_patterns.rs:12:13 | LL | Err(_) => {}, | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> $DIR/ignored_unit_patterns.rs:13:15 + --> $DIR/ignored_unit_patterns.rs:14:15 | LL | if let Ok(_) = foo() {} | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> $DIR/ignored_unit_patterns.rs:15:28 + --> $DIR/ignored_unit_patterns.rs:16:28 | LL | let _ = foo().map_err(|_| todo!()); | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> $DIR/ignored_unit_patterns.rs:21:9 + --> $DIR/ignored_unit_patterns.rs:22:16 + | +LL | Ok(_) => {}, + | ^ help: use `()` instead of `_`: `()` + +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:24:17 + | +LL | Err(_) => {}, + | ^ help: use `()` instead of `_`: `()` + +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:36:9 | LL | let _ = foo().unwrap(); | ^ help: use `()` instead of `_`: `()` -error: aborting due to 5 previous errors +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:45:13 + | +LL | (1, _) => unimplemented!(), + | ^ help: use `()` instead of `_`: `()` + +error: matching over `()` is more explicit + --> $DIR/ignored_unit_patterns.rs:52:13 + | +LL | for (x, _) in v { + | ^ help: use `()` instead of `_`: `()` + +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.rs b/src/tools/clippy/tests/ui/impl_trait_in_params.rs index b652e4a4a..a6251a370 100644 --- a/src/tools/clippy/tests/ui/impl_trait_in_params.rs +++ b/src/tools/clippy/tests/ui/impl_trait_in_params.rs @@ -1,20 +1,47 @@ #![allow(unused)] #![warn(clippy::impl_trait_in_params)] + //@no-rustfix pub trait Trait {} pub trait AnotherTrait<T> {} // Should warn pub fn a(_: impl Trait) {} -//~^ ERROR: '`impl Trait` used as a function parameter' -//~| NOTE: `-D clippy::impl-trait-in-params` implied by `-D warnings` +//~^ ERROR: `impl Trait` used as a function parameter pub fn c<C: Trait>(_: C, _: impl Trait) {} -//~^ ERROR: '`impl Trait` used as a function parameter' -fn d(_: impl AnotherTrait<u32>) {} +//~^ ERROR: `impl Trait` used as a function parameter // Shouldn't warn pub fn b<B: Trait>(_: B) {} fn e<T: AnotherTrait<u32>>(_: T) {} +fn d(_: impl AnotherTrait<u32>) {} + +//------ IMPLS + +pub trait Public { + // See test in ui-toml for a case where avoid-breaking-exported-api is set to false + fn t(_: impl Trait); + fn tt<T: Trait>(_: T) {} +} + +trait Private { + // This shouldn't lint + fn t(_: impl Trait); + fn tt<T: Trait>(_: T) {} +} + +struct S; +impl S { + pub fn h(_: impl Trait) {} //~ ERROR: `impl Trait` used as a function parameter + fn i(_: impl Trait) {} + pub fn j<J: Trait>(_: J) {} + pub fn k<K: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {} //~ ERROR: `impl Trait` used as a function parameter +} + +// Trying with traits +impl Public for S { + fn t(_: impl Trait) {} +} fn main() {} diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr index 36b4f27e9..0ae7a3672 100644 --- a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr +++ b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr @@ -1,5 +1,5 @@ -error: '`impl Trait` used as a function parameter' - --> $DIR/impl_trait_in_params.rs:8:13 +error: `impl Trait` used as a function parameter + --> $DIR/impl_trait_in_params.rs:9:13 | LL | pub fn a(_: impl Trait) {} | ^^^^^^^^^^ @@ -11,7 +11,7 @@ help: add a type parameter LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {} | +++++++++++++++++++++++++++++++ -error: '`impl Trait` used as a function parameter' +error: `impl Trait` used as a function parameter --> $DIR/impl_trait_in_params.rs:11:29 | LL | pub fn c<C: Trait>(_: C, _: impl Trait) {} @@ -22,5 +22,27 @@ help: add a type parameter LL | pub fn c<C: Trait, { /* Generic name */ }: Trait>(_: C, _: impl Trait) {} | +++++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: `impl Trait` used as a function parameter + --> $DIR/impl_trait_in_params.rs:36:17 + | +LL | pub fn h(_: impl Trait) {} + | ^^^^^^^^^^ + | +help: add a type parameter + | +LL | pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {} + | +++++++++++++++++++++++++++++++ + +error: `impl Trait` used as a function parameter + --> $DIR/impl_trait_in_params.rs:39:45 + | +LL | pub fn k<K: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: add a type parameter + | +LL | pub fn k<K: AnotherTrait<u32>, { /* Generic name */ }: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {} + | +++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed index a50fa0ccf..fa117aadd 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed @@ -1,6 +1,5 @@ #![warn(clippy::implied_bounds_in_impls)] #![allow(dead_code)] -#![feature(return_position_impl_trait_in_trait)] use std::ops::{Deref, DerefMut}; diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs index e74ed4425..c96aac151 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs @@ -1,6 +1,5 @@ #![warn(clippy::implied_bounds_in_impls)] #![allow(dead_code)] -#![feature(return_position_impl_trait_in_trait)] use std::ops::{Deref, DerefMut}; diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr index 72dc2a183..fb44f2aba 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr @@ -1,5 +1,5 @@ error: this bound is already specified as the supertrait of `DerefMut<Target = T>` - --> $DIR/implied_bounds_in_impls.rs:13:36 + --> $DIR/implied_bounds_in_impls.rs:12:36 | LL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> { | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> { | error: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>` - --> $DIR/implied_bounds_in_impls.rs:30:37 + --> $DIR/implied_bounds_in_impls.rs:29:37 | LL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U> | ^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U> | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> $DIR/implied_bounds_in_impls.rs:36:40 + --> $DIR/implied_bounds_in_impls.rs:35:40 | LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<( | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> $DIR/implied_bounds_in_impls.rs:36:60 + --> $DIR/implied_bounds_in_impls.rs:35:60 | LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait< | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> $DIR/implied_bounds_in_impls.rs:38:44 + --> $DIR/implied_bounds_in_impls.rs:37:44 | LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtra | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> $DIR/implied_bounds_in_impls.rs:38:62 + --> $DIR/implied_bounds_in_impls.rs:37:62 | LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrai | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>` - --> $DIR/implied_bounds_in_impls.rs:48:28 + --> $DIR/implied_bounds_in_impls.rs:47:28 | LL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {} | ^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:52:20 + --> $DIR/implied_bounds_in_impls.rs:51:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8>; | ^^^^^ @@ -97,7 +97,7 @@ LL + fn f() -> impl DerefMut<Target = u8>; | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:57:20 + --> $DIR/implied_bounds_in_impls.rs:56:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8> { | ^^^^^ @@ -109,7 +109,7 @@ LL + fn f() -> impl DerefMut<Target = u8> { | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:63:20 + --> $DIR/implied_bounds_in_impls.rs:62:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8> { | ^^^^^ @@ -121,7 +121,7 @@ LL + fn f() -> impl DerefMut<Target = u8> { | error: this bound is already specified as the supertrait of `PartialOrd` - --> $DIR/implied_bounds_in_impls.rs:74:41 + --> $DIR/implied_bounds_in_impls.rs:73:41 | LL | fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {} | ^^^^^^^^^ @@ -133,7 +133,7 @@ LL + fn default_generic_param1() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `PartialOrd` - --> $DIR/implied_bounds_in_impls.rs:75:54 + --> $DIR/implied_bounds_in_impls.rs:74:54 | LL | fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {} | ^^^^^^^^^ @@ -145,7 +145,7 @@ LL + fn default_generic_param2() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `DoubleEndedIterator` - --> $DIR/implied_bounds_in_impls.rs:88:26 + --> $DIR/implied_bounds_in_impls.rs:87:26 | LL | fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + fn my_iter() -> impl DoubleEndedIterator<Item = u32> { | error: this bound is already specified as the supertrait of `Copy` - --> $DIR/implied_bounds_in_impls.rs:93:27 + --> $DIR/implied_bounds_in_impls.rs:92:27 | LL | fn f() -> impl Copy + Clone { | ^^^^^ @@ -169,7 +169,7 @@ LL + fn f() -> impl Copy { | error: this bound is already specified as the supertrait of `Trait2<i32>` - --> $DIR/implied_bounds_in_impls.rs:107:21 + --> $DIR/implied_bounds_in_impls.rs:106:21 | LL | fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {} | ^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + fn f2() -> impl Trait2<i32, U = i64> {} | error: this bound is already specified as the supertrait of `Trait4<i8, X = i32>` - --> $DIR/implied_bounds_in_impls.rs:122:21 + --> $DIR/implied_bounds_in_impls.rs:121:21 | LL | fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/into_iter_without_iter.rs b/src/tools/clippy/tests/ui/into_iter_without_iter.rs new file mode 100644 index 000000000..448d0114d --- /dev/null +++ b/src/tools/clippy/tests/ui/into_iter_without_iter.rs @@ -0,0 +1,148 @@ +//@no-rustfix +#![warn(clippy::into_iter_without_iter)] + +use std::iter::IntoIterator; + +pub struct S1; +impl<'a> IntoIterator for &'a S1 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method + type IntoIter = std::slice::Iter<'a, u8>; + type Item = &'a u8; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +impl<'a> IntoIterator for &'a mut S1 { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, u8>; + type Item = &'a mut u8; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +pub struct S2<T>(T); +impl<'a, T> IntoIterator for &'a S2<T> { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +impl<'a, T> IntoIterator for &'a mut S2<T> { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +// Both iter and iter_mut methods exist, don't lint +pub struct S3<'a, T>(&'a T); +impl<'a, T> S3<'a, T> { + fn iter(&self) -> std::slice::Iter<'a, T> { + todo!() + } + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { + todo!() + } +} +impl<'a, T> IntoIterator for &S3<'a, T> { + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +impl<'a, T> IntoIterator for &mut S3<'a, T> { + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +// Only `iter` exists, no `iter_mut` +pub struct S4<'a, T>(&'a T); + +impl<'a, T> S4<'a, T> { + fn iter(&self) -> std::slice::Iter<'a, T> { + todo!() + } +} + +impl<'a, T> IntoIterator for &S4<'a, T> { + type IntoIter = std::slice::Iter<'a, T>; + type Item = &'a T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +impl<'a, T> IntoIterator for &mut S4<'a, T> { + //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method + type IntoIter = std::slice::IterMut<'a, T>; + type Item = &'a mut T; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +// `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize" +// aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead +// to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias). +pub struct S5; + +impl S5 { + fn iter(&self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub type Alias = S5; + +impl IntoIterator for &Alias { + type IntoIter = std::slice::Iter<'static, u8>; + type Item = &'static u8; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +fn main() {} + +pub mod issue11635 { + // A little more involved than the original repro in the issue, but this tests that it correctly + // works for more than one deref step + + use std::ops::Deref; + + pub struct Thing(Vec<u8>); + pub struct Thing2(Thing); + + impl Deref for Thing { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl Deref for Thing2 { + type Target = Thing; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl<'a> IntoIterator for &'a Thing2 { + type Item = &'a u8; + type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } + } +} diff --git a/src/tools/clippy/tests/ui/into_iter_without_iter.stderr b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr new file mode 100644 index 000000000..70f3f82a9 --- /dev/null +++ b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr @@ -0,0 +1,114 @@ +error: `IntoIterator` implemented for a reference type without an `iter` method + --> $DIR/into_iter_without_iter.rs:7:1 + | +LL | / impl<'a> IntoIterator for &'a S1 { +LL | | +LL | | type IntoIter = std::slice::Iter<'a, u8>; +LL | | type Item = &'a u8; +... | +LL | | } +LL | | } + | |_^ + | + = note: `-D clippy::into-iter-without-iter` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]` +help: consider implementing `iter` + | +LL + +LL + impl S1 { +LL + fn iter(&self) -> std::slice::Iter<'a, u8> { +LL + <&Self as IntoIterator>::into_iter(self) +LL + } +LL + } + | + +error: `IntoIterator` implemented for a reference type without an `iter_mut` method + --> $DIR/into_iter_without_iter.rs:15:1 + | +LL | / impl<'a> IntoIterator for &'a mut S1 { +LL | | +LL | | type IntoIter = std::slice::IterMut<'a, u8>; +LL | | type Item = &'a mut u8; +... | +LL | | } +LL | | } + | |_^ + | +help: consider implementing `iter_mut` + | +LL + +LL + impl S1 { +LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> { +LL + <&mut Self as IntoIterator>::into_iter(self) +LL + } +LL + } + | + +error: `IntoIterator` implemented for a reference type without an `iter` method + --> $DIR/into_iter_without_iter.rs:25:1 + | +LL | / impl<'a, T> IntoIterator for &'a S2<T> { +LL | | +LL | | type IntoIter = std::slice::Iter<'a, T>; +LL | | type Item = &'a T; +... | +LL | | } +LL | | } + | |_^ + | +help: consider implementing `iter` + | +LL + +LL + impl S2<T> { +LL + fn iter(&self) -> std::slice::Iter<'a, T> { +LL + <&Self as IntoIterator>::into_iter(self) +LL + } +LL + } + | + +error: `IntoIterator` implemented for a reference type without an `iter_mut` method + --> $DIR/into_iter_without_iter.rs:33:1 + | +LL | / impl<'a, T> IntoIterator for &'a mut S2<T> { +LL | | +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; +... | +LL | | } +LL | | } + | |_^ + | +help: consider implementing `iter_mut` + | +LL + +LL + impl S2<T> { +LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { +LL + <&mut Self as IntoIterator>::into_iter(self) +LL + } +LL + } + | + +error: `IntoIterator` implemented for a reference type without an `iter_mut` method + --> $DIR/into_iter_without_iter.rs:84:1 + | +LL | / impl<'a, T> IntoIterator for &mut S4<'a, T> { +LL | | +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; +... | +LL | | } +LL | | } + | |_^ + | +help: consider implementing `iter_mut` + | +LL + +LL + impl S4<'a, T> { +LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { +LL + <&mut Self as IntoIterator>::into_iter(self) +LL + } +LL + } + | + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs b/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs new file mode 100644 index 000000000..d9c0aef88 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs @@ -0,0 +1,11 @@ +//@aux-build:../auxiliary/proc_macros.rs +extern crate proc_macros; + +proc_macros::with_span! { + span + #[cfg(test)] + mod tests {} +} + +#[test] +fn f() {} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs new file mode 100644 index 000000000..69d617901 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs @@ -0,0 +1,4 @@ +#[cfg(test)] +mod tests {} + +fn in_submodule() {} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr deleted file mode 100644 index 1b6257471..000000000 --- a/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: Option 'test' given more than once - diff --git a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs new file mode 100644 index 000000000..7132e7176 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs @@ -0,0 +1,8 @@ +#[path = "auxiliary/submodule.rs"] +mod submodule; + +#[cfg(test)] +mod tests { + #[test] + fn t() {} +} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr new file mode 100644 index 000000000..4e9987636 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr @@ -0,0 +1,14 @@ +error: items after a test module + --> $DIR/auxiliary/submodule.rs:2:1 + | +LL | mod tests {} + | ^^^^^^^^^ +LL | +LL | fn in_submodule() {} + | ^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::items-after-test-module` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs b/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs new file mode 100644 index 000000000..8ab9e8200 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs @@ -0,0 +1,11 @@ +#[cfg(test)] +mod tests { + #[test] + fn f() {} +} + +#[cfg(test)] +mod more_tests { + #[test] + fn g() {} +} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/root_module.fixed index 5136b2557..d444100a7 100644 --- a/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs +++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.fixed @@ -1,4 +1,3 @@ -//@compile-flags: --test #![allow(unused)] #![warn(clippy::items_after_test_module)] @@ -6,6 +5,13 @@ fn main() {} fn should_not_lint() {} +fn should_lint() {} + +const SHOULD_ALSO_LINT: usize = 1; +macro_rules! should_lint { + () => {}; +} + #[allow(dead_code)] #[allow(unused)] // Some attributes to check that span replacement is good enough #[allow(clippy::allow_attributes)] @@ -14,10 +20,3 @@ mod tests { #[test] fn hi() {} } - -fn should_lint() {} - -const SHOULD_ALSO_LINT: usize = 1; -macro_rules! should_not_lint { - () => {}; -} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs new file mode 100644 index 000000000..57da01639 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs @@ -0,0 +1,22 @@ +#![allow(unused)] +#![warn(clippy::items_after_test_module)] + +fn main() {} + +fn should_not_lint() {} + +#[allow(dead_code)] +#[allow(unused)] // Some attributes to check that span replacement is good enough +#[allow(clippy::allow_attributes)] +#[cfg(test)] +mod tests { + #[test] + fn hi() {} +} + +fn should_lint() {} + +const SHOULD_ALSO_LINT: usize = 1; +macro_rules! should_lint { + () => {}; +} diff --git a/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr new file mode 100644 index 000000000..67bc82ebf --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr @@ -0,0 +1,20 @@ +error: items after a test module + --> $DIR/root_module.rs:12:1 + | +LL | mod tests { + | ^^^^^^^^^ +... +LL | fn should_lint() {} + | ^^^^^^^^^^^^^^^^ +LL | +LL | const SHOULD_ALSO_LINT: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! should_lint { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::items-after-test-module` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]` + = help: move the items to before the test module was defined + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.rs b/src/tools/clippy/tests/ui/iter_without_into_iter.rs new file mode 100644 index 000000000..29f526b45 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_without_into_iter.rs @@ -0,0 +1,124 @@ +//@no-rustfix +#![warn(clippy::iter_without_into_iter)] + +pub struct S1; +impl S1 { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + [].iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + [].iter_mut() + } +} + +pub struct S2; +impl S2 { + pub fn iter(&self) -> impl Iterator<Item = &u8> { + // RPITIT is not stable, so we can't generally suggest it here yet + [].iter() + } +} + +pub struct S3<'a>(&'a mut [u8]); +impl<'a> S3<'a> { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + self.0.iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + self.0.iter_mut() + } +} + +// Incompatible signatures +pub struct S4; +impl S4 { + pub fn iter(self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S5; +impl S5 { + pub async fn iter(&self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S6; +impl S6 { + pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S7<T>(T); +impl<T> S7<T> { + pub fn iter<U>(&self) -> std::slice::Iter<'static, (T, U)> { + todo!() + } +} + +pub struct S8<T>(T); +impl<T> S8<T> { + pub fn iter(&self) -> std::slice::Iter<'static, T> { + todo!() + } +} + +// =========================== +pub struct S9<T>(T); +impl<T> S9<T> { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + todo!() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + todo!() + } +} + +pub struct S10<T>(T); +impl<T> S10<T> { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} + +impl<'a, T> IntoIterator for &'a S10<T> { + type Item = &'a String; + type IntoIter = std::slice::Iter<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +pub struct S11<T>(T); +impl<T> S11<T> { + pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} +impl<'a, T> IntoIterator for &'a mut S11<T> { + type Item = &'a mut String; + type IntoIter = std::slice::IterMut<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +// Private type not exported: don't lint +struct S12; +impl S12 { + fn iter(&self) -> std::slice::Iter<'_, u8> { + todo!() + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr new file mode 100644 index 000000000..af5afd47b --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr @@ -0,0 +1,150 @@ +error: `iter` method without an `IntoIterator` impl for `&S1` + --> $DIR/iter_without_into_iter.rs:6:5 + | +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | | +LL | | [].iter() +LL | | } + | |_____^ + | + = note: `-D clippy::iter-without-into-iter` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]` +help: consider implementing `IntoIterator` for `&S1` + | +LL + +LL + impl IntoIterator for &S1 { +LL + type IntoIter = std::slice::Iter<'_, u8>; +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter_mut` method without an `IntoIterator` impl for `&mut S1` + --> $DIR/iter_without_into_iter.rs:10:5 + | +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | | +LL | | [].iter_mut() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&mut S1` + | +LL + +LL + impl IntoIterator for &mut S1 { +LL + type IntoIter = std::slice::IterMut<'_, u8>; +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter` method without an `IntoIterator` impl for `&S3<'a>` + --> $DIR/iter_without_into_iter.rs:26:5 + | +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | | +LL | | self.0.iter() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&S3<'a>` + | +LL + +LL + impl IntoIterator for &S3<'a> { +LL + type IntoIter = std::slice::Iter<'_, u8>; +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>` + --> $DIR/iter_without_into_iter.rs:30:5 + | +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | | +LL | | self.0.iter_mut() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&mut S3<'a>` + | +LL + +LL + impl IntoIterator for &mut S3<'a> { +LL + type IntoIter = std::slice::IterMut<'_, u8>; +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter` method without an `IntoIterator` impl for `&S8<T>` + --> $DIR/iter_without_into_iter.rs:67:5 + | +LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { +LL | | todo!() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&S8<T>` + | +LL + +LL + impl IntoIterator for &S8<T> { +LL + type IntoIter = std::slice::Iter<'static, T>; +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter` method without an `IntoIterator` impl for `&S9<T>` + --> $DIR/iter_without_into_iter.rs:75:5 + | +LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { +LL | | +LL | | todo!() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&S9<T>` + | +LL + +LL + impl IntoIterator for &S9<T> { +LL + type IntoIter = std::slice::Iter<'_, T>; +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: `iter_mut` method without an `IntoIterator` impl for `&mut S9<T>` + --> $DIR/iter_without_into_iter.rs:79:5 + | +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { +LL | | +LL | | todo!() +LL | | } + | |_____^ + | +help: consider implementing `IntoIterator` for `&mut S9<T>` + | +LL + +LL + impl IntoIterator for &mut S9<T> { +LL + type IntoIter = std::slice::IterMut<'_, T>; +LL + type Item = &mut T; +LL + fn into_iter(self) -> Self::IntoIter { +LL + self.iter() +LL + } +LL + } + | + +error: aborting due to 7 previous errors + diff --git a/src/tools/clippy/tests/ui/large_futures.fixed b/src/tools/clippy/tests/ui/large_futures.fixed index 4c192d1c8..aa8c3021b 100644 --- a/src/tools/clippy/tests/ui/large_futures.fixed +++ b/src/tools/clippy/tests/ui/large_futures.fixed @@ -1,4 +1,4 @@ -#![feature(generators)] +#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/src/tools/clippy/tests/ui/large_futures.rs b/src/tools/clippy/tests/ui/large_futures.rs index 557d89a9c..fc6ea458d 100644 --- a/src/tools/clippy/tests/ui/large_futures.rs +++ b/src/tools/clippy/tests/ui/large_futures.rs @@ -1,4 +1,4 @@ -#![feature(generators)] +#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/src/tools/clippy/tests/ui/let_and_return.fixed b/src/tools/clippy/tests/ui/let_and_return.fixed index 88b8ae673..b5584fcde 100644 --- a/src/tools/clippy/tests/ui/let_and_return.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.fixed @@ -168,7 +168,26 @@ mod issue_5729 { impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> { fn foo_cloned(&self) -> Arc<dyn Foo> { - Arc::clone(&self.foo) as _ + (Arc::clone(&self.foo)) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_11335 { + pub enum E<T> { + A(T), + B(T), + } + + impl<T> E<T> { + pub fn inner(&self) -> &T { + + + (match self { + E::A(x) => x, + E::B(x) => x, + }) as _ //~^ ERROR: returning the result of a `let` binding from a block } } diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs index f366842c5..f13c7c4e2 100644 --- a/src/tools/clippy/tests/ui/let_and_return.rs +++ b/src/tools/clippy/tests/ui/let_and_return.rs @@ -174,6 +174,25 @@ mod issue_5729 { } } +mod issue_11335 { + pub enum E<T> { + A(T), + B(T), + } + + impl<T> E<T> { + pub fn inner(&self) -> &T { + let result = match self { + E::A(x) => x, + E::B(x) => x, + }; + + result + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + // https://github.com/rust-lang/rust-clippy/issues/11167 macro_rules! fn_in_macro { ($b:block) => { diff --git a/src/tools/clippy/tests/ui/let_and_return.stderr b/src/tools/clippy/tests/ui/let_and_return.stderr index c09c2b32a..fe60072d1 100644 --- a/src/tools/clippy/tests/ui/let_and_return.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.stderr @@ -53,8 +53,30 @@ LL | clone help: return the expression directly | LL ~ -LL ~ Arc::clone(&self.foo) as _ +LL ~ (Arc::clone(&self.foo)) as _ | -error: aborting due to 4 previous errors +error: returning the result of a `let` binding from a block + --> $DIR/let_and_return.rs:190:13 + | +LL | / let result = match self { +LL | | E::A(x) => x, +LL | | E::B(x) => x, +LL | | }; + | |______________- unnecessary `let` binding +LL | +LL | result + | ^^^^^^ + | +help: return the expression directly + | +LL ~ +LL | +LL ~ (match self { +LL + E::A(x) => x, +LL + E::B(x) => x, +LL + }) as _ + | + +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/manual_filter.rs b/src/tools/clippy/tests/ui/manual_filter.rs index 06968f8ba..ee44909f3 100644 --- a/src/tools/clippy/tests/ui/manual_filter.rs +++ b/src/tools/clippy/tests/ui/manual_filter.rs @@ -191,9 +191,7 @@ fn main() { None => None, }; let _ = match Some(15) { - Some(x) => unsafe { - if f(x) { Some(x) } else { None } - }, + Some(x) => unsafe { if f(x) { Some(x) } else { None } }, None => None, }; diff --git a/src/tools/clippy/tests/ui/manual_filter.stderr b/src/tools/clippy/tests/ui/manual_filter.stderr index 1490f2097..b23ad887e 100644 --- a/src/tools/clippy/tests/ui/manual_filter.stderr +++ b/src/tools/clippy/tests/ui/manual_filter.stderr @@ -169,15 +169,13 @@ error: manual implementation of `Option::filter` | LL | let _ = match Some(15) { | _____________^ -LL | | Some(x) => unsafe { -LL | | if f(x) { Some(x) } else { None } -LL | | }, +LL | | Some(x) => unsafe { if f(x) { Some(x) } else { None } }, LL | | None => None, LL | | }; | |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` - --> $DIR/manual_filter.rs:203:12 + --> $DIR/manual_filter.rs:201:12 | LL | } else if let Some(x) = Some(16) { | ____________^ diff --git a/src/tools/clippy/tests/ui/manual_filter_map.fixed b/src/tools/clippy/tests/ui/manual_filter_map.fixed index 4de45e39b..a44c46c14 100644 --- a/src/tools/clippy/tests/ui/manual_filter_map.fixed +++ b/src/tools/clippy/tests/ui/manual_filter_map.fixed @@ -2,6 +2,7 @@ #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure #![allow(clippy::useless_vec)] +#![allow(clippy::struct_field_names)] fn main() { // is_some(), unwrap() diff --git a/src/tools/clippy/tests/ui/manual_filter_map.rs b/src/tools/clippy/tests/ui/manual_filter_map.rs index 22f316f90..e72d0c430 100644 --- a/src/tools/clippy/tests/ui/manual_filter_map.rs +++ b/src/tools/clippy/tests/ui/manual_filter_map.rs @@ -2,6 +2,7 @@ #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure #![allow(clippy::useless_vec)] +#![allow(clippy::struct_field_names)] fn main() { // is_some(), unwrap() diff --git a/src/tools/clippy/tests/ui/manual_filter_map.stderr b/src/tools/clippy/tests/ui/manual_filter_map.stderr index 0bfc1f5c7..cf64bb259 100644 --- a/src/tools/clippy/tests/ui/manual_filter_map.stderr +++ b/src/tools/clippy/tests/ui/manual_filter_map.stderr @@ -1,11 +1,11 @@ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:8:19 + --> $DIR/manual_filter_map.rs:9:19 | LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:8:30 + --> $DIR/manual_filter_map.rs:9:30 | LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^ @@ -13,31 +13,31 @@ LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap = help: to override `-D warnings` add `#[allow(clippy::manual_filter_map)]` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:11:19 + --> $DIR/manual_filter_map.rs:12:19 | LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:11:31 + --> $DIR/manual_filter_map.rs:12:31 | LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:14:19 + --> $DIR/manual_filter_map.rs:15:19 | LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:14:31 + --> $DIR/manual_filter_map.rs:15:31 | LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:17:10 + --> $DIR/manual_filter_map.rs:18:10 | LL | .filter(|&x| to_ref(to_opt(x)).is_some()) | __________^ @@ -45,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:17:22 + --> $DIR/manual_filter_map.rs:18:22 | LL | .filter(|&x| to_ref(to_opt(x)).is_some()) | ^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:20:10 + --> $DIR/manual_filter_map.rs:21:10 | LL | .filter(|x| to_ref(to_opt(*x)).is_some()) | __________^ @@ -59,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:20:21 + --> $DIR/manual_filter_map.rs:21:21 | LL | .filter(|x| to_ref(to_opt(*x)).is_some()) | ^^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:24:10 + --> $DIR/manual_filter_map.rs:25:10 | LL | .filter(|&x| to_ref(to_res(x)).is_ok()) | __________^ @@ -73,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:24:22 + --> $DIR/manual_filter_map.rs:25:22 | LL | .filter(|&x| to_ref(to_res(x)).is_ok()) | ^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:27:10 + --> $DIR/manual_filter_map.rs:28:10 | LL | .filter(|x| to_ref(to_res(*x)).is_ok()) | __________^ @@ -87,13 +87,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:27:21 + --> $DIR/manual_filter_map.rs:28:21 | LL | .filter(|x| to_ref(to_res(*x)).is_ok()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:33:27 + --> $DIR/manual_filter_map.rs:34:27 | LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` @@ -102,79 +102,79 @@ LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap() = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:34:28 + --> $DIR/manual_filter_map.rs:35:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:35:31 + --> $DIR/manual_filter_map.rs:36:31 | LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:36:31 + --> $DIR/manual_filter_map.rs:37:31 | LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:36:41 + --> $DIR/manual_filter_map.rs:37:41 | LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:38:30 + --> $DIR/manual_filter_map.rs:39:30 | LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:39:31 + --> $DIR/manual_filter_map.rs:40:31 | LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:40:32 + --> $DIR/manual_filter_map.rs:41:32 | LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:41:31 + --> $DIR/manual_filter_map.rs:42:31 | LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:42:32 + --> $DIR/manual_filter_map.rs:43:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:43:35 + --> $DIR/manual_filter_map.rs:44:35 | LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:44:35 + --> $DIR/manual_filter_map.rs:45:35 | LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_filter_map.rs:44:45 + --> $DIR/manual_filter_map.rs:45:45 | LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:92:10 + --> $DIR/manual_filter_map.rs:93:10 | LL | .filter(|f| f.option_field.is_some()) | __________^ @@ -182,7 +182,7 @@ LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:97:10 + --> $DIR/manual_filter_map.rs:98:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ @@ -190,7 +190,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:102:10 + --> $DIR/manual_filter_map.rs:103:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ @@ -198,7 +198,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:107:10 + --> $DIR/manual_filter_map.rs:108:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -206,7 +206,7 @@ LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:112:10 + --> $DIR/manual_filter_map.rs:113:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -214,7 +214,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:117:10 + --> $DIR/manual_filter_map.rs:118:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -222,7 +222,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:122:10 + --> $DIR/manual_filter_map.rs:123:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -230,7 +230,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:127:10 + --> $DIR/manual_filter_map.rs:128:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -238,7 +238,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:132:10 + --> $DIR/manual_filter_map.rs:133:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -246,7 +246,7 @@ LL | | .map(|f| f.result_field.to_owned().unwrap()); | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:145:27 + --> $DIR/manual_filter_map.rs:146:27 | LL | let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x { | ___________________________^ @@ -256,7 +256,7 @@ LL | | }); | |______^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:155:10 + --> $DIR/manual_filter_map.rs:156:10 | LL | .filter(|x| matches!(x, Enum::A(_))) | __________^ diff --git a/src/tools/clippy/tests/ui/manual_find_map.fixed b/src/tools/clippy/tests/ui/manual_find_map.fixed index 0e92d25e6..2d9a356b9 100644 --- a/src/tools/clippy/tests/ui/manual_find_map.fixed +++ b/src/tools/clippy/tests/ui/manual_find_map.fixed @@ -2,6 +2,7 @@ #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure #![allow(clippy::useless_vec)] +#![allow(clippy::struct_field_names)] fn main() { // is_some(), unwrap() diff --git a/src/tools/clippy/tests/ui/manual_find_map.rs b/src/tools/clippy/tests/ui/manual_find_map.rs index b2568c823..7c5cc1366 100644 --- a/src/tools/clippy/tests/ui/manual_find_map.rs +++ b/src/tools/clippy/tests/ui/manual_find_map.rs @@ -2,6 +2,7 @@ #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure #![allow(clippy::useless_vec)] +#![allow(clippy::struct_field_names)] fn main() { // is_some(), unwrap() diff --git a/src/tools/clippy/tests/ui/manual_find_map.stderr b/src/tools/clippy/tests/ui/manual_find_map.stderr index 0dc9ae1df..052638232 100644 --- a/src/tools/clippy/tests/ui/manual_find_map.stderr +++ b/src/tools/clippy/tests/ui/manual_find_map.stderr @@ -1,11 +1,11 @@ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:8:19 + --> $DIR/manual_find_map.rs:9:19 | LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:8:28 + --> $DIR/manual_find_map.rs:9:28 | LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^ @@ -13,31 +13,31 @@ LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap() = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:11:19 + --> $DIR/manual_find_map.rs:12:19 | LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:11:29 + --> $DIR/manual_find_map.rs:12:29 | LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:14:19 + --> $DIR/manual_find_map.rs:15:19 | LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:14:29 + --> $DIR/manual_find_map.rs:15:29 | LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:17:10 + --> $DIR/manual_find_map.rs:18:10 | LL | .find(|&x| to_ref(to_opt(x)).is_some()) | __________^ @@ -45,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:17:20 + --> $DIR/manual_find_map.rs:18:20 | LL | .find(|&x| to_ref(to_opt(x)).is_some()) | ^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:20:10 + --> $DIR/manual_find_map.rs:21:10 | LL | .find(|x| to_ref(to_opt(*x)).is_some()) | __________^ @@ -59,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:20:19 + --> $DIR/manual_find_map.rs:21:19 | LL | .find(|x| to_ref(to_opt(*x)).is_some()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:24:10 + --> $DIR/manual_find_map.rs:25:10 | LL | .find(|&x| to_ref(to_res(x)).is_ok()) | __________^ @@ -73,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:24:20 + --> $DIR/manual_find_map.rs:25:20 | LL | .find(|&x| to_ref(to_res(x)).is_ok()) | ^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:27:10 + --> $DIR/manual_find_map.rs:28:10 | LL | .find(|x| to_ref(to_res(*x)).is_ok()) | __________^ @@ -87,109 +87,109 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:27:19 + --> $DIR/manual_find_map.rs:28:19 | LL | .find(|x| to_ref(to_res(*x)).is_ok()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:33:26 + --> $DIR/manual_find_map.rs:34:26 | LL | iter::<Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:34:27 + --> $DIR/manual_find_map.rs:35:27 | LL | iter::<&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:35:28 + --> $DIR/manual_find_map.rs:36:28 | LL | iter::<&&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:36:27 + --> $DIR/manual_find_map.rs:37:27 | LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:37:28 + --> $DIR/manual_find_map.rs:38:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:38:31 + --> $DIR/manual_find_map.rs:39:31 | LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:39:31 + --> $DIR/manual_find_map.rs:40:31 | LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:39:41 + --> $DIR/manual_find_map.rs:40:41 | LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:41:30 + --> $DIR/manual_find_map.rs:42:30 | LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:42:31 + --> $DIR/manual_find_map.rs:43:31 | LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:43:32 + --> $DIR/manual_find_map.rs:44:32 | LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:44:31 + --> $DIR/manual_find_map.rs:45:31 | LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:45:32 + --> $DIR/manual_find_map.rs:46:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:46:35 + --> $DIR/manual_find_map.rs:47:35 | LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:47:35 + --> $DIR/manual_find_map.rs:48:35 | LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> $DIR/manual_find_map.rs:47:45 + --> $DIR/manual_find_map.rs:48:45 | LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:95:10 + --> $DIR/manual_find_map.rs:96:10 | LL | .find(|f| f.option_field.is_some()) | __________^ @@ -197,7 +197,7 @@ LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:100:10 + --> $DIR/manual_find_map.rs:101:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ @@ -205,7 +205,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:105:10 + --> $DIR/manual_find_map.rs:106:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ @@ -213,7 +213,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:110:10 + --> $DIR/manual_find_map.rs:111:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -221,7 +221,7 @@ LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:115:10 + --> $DIR/manual_find_map.rs:116:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -229,7 +229,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:120:10 + --> $DIR/manual_find_map.rs:121:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -237,7 +237,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:125:10 + --> $DIR/manual_find_map.rs:126:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -245,7 +245,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:130:10 + --> $DIR/manual_find_map.rs:131:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -253,7 +253,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:135:10 + --> $DIR/manual_find_map.rs:136:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ diff --git a/src/tools/clippy/tests/ui/manual_hash_one.fixed b/src/tools/clippy/tests/ui/manual_hash_one.fixed new file mode 100644 index 000000000..edfd9c4a4 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_hash_one.fixed @@ -0,0 +1,89 @@ +#![warn(clippy::manual_hash_one)] +#![allow(clippy::needless_borrows_for_generic_args)] + +use std::hash::{BuildHasher, Hash, Hasher}; + +fn returned(b: impl BuildHasher) -> u64 { + + + b.hash_one(&true) +} + +fn unsized_receiver(b: impl BuildHasher, s: &str) { + + + let _ = b.hash_one(&s[4..10]); +} + +fn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> { + + + let _ = b.hash_one(&v); + v +} + +fn reused_hasher(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + let _ = hasher.finish(); +} + +fn reused_hasher_in_return(b: impl BuildHasher) -> u64 { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + hasher.finish() +} + +fn no_hash(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + let _ = hasher.finish(); +} + +fn hash_twice(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + true.hash(&mut hasher); + let _ = hasher.finish(); +} + +fn other_hasher(b: impl BuildHasher) { + let mut other_hasher = b.build_hasher(); + + let mut hasher = b.build_hasher(); + true.hash(&mut other_hasher); + let _ = hasher.finish(); +} + +fn finish_then_hash(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + let _ = hasher.finish(); + true.hash(&mut hasher); +} + +fn in_macro(b: impl BuildHasher) { + macro_rules! m { + ($b:expr) => {{ + let mut hasher = $b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + }}; + } + + m!(b); +} + +#[clippy::msrv = "1.70"] +fn msrv_1_70(b: impl BuildHasher, v: impl Hash) { + let mut hasher = b.build_hasher(); + v.hash(&mut hasher); + let _ = hasher.finish(); +} + +#[clippy::msrv = "1.71"] +fn msrv_1_71(b: impl BuildHasher, v: impl Hash) { + + + let _ = b.hash_one(&v); +} diff --git a/src/tools/clippy/tests/ui/manual_hash_one.rs b/src/tools/clippy/tests/ui/manual_hash_one.rs new file mode 100644 index 000000000..ee6152285 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_hash_one.rs @@ -0,0 +1,89 @@ +#![warn(clippy::manual_hash_one)] +#![allow(clippy::needless_borrows_for_generic_args)] + +use std::hash::{BuildHasher, Hash, Hasher}; + +fn returned(b: impl BuildHasher) -> u64 { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + hasher.finish() +} + +fn unsized_receiver(b: impl BuildHasher, s: &str) { + let mut hasher = b.build_hasher(); + s[4..10].hash(&mut hasher); + let _ = hasher.finish(); +} + +fn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> { + let mut hasher = b.build_hasher(); + v.hash(&mut hasher); + let _ = hasher.finish(); + v +} + +fn reused_hasher(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + let _ = hasher.finish(); +} + +fn reused_hasher_in_return(b: impl BuildHasher) -> u64 { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + hasher.finish() +} + +fn no_hash(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + let _ = hasher.finish(); +} + +fn hash_twice(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + true.hash(&mut hasher); + true.hash(&mut hasher); + let _ = hasher.finish(); +} + +fn other_hasher(b: impl BuildHasher) { + let mut other_hasher = b.build_hasher(); + + let mut hasher = b.build_hasher(); + true.hash(&mut other_hasher); + let _ = hasher.finish(); +} + +fn finish_then_hash(b: impl BuildHasher) { + let mut hasher = b.build_hasher(); + let _ = hasher.finish(); + true.hash(&mut hasher); +} + +fn in_macro(b: impl BuildHasher) { + macro_rules! m { + ($b:expr) => {{ + let mut hasher = $b.build_hasher(); + true.hash(&mut hasher); + let _ = hasher.finish(); + }}; + } + + m!(b); +} + +#[clippy::msrv = "1.70"] +fn msrv_1_70(b: impl BuildHasher, v: impl Hash) { + let mut hasher = b.build_hasher(); + v.hash(&mut hasher); + let _ = hasher.finish(); +} + +#[clippy::msrv = "1.71"] +fn msrv_1_71(b: impl BuildHasher, v: impl Hash) { + let mut hasher = b.build_hasher(); + v.hash(&mut hasher); + let _ = hasher.finish(); +} diff --git a/src/tools/clippy/tests/ui/manual_hash_one.stderr b/src/tools/clippy/tests/ui/manual_hash_one.stderr new file mode 100644 index 000000000..3ce6f41e1 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_hash_one.stderr @@ -0,0 +1,56 @@ +error: manual implementation of `BuildHasher::hash_one` + --> $DIR/manual_hash_one.rs:9:5 + | +LL | hasher.finish() + | ^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-hash-one` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_hash_one)]` +help: try + | +LL ~ +LL ~ +LL ~ b.hash_one(&true) + | + +error: manual implementation of `BuildHasher::hash_one` + --> $DIR/manual_hash_one.rs:15:13 + | +LL | let _ = hasher.finish(); + | ^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ +LL ~ +LL ~ let _ = b.hash_one(&s[4..10]); + | + +error: manual implementation of `BuildHasher::hash_one` + --> $DIR/manual_hash_one.rs:21:13 + | +LL | let _ = hasher.finish(); + | ^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ +LL ~ +LL ~ let _ = b.hash_one(&v); + | + +error: manual implementation of `BuildHasher::hash_one` + --> $DIR/manual_hash_one.rs:88:13 + | +LL | let _ = hasher.finish(); + | ^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ +LL ~ +LL ~ let _ = b.hash_one(&v); + | + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed index 5be2dd280..9c4bd335a 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed @@ -33,6 +33,7 @@ fn msrv_1_23() { assert!(matches!(b'1', b'0'..=b'9')); assert!(matches!('X', 'A'..='Z')); assert!(matches!('x', 'A'..='Z' | 'a'..='z')); + assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); } #[clippy::msrv = "1.24"] @@ -40,14 +41,17 @@ fn msrv_1_24() { assert!(b'1'.is_ascii_digit()); assert!('X'.is_ascii_uppercase()); assert!('x'.is_ascii_alphabetic()); + assert!('x'.is_ascii_hexdigit()); } #[clippy::msrv = "1.46"] fn msrv_1_46() { const FOO: bool = matches!('x', '0'..='9'); + const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); } #[clippy::msrv = "1.47"] fn msrv_1_47() { const FOO: bool = 'x'.is_ascii_digit(); + const BAR: bool = 'x'.is_ascii_hexdigit(); } diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs index f9249e22a..785943cd2 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs @@ -33,6 +33,7 @@ fn msrv_1_23() { assert!(matches!(b'1', b'0'..=b'9')); assert!(matches!('X', 'A'..='Z')); assert!(matches!('x', 'A'..='Z' | 'a'..='z')); + assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); } #[clippy::msrv = "1.24"] @@ -40,14 +41,17 @@ fn msrv_1_24() { assert!(matches!(b'1', b'0'..=b'9')); assert!(matches!('X', 'A'..='Z')); assert!(matches!('x', 'A'..='Z' | 'a'..='z')); + assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); } #[clippy::msrv = "1.46"] fn msrv_1_46() { const FOO: bool = matches!('x', '0'..='9'); + const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); } #[clippy::msrv = "1.47"] fn msrv_1_47() { const FOO: bool = matches!('x', '0'..='9'); + const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); } diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr index e0fb46e59..f69522c5f 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr @@ -98,28 +98,40 @@ LL | ('A'..='Z').contains(cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_uppercase()` error: manual check for common ascii range - --> $DIR/manual_is_ascii_check.rs:40:13 + --> $DIR/manual_is_ascii_check.rs:41:13 | LL | assert!(matches!(b'1', b'0'..=b'9')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'1'.is_ascii_digit()` error: manual check for common ascii range - --> $DIR/manual_is_ascii_check.rs:41:13 + --> $DIR/manual_is_ascii_check.rs:42:13 | LL | assert!(matches!('X', 'A'..='Z')); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'X'.is_ascii_uppercase()` error: manual check for common ascii range - --> $DIR/manual_is_ascii_check.rs:42:13 + --> $DIR/manual_is_ascii_check.rs:43:13 | LL | assert!(matches!('x', 'A'..='Z' | 'a'..='z')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_alphabetic()` error: manual check for common ascii range - --> $DIR/manual_is_ascii_check.rs:52:23 + --> $DIR/manual_is_ascii_check.rs:44:13 + | +LL | assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()` + +error: manual check for common ascii range + --> $DIR/manual_is_ascii_check.rs:55:23 | LL | const FOO: bool = matches!('x', '0'..='9'); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_digit()` -error: aborting due to 20 previous errors +error: manual check for common ascii range + --> $DIR/manual_is_ascii_check.rs:56:23 + | +LL | const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()` + +error: aborting due to 22 previous errors diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs index 6775fdc92..27717ab3a 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.rs +++ b/src/tools/clippy/tests/ui/manual_let_else.rs @@ -35,9 +35,7 @@ fn fire() { let v = if let Some(v) = g() { //~^ ERROR: this could be rewritten as `let...else` // Blocks around the identity should have no impact - { - { v } - } + { { v } } } else { // Some computation should still make it fire g(); diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr index 49dbd7615..2b6504a18 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.stderr +++ b/src/tools/clippy/tests/ui/manual_let_else.stderr @@ -31,7 +31,7 @@ error: this could be rewritten as `let...else` LL | / let v = if let Some(v) = g() { LL | | LL | | // Blocks around the identity should have no impact -LL | | { +LL | | { { v } } ... | LL | | return; LL | | }; @@ -47,25 +47,25 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:49:9 + --> $DIR/manual_let_else.rs:47:9 | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:51:9 + --> $DIR/manual_let_else.rs:49:9 | LL | let v = if let Some(v_some) = g() { v_some } else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:56:5 + --> $DIR/manual_let_else.rs:54:5 | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:60:5 + --> $DIR/manual_let_else.rs:58:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -83,7 +83,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:68:5 + --> $DIR/manual_let_else.rs:66:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -101,7 +101,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:76:5 + --> $DIR/manual_let_else.rs:74:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -121,7 +121,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:87:5 + --> $DIR/manual_let_else.rs:85:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -143,13 +143,13 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:98:5 + --> $DIR/manual_let_else.rs:96:5 | LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { if panic!() {} };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:102:5 + --> $DIR/manual_let_else.rs:100:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -170,7 +170,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:112:5 + --> $DIR/manual_let_else.rs:110:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -191,7 +191,7 @@ LL + } }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:122:5 + --> $DIR/manual_let_else.rs:120:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -220,7 +220,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:140:5 + --> $DIR/manual_let_else.rs:138:5 | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | @@ -238,7 +238,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:148:5 + --> $DIR/manual_let_else.rs:146:5 | LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | @@ -256,7 +256,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:158:13 + --> $DIR/manual_let_else.rs:156:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` @@ -267,19 +267,19 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:167:5 + --> $DIR/manual_let_else.rs:165:5 | LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:171:5 + --> $DIR/manual_let_else.rs:169:5 | LL | let mut v = if let Variant::B(b) = e() { b } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:176:5 + --> $DIR/manual_let_else.rs:174:5 | LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { LL | | @@ -297,19 +297,19 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:183:5 + --> $DIR/manual_let_else.rs:181:5 | LL | let v = if let Variant::A(.., a) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:187:5 + --> $DIR/manual_let_else.rs:185:5 | LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:191:5 + --> $DIR/manual_let_else.rs:189:5 | LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -327,7 +327,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:199:5 + --> $DIR/manual_let_else.rs:197:5 | LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -345,7 +345,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:207:5 + --> $DIR/manual_let_else.rs:205:5 | LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> { LL | | @@ -363,7 +363,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:324:5 + --> $DIR/manual_let_else.rs:322:5 | LL | / let _ = match ff { LL | | diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.fixed b/src/tools/clippy/tests/ui/manual_let_else_match.fixed index 09b713f04..588ba5edd 100644 --- a/src/tools/clippy/tests/ui/manual_let_else_match.fixed +++ b/src/tools/clippy/tests/ui/manual_let_else_match.fixed @@ -133,3 +133,7 @@ fn not_fire() { [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data, }; } + +fn issue11579() { + let Some(msg) = Some("hi") else { unreachable!("can't happen") }; +} diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs index e6af47384..c37b5613f 100644 --- a/src/tools/clippy/tests/ui/manual_let_else_match.rs +++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs @@ -170,3 +170,11 @@ fn not_fire() { [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data, }; } + +fn issue11579() { + let msg = match Some("hi") { + //~^ ERROR: this could be rewritten as `let...else` + Some(m) => m, + _ => unreachable!("can't happen"), + }; +} diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr index 8ca2c8407..18bfe324b 100644 --- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr +++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr @@ -92,5 +92,15 @@ LL | | _ => return, LL | | }; | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };` -error: aborting due to 9 previous errors +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else_match.rs:175:5 + | +LL | / let msg = match Some("hi") { +LL | | +LL | | Some(m) => m, +LL | | _ => unreachable!("can't happen"), +LL | | }; + | |______^ help: consider writing: `let Some(msg) = Some("hi") else { unreachable!("can't happen") };` + +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.fixed b/src/tools/clippy/tests/ui/manual_map_option_2.fixed index 513f6e323..f5bb4e0af 100644 --- a/src/tools/clippy/tests/ui/manual_map_option_2.fixed +++ b/src/tools/clippy/tests/ui/manual_map_option_2.fixed @@ -42,9 +42,7 @@ fn main() { // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); - let _ = s.as_ref().map(|x| { - if let Some(ref s) = s { (x.clone(), s) } else { panic!() } - }); + let _ = s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }); // Issue #7820 unsafe fn f(x: u32) -> u32 { diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.rs b/src/tools/clippy/tests/ui/manual_map_option_2.rs index fd186743f..cbc2356e0 100644 --- a/src/tools/clippy/tests/ui/manual_map_option_2.rs +++ b/src/tools/clippy/tests/ui/manual_map_option_2.rs @@ -46,9 +46,7 @@ fn main() { // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); let _ = match &s { - Some(x) => Some({ - if let Some(ref s) = s { (x.clone(), s) } else { panic!() } - }), + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.stderr b/src/tools/clippy/tests/ui/manual_map_option_2.stderr index bf242c041..d3754f22d 100644 --- a/src/tools/clippy/tests/ui/manual_map_option_2.stderr +++ b/src/tools/clippy/tests/ui/manual_map_option_2.stderr @@ -26,22 +26,13 @@ error: manual implementation of `Option::map` | LL | let _ = match &s { | _____________^ -LL | | Some(x) => Some({ -LL | | if let Some(ref s) = s { (x.clone(), s) } else { panic!() } -LL | | }), +LL | | Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), LL | | None => None, LL | | }; - | |_____^ - | -help: try - | -LL ~ let _ = s.as_ref().map(|x| { -LL + if let Some(ref s) = s { (x.clone(), s) } else { panic!() } -LL ~ }); - | + | |_____^ help: try: `s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } })` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:60:17 + --> $DIR/manual_map_option_2.rs:58:17 | LL | let _ = match Some(0) { | _________________^ @@ -51,7 +42,7 @@ LL | | }; | |_________^ help: try: `Some(0).map(|x| f(x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:65:13 + --> $DIR/manual_map_option_2.rs:63:13 | LL | let _ = match Some(0) { | _____________^ @@ -61,7 +52,7 @@ LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` - --> $DIR/manual_map_option_2.rs:69:13 + --> $DIR/manual_map_option_2.rs:67:13 | LL | let _ = match Some(0) { | _____________^ diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs index 0e439dabf..e32ba8631 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs @@ -10,10 +10,9 @@ enum E { _C, } -// user forgot to remove the marker +// if the user explicitly marks as nonexhaustive we shouldn't warn them #[non_exhaustive] enum Ep { - //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern A, B, #[doc(hidden)] diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr index ce7e21c94..7361a4a2c 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr @@ -22,23 +22,5 @@ LL | _C, = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]` -error: this seems like a manual implementation of the non-exhaustive pattern - --> $DIR/manual_non_exhaustive_enum.rs:15:1 - | -LL | / enum Ep { -LL | | -LL | | A, -LL | | B, -LL | | #[doc(hidden)] -LL | | _C, -LL | | } - | |_^ - | -help: remove this variant - --> $DIR/manual_non_exhaustive_enum.rs:20:5 - | -LL | _C, - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/manual_string_new.fixed b/src/tools/clippy/tests/ui/manual_string_new.fixed index 273be4e0f..2d4c5a029 100644 --- a/src/tools/clippy/tests/ui/manual_string_new.fixed +++ b/src/tools/clippy/tests/ui/manual_string_new.fixed @@ -1,4 +1,5 @@ #![warn(clippy::manual_string_new)] +#![allow(clippy::unnecessary_fallible_conversions)] macro_rules! create_strings_from_macro { // When inside a macro, nothing should warn to prevent false positives. diff --git a/src/tools/clippy/tests/ui/manual_string_new.rs b/src/tools/clippy/tests/ui/manual_string_new.rs index 0d5514fc8..20f0be6aa 100644 --- a/src/tools/clippy/tests/ui/manual_string_new.rs +++ b/src/tools/clippy/tests/ui/manual_string_new.rs @@ -1,4 +1,5 @@ #![warn(clippy::manual_string_new)] +#![allow(clippy::unnecessary_fallible_conversions)] macro_rules! create_strings_from_macro { // When inside a macro, nothing should warn to prevent false positives. diff --git a/src/tools/clippy/tests/ui/manual_string_new.stderr b/src/tools/clippy/tests/ui/manual_string_new.stderr index 399652d3f..cb2d78c39 100644 --- a/src/tools/clippy/tests/ui/manual_string_new.stderr +++ b/src/tools/clippy/tests/ui/manual_string_new.stderr @@ -1,5 +1,5 @@ error: empty String is being created manually - --> $DIR/manual_string_new.rs:13:13 + --> $DIR/manual_string_new.rs:14:13 | LL | let _ = "".to_string(); | ^^^^^^^^^^^^^^ help: consider using: `String::new()` @@ -8,49 +8,49 @@ LL | let _ = "".to_string(); = help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]` error: empty String is being created manually - --> $DIR/manual_string_new.rs:16:13 + --> $DIR/manual_string_new.rs:17:13 | LL | let _ = "".to_owned(); | ^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:19:21 + --> $DIR/manual_string_new.rs:20:21 | LL | let _: String = "".into(); | ^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:26:13 + --> $DIR/manual_string_new.rs:27:13 | LL | let _ = String::from(""); | ^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:27:13 + --> $DIR/manual_string_new.rs:28:13 | LL | let _ = <String>::from(""); | ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:32:13 + --> $DIR/manual_string_new.rs:33:13 | LL | let _ = String::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:38:21 + --> $DIR/manual_string_new.rs:39:21 | LL | let _: String = From::from(""); | ^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:43:21 + --> $DIR/manual_string_new.rs:44:21 | LL | let _: String = TryFrom::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> $DIR/manual_string_new.rs:46:21 + --> $DIR/manual_string_new.rs:47:21 | LL | let _: String = TryFrom::try_from("").expect("this should warn"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed index cc40b1620..62b0ba018 100644 --- a/src/tools/clippy/tests/ui/map_identity.fixed +++ b/src/tools/clippy/tests/ui/map_identity.fixed @@ -17,6 +17,33 @@ fn main() { }); let _: Result<u32, u32> = Ok(1); let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42); + // : u32 guides type inference + let _ = Ok(1).map_err(|a: u32| a); + let _ = Ok(1).map_err(std::convert::identity::<u32>); +} + +fn issue7189() { + // should lint + let x = [(1, 2), (3, 4)]; + let _ = x.iter(); + let _ = x.iter(); + let _ = x.iter(); + + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))]; + let _ = y.iter(); + + // should not lint + let _ = x.iter().map(|(x, y)| (x, y, y)); + let _ = x.iter().map(|(x, _y)| (x,)); + let _ = x.iter().map(|(x, _)| (x,)); + let _ = x.iter().map(|(x, ..)| (x,)); + let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); } fn not_identity(x: &u16) -> u16 { diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs index 97a91aea6..b7f4c99f2 100644 --- a/src/tools/clippy/tests/ui/map_identity.rs +++ b/src/tools/clippy/tests/ui/map_identity.rs @@ -19,6 +19,35 @@ fn main() { }); let _: Result<u32, u32> = Ok(1).map_err(|a| a); let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42); + // : u32 guides type inference + let _ = Ok(1).map_err(|a: u32| a); + let _ = Ok(1).map_err(std::convert::identity::<u32>); +} + +fn issue7189() { + // should lint + let x = [(1, 2), (3, 4)]; + let _ = x.iter().map(|(x, y)| (x, y)); + let _ = x.iter().map(|(x, y)| { + return (x, y); + }); + let _ = x.iter().map(|(x, y)| return (x, y)); + + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))]; + let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + + // should not lint + let _ = x.iter().map(|(x, y)| (x, y, y)); + let _ = x.iter().map(|(x, _y)| (x,)); + let _ = x.iter().map(|(x, _)| (x,)); + let _ = x.iter().map(|(x, ..)| (x,)); + let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + let _ = y + .iter() + .map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); } fn not_identity(x: &u16) -> u16 { diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr index 8942fd7c0..4ca24b0b0 100644 --- a/src/tools/clippy/tests/ui/map_identity.stderr +++ b/src/tools/clippy/tests/ui/map_identity.stderr @@ -40,5 +40,32 @@ error: unnecessary map of the identity function LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a); | ^^^^^^^^^^^^^^^ help: remove the call to `map_err` -error: aborting due to 6 previous errors +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:30:21 + | +LL | let _ = x.iter().map(|(x, y)| (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:31:21 + | +LL | let _ = x.iter().map(|(x, y)| { + | _____________________^ +LL | | return (x, y); +LL | | }); + | |______^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:34:21 + | +LL | let _ = x.iter().map(|(x, y)| return (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:37:21 + | +LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs index 1ee048bf7..5c277f925 100644 --- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs +++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs @@ -4,14 +4,18 @@ //@no-rustfix use std::sync::atomic::Ordering; // #[non_exhaustive] enum +fn repeat() -> ! { + panic!() +} + pub fn f(x: Ordering) { + #[deny(non_exhaustive_omitted_patterns)] match x { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), - #[deny(non_exhaustive_omitted_patterns)] - _ => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), + _ => repeat(), } } @@ -25,8 +29,8 @@ mod f { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), - _ => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), + _ => repeat(), } } } @@ -38,9 +42,9 @@ pub fn g(x: Ordering) { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ ERROR: this match arm has an identical body to the `_` wildcard arm - _ => panic!(), + _ => repeat(), } } @@ -52,9 +56,9 @@ mod g { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ ERROR: this match arm has an identical body to the `_` wildcard arm - _ => panic!(), + _ => repeat(), } } } diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr index a03953633..ae6b02ab1 100644 --- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr +++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr @@ -1,29 +1,29 @@ error: this match arm has an identical body to the `_` wildcard arm - --> $DIR/match_same_arms_non_exhaustive.rs:41:9 + --> $DIR/match_same_arms_non_exhaustive.rs:45:9 | -LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), +LL | Ordering::AcqRel | Ordering::SeqCst => repeat(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> $DIR/match_same_arms_non_exhaustive.rs:43:9 + --> $DIR/match_same_arms_non_exhaustive.rs:47:9 | -LL | _ => panic!(), +LL | _ => repeat(), | ^^^^^^^^^^^^^ = note: `-D clippy::match-same-arms` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to the `_` wildcard arm - --> $DIR/match_same_arms_non_exhaustive.rs:55:13 + --> $DIR/match_same_arms_non_exhaustive.rs:59:13 | -LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), +LL | Ordering::AcqRel | Ordering::SeqCst => repeat(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> $DIR/match_same_arms_non_exhaustive.rs:57:13 + --> $DIR/match_same_arms_non_exhaustive.rs:61:13 | -LL | _ => panic!(), +LL | _ => repeat(), | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/min_ident_chars.rs b/src/tools/clippy/tests/ui/min_ident_chars.rs index 030863ca0..f99c35d5c 100644 --- a/src/tools/clippy/tests/ui/min_ident_chars.rs +++ b/src/tools/clippy/tests/ui/min_ident_chars.rs @@ -1,5 +1,6 @@ //@aux-build:proc_macros.rs #![allow(irrefutable_let_patterns, nonstandard_style, unused)] +#![allow(clippy::struct_field_names)] #![warn(clippy::min_ident_chars)] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/min_ident_chars.stderr b/src/tools/clippy/tests/ui/min_ident_chars.stderr index 253636cf9..e4181157e 100644 --- a/src/tools/clippy/tests/ui/min_ident_chars.stderr +++ b/src/tools/clippy/tests/ui/min_ident_chars.stderr @@ -1,5 +1,5 @@ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:8:8 + --> $DIR/min_ident_chars.rs:9:8 | LL | struct A { | ^ @@ -8,169 +8,169 @@ LL | struct A { = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]` error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:9:5 + --> $DIR/min_ident_chars.rs:10:5 | LL | a: u32, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:11:5 + --> $DIR/min_ident_chars.rs:12:5 | LL | A: u32, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:12:5 + --> $DIR/min_ident_chars.rs:13:5 | LL | I: u32, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:15:8 + --> $DIR/min_ident_chars.rs:16:8 | LL | struct B(u32); | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:17:8 + --> $DIR/min_ident_chars.rs:18:8 | LL | struct O { | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:18:5 + --> $DIR/min_ident_chars.rs:19:5 | LL | o: u32, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:23:6 + --> $DIR/min_ident_chars.rs:24:6 | LL | enum C { | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:24:5 + --> $DIR/min_ident_chars.rs:25:5 | LL | D, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:25:5 + --> $DIR/min_ident_chars.rs:26:5 | LL | E, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:26:5 + --> $DIR/min_ident_chars.rs:27:5 | LL | F, | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:50:9 + --> $DIR/min_ident_chars.rs:51:9 | LL | let h = 1; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:51:9 + --> $DIR/min_ident_chars.rs:52:9 | LL | let e = 2; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:52:9 + --> $DIR/min_ident_chars.rs:53:9 | LL | let l = 3; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:53:9 + --> $DIR/min_ident_chars.rs:54:9 | LL | let l = 4; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:54:9 + --> $DIR/min_ident_chars.rs:55:9 | LL | let o = 6; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:58:10 + --> $DIR/min_ident_chars.rs:59:10 | LL | let (h, o, w) = (1, 2, 3); | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:58:13 + --> $DIR/min_ident_chars.rs:59:13 | LL | let (h, o, w) = (1, 2, 3); | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:59:10 + --> $DIR/min_ident_chars.rs:60:10 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:59:14 + --> $DIR/min_ident_chars.rs:60:14 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:59:17 + --> $DIR/min_ident_chars.rs:60:17 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:61:16 + --> $DIR/min_ident_chars.rs:62:16 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:61:19 + --> $DIR/min_ident_chars.rs:62:19 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:61:29 + --> $DIR/min_ident_chars.rs:62:29 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:65:9 + --> $DIR/min_ident_chars.rs:66:9 | LL | let o = 1; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:66:9 + --> $DIR/min_ident_chars.rs:67:9 | LL | let o = O { o }; | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:80:4 + --> $DIR/min_ident_chars.rs:81:4 | LL | fn b() {} | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:81:21 + --> $DIR/min_ident_chars.rs:82:21 | LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { | ^ error: this ident consists of a single char - --> $DIR/min_ident_chars.rs:81:29 + --> $DIR/min_ident_chars.rs:82:29 | LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { | ^ diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs index c8a0d6641..3917bb9e0 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs @@ -11,13 +11,12 @@ fn outer_attr() {} mod multiple { #![clippy::msrv = "1.40"] #![clippy::msrv = "=1.35.0"] - //~^ ERROR: `msrv` is defined multiple times #![clippy::msrv = "1.10.1"] - //~^ ERROR: `msrv` is defined multiple times + //~^ ERROR: `clippy::msrv` is defined multiple times mod foo { #![clippy::msrv = "1"] #![clippy::msrv = "1.0.0"] - //~^ ERROR: `msrv` is defined multiple times + //~^ ERROR: `clippy::msrv` is defined multiple times } } diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr index 8d4071e25..cf8392f03 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr @@ -10,20 +10,8 @@ error: `invalid.version` is not a valid Rust version LL | #[clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:13:5 - | -LL | #![clippy::msrv = "=1.35.0"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: first definition found here - --> $DIR/min_rust_version_invalid_attr.rs:12:5 - | -LL | #![clippy::msrv = "1.40"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:15:5 +error: `clippy::msrv` is defined multiple times + --> $DIR/min_rust_version_invalid_attr.rs:14:5 | LL | #![clippy::msrv = "1.10.1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,17 +22,17 @@ note: first definition found here LL | #![clippy::msrv = "1.40"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `msrv` is defined multiple times - --> $DIR/min_rust_version_invalid_attr.rs:20:9 +error: `clippy::msrv` is defined multiple times + --> $DIR/min_rust_version_invalid_attr.rs:19:9 | LL | #![clippy::msrv = "1.0.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> $DIR/min_rust_version_invalid_attr.rs:19:9 + --> $DIR/min_rust_version_invalid_attr.rs:18:9 | LL | #![clippy::msrv = "1"] | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/misnamed_getters.fixed b/src/tools/clippy/tests/ui/misnamed_getters.fixed index 2a7a2067e..70af604b2 100644 --- a/src/tools/clippy/tests/ui/misnamed_getters.fixed +++ b/src/tools/clippy/tests/ui/misnamed_getters.fixed @@ -1,4 +1,5 @@ #![allow(unused)] +#![allow(clippy::struct_field_names)] #![warn(clippy::misnamed_getters)] struct A { diff --git a/src/tools/clippy/tests/ui/misnamed_getters.rs b/src/tools/clippy/tests/ui/misnamed_getters.rs index 56ddc46c4..23c3e7bc5 100644 --- a/src/tools/clippy/tests/ui/misnamed_getters.rs +++ b/src/tools/clippy/tests/ui/misnamed_getters.rs @@ -1,4 +1,5 @@ #![allow(unused)] +#![allow(clippy::struct_field_names)] #![warn(clippy::misnamed_getters)] struct A { diff --git a/src/tools/clippy/tests/ui/misnamed_getters.stderr b/src/tools/clippy/tests/ui/misnamed_getters.stderr index aadec6549..120a3f311 100644 --- a/src/tools/clippy/tests/ui/misnamed_getters.stderr +++ b/src/tools/clippy/tests/ui/misnamed_getters.stderr @@ -1,5 +1,5 @@ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:11:5 + --> $DIR/misnamed_getters.rs:12:5 | LL | / fn a(&self) -> &u8 { LL | | @@ -13,7 +13,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]` error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:16:5 + --> $DIR/misnamed_getters.rs:17:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | @@ -23,7 +23,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:21:5 + --> $DIR/misnamed_getters.rs:22:5 | LL | / fn b(self) -> u8 { LL | | @@ -33,7 +33,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:26:5 + --> $DIR/misnamed_getters.rs:27:5 | LL | / fn b_mut(&mut self) -> &mut u8 { LL | | @@ -43,7 +43,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:31:5 + --> $DIR/misnamed_getters.rs:32:5 | LL | / fn c(&self) -> &u8 { LL | | @@ -53,7 +53,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:36:5 + --> $DIR/misnamed_getters.rs:37:5 | LL | / fn c_mut(&mut self) -> &mut u8 { LL | | @@ -63,7 +63,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:48:5 + --> $DIR/misnamed_getters.rs:49:5 | LL | / unsafe fn a(&self) -> &u8 { LL | | @@ -73,7 +73,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:52:5 + --> $DIR/misnamed_getters.rs:53:5 | LL | / unsafe fn a_mut(&mut self) -> &mut u8 { LL | | @@ -83,7 +83,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:57:5 + --> $DIR/misnamed_getters.rs:58:5 | LL | / unsafe fn b(self) -> u8 { LL | | @@ -93,7 +93,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:62:5 + --> $DIR/misnamed_getters.rs:63:5 | LL | / unsafe fn b_mut(&mut self) -> &mut u8 { LL | | @@ -103,7 +103,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:75:5 + --> $DIR/misnamed_getters.rs:76:5 | LL | / unsafe fn a_unchecked(&self) -> &u8 { LL | | @@ -113,7 +113,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:79:5 + --> $DIR/misnamed_getters.rs:80:5 | LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { LL | | @@ -123,7 +123,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:84:5 + --> $DIR/misnamed_getters.rs:85:5 | LL | / unsafe fn b_unchecked(self) -> u8 { LL | | @@ -133,7 +133,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:89:5 + --> $DIR/misnamed_getters.rs:90:5 | LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { LL | | @@ -143,7 +143,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:122:5 + --> $DIR/misnamed_getters.rs:123:5 | LL | / fn a(&self) -> &u8 { LL | | @@ -153,7 +153,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:126:5 + --> $DIR/misnamed_getters.rs:127:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | @@ -163,7 +163,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:131:5 + --> $DIR/misnamed_getters.rs:132:5 | LL | / fn d(&self) -> &u8 { LL | | @@ -173,7 +173,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> $DIR/misnamed_getters.rs:135:5 + --> $DIR/misnamed_getters.rs:136:5 | LL | / fn d_mut(&mut self) -> &mut u8 { LL | | diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/auxiliary/helper.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/auxiliary/helper.rs index 7b9dc76b8..775e07114 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/auxiliary/helper.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/auxiliary/helper.rs @@ -1,8 +1,8 @@ // This file provides a const function that is unstably const forever. #![feature(staged_api)] -#![stable(feature = "1", since = "1.0.0")] +#![stable(feature = "clippytest", since = "1.0.0")] -#[stable(feature = "1", since = "1.0.0")] +#[stable(feature = "clippytest", since = "1.0.0")] #[rustc_const_unstable(feature = "foo", issue = "none")] pub const fn unstably_const_fn() {} diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs index 4ef6f0ca9..8afb4df20 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -147,4 +147,11 @@ fn _field_fn_ptr(x: unsafe fn()) { } } +// await expands to an unsafe block with several operations, but this is fine.: #11312 +async fn await_desugaring_silent() { + async fn helper() {} + + helper().await; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/must_use_unit.stderr b/src/tools/clippy/tests/ui/must_use_unit.stderr index e67d9b5b9..f2ee18585 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.stderr +++ b/src/tools/clippy/tests/ui/must_use_unit.stderr @@ -4,7 +4,7 @@ error: this unit-returning function has a `#[must_use]` attribute LL | #[must_use] | ----------- help: remove the attribute LL | pub fn must_use_default() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::must-use-unit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]` @@ -23,7 +23,7 @@ error: this unit-returning function has a `#[must_use]` attribute LL | #[must_use = "With note"] | ------------------------- help: remove the attribute LL | pub fn must_use_with_note() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed index c9ea831f8..3059de8f8 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed @@ -7,7 +7,8 @@ clippy::equatable_if_let, clippy::needless_if, clippy::needless_return, - clippy::self_named_constructors + clippy::self_named_constructors, + clippy::struct_field_names )] use std::cell::Cell; diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.rs b/src/tools/clippy/tests/ui/needless_bool/fixable.rs index b83d9c3f2..b2cbe86e2 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.rs +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.rs @@ -7,7 +7,8 @@ clippy::equatable_if_let, clippy::needless_if, clippy::needless_return, - clippy::self_named_constructors + clippy::self_named_constructors, + clippy::struct_field_names )] use std::cell::Cell; diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr index 2b189c898..72b0670c9 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr @@ -1,5 +1,5 @@ error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:40:5 + --> $DIR/fixable.rs:41:5 | LL | / if x { LL | | true @@ -12,7 +12,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:45:5 + --> $DIR/fixable.rs:46:5 | LL | / if x { LL | | false @@ -22,7 +22,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:50:5 + --> $DIR/fixable.rs:51:5 | LL | / if x && y { LL | | false @@ -32,7 +32,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!(x && y)` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:58:5 + --> $DIR/fixable.rs:59:5 | LL | / if a == b { LL | | false @@ -42,7 +42,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a != b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:63:5 + --> $DIR/fixable.rs:64:5 | LL | / if a != b { LL | | false @@ -52,7 +52,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a == b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:68:5 + --> $DIR/fixable.rs:69:5 | LL | / if a < b { LL | | false @@ -62,7 +62,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a >= b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:73:5 + --> $DIR/fixable.rs:74:5 | LL | / if a <= b { LL | | false @@ -72,7 +72,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a > b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:78:5 + --> $DIR/fixable.rs:79:5 | LL | / if a > b { LL | | false @@ -82,7 +82,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a <= b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:83:5 + --> $DIR/fixable.rs:84:5 | LL | / if a >= b { LL | | false @@ -92,7 +92,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a < b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:111:5 + --> $DIR/fixable.rs:112:5 | LL | / if x { LL | | return true; @@ -102,7 +102,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:119:5 + --> $DIR/fixable.rs:120:5 | LL | / if x { LL | | return false; @@ -112,7 +112,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return !x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:127:5 + --> $DIR/fixable.rs:128:5 | LL | / if x && y { LL | | return true; @@ -122,7 +122,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return x && y` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:135:5 + --> $DIR/fixable.rs:136:5 | LL | / if x && y { LL | | return false; @@ -132,7 +132,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return !(x && y)` error: equality checks against true are unnecessary - --> $DIR/fixable.rs:143:8 + --> $DIR/fixable.rs:144:8 | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` @@ -141,25 +141,25 @@ LL | if x == true {}; = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against false can be replaced by a negation - --> $DIR/fixable.rs:147:8 + --> $DIR/fixable.rs:148:8 | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: equality checks against true are unnecessary - --> $DIR/fixable.rs:157:8 + --> $DIR/fixable.rs:158:8 | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` error: equality checks against false can be replaced by a negation - --> $DIR/fixable.rs:158:8 + --> $DIR/fixable.rs:159:8 | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:167:12 + --> $DIR/fixable.rs:168:12 | LL | } else if returns_bool() { | ____________^ @@ -170,7 +170,7 @@ LL | | }; | |_____^ help: you can reduce it to: `{ !returns_bool() }` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:180:5 + --> $DIR/fixable.rs:181:5 | LL | / if unsafe { no(4) } & 1 != 0 { LL | | true @@ -180,13 +180,13 @@ LL | | }; | |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:185:30 + --> $DIR/fixable.rs:186:30 | LL | let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:188:9 + --> $DIR/fixable.rs:189:9 | LL | if unsafe { no(4) } & 1 != 0 { true } else { false } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` diff --git a/src/tools/clippy/tests/ui/needless_if.fixed b/src/tools/clippy/tests/ui/needless_if.fixed index b84182c57..be35dcddb 100644 --- a/src/tools/clippy/tests/ui/needless_if.fixed +++ b/src/tools/clippy/tests/ui/needless_if.fixed @@ -39,11 +39,21 @@ fn main() { } // Do not lint `if let` or let chains if let true = true {} - if let true = true && true {} - if true && let true = true {} + if let true = true + && true + {} + if true + && let true = true + {} // Can lint nested `if let`s ({ - if let true = true && true { true } else { false } + if let true = true + && true + { + true + } else { + false + } } && true); external! { if (true) {} } with_span! { diff --git a/src/tools/clippy/tests/ui/needless_if.rs b/src/tools/clippy/tests/ui/needless_if.rs index 6c6023c72..e2ad17e69 100644 --- a/src/tools/clippy/tests/ui/needless_if.rs +++ b/src/tools/clippy/tests/ui/needless_if.rs @@ -39,11 +39,21 @@ fn main() { } // Do not lint `if let` or let chains if let true = true {} - if let true = true && true {} - if true && let true = true {} + if let true = true + && true + {} + if true + && let true = true + {} // Can lint nested `if let`s if { - if let true = true && true { true } else { false } + if let true = true + && true + { + true + } else { + false + } } && true {} external! { if (true) {} } diff --git a/src/tools/clippy/tests/ui/needless_if.stderr b/src/tools/clippy/tests/ui/needless_if.stderr index ed5b9452b..c3e83c0f1 100644 --- a/src/tools/clippy/tests/ui/needless_if.stderr +++ b/src/tools/clippy/tests/ui/needless_if.stderr @@ -29,10 +29,13 @@ LL + }); | error: this `if` branch is empty - --> $DIR/needless_if.rs:45:5 + --> $DIR/needless_if.rs:49:5 | LL | / if { -LL | | if let true = true && true { true } else { false } +LL | | if let true = true +LL | | && true +LL | | { +... | LL | | } && true LL | | {} | |______^ @@ -40,24 +43,30 @@ LL | | {} help: you can remove it | LL ~ ({ -LL + if let true = true && true { true } else { false } +LL + if let true = true +LL + && true +LL + { +LL + true +LL + } else { +LL + false +LL + } LL + } && true); | error: this `if` branch is empty - --> $DIR/needless_if.rs:83:5 + --> $DIR/needless_if.rs:93:5 | LL | if { maybe_side_effect() } {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });` error: this `if` branch is empty - --> $DIR/needless_if.rs:85:5 + --> $DIR/needless_if.rs:95:5 | LL | if { maybe_side_effect() } && true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);` error: this `if` branch is empty - --> $DIR/needless_if.rs:89:5 + --> $DIR/needless_if.rs:99:5 | LL | if true {} | ^^^^^^^^^^ help: you can remove it: `true;` diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed index 9f45da048..891b2b014 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.fixed +++ b/src/tools/clippy/tests/ui/needless_late_init.fixed @@ -230,7 +230,9 @@ fn does_not_lint() { } let x; - if true && let Some(n) = Some("let chains too") { + if true + && let Some(n) = Some("let chains too") + { x = 1; } else { x = 2; diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs index 0dab0faad..553995116 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.rs +++ b/src/tools/clippy/tests/ui/needless_late_init.rs @@ -230,7 +230,9 @@ fn does_not_lint() { } let x; - if true && let Some(n) = Some("let chains too") { + if true + && let Some(n) = Some("let chains too") + { x = 1; } else { x = 2; diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs index 39d76f999..bdb6d40d9 100644 --- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs @@ -270,6 +270,51 @@ pub async fn closure4(n: &mut usize) { })(); } +// Should not warn. +async fn _f(v: &mut Vec<()>) { + let x = || v.pop(); + _ = || || x; +} + +struct Data<T: ?Sized> { + value: T, +} +// Unsafe functions should not warn. +unsafe fn get_mut_unchecked<T>(ptr: &mut NonNull<Data<T>>) -> &mut T { + &mut (*ptr.as_ptr()).value +} +// Unsafe blocks should not warn. +fn get_mut_unchecked2<T>(ptr: &mut NonNull<Data<T>>) -> &mut T { + unsafe { &mut (*ptr.as_ptr()).value } +} + +fn set_true(b: &mut bool) { + *b = true; +} + +// Should not warn. +fn true_setter(b: &mut bool) -> impl FnOnce() + '_ { + move || set_true(b) +} + +// Should not warn. +fn filter_copy<T: Copy>(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T) -> bool + '_ { + move |&item| predicate(item) +} + +// `is_from_proc_macro` stress tests +fn _empty_tup(x: &mut (())) {} +fn _single_tup(x: &mut ((i32,))) {} +fn _multi_tup(x: &mut ((i32, u32))) {} +fn _fn(x: &mut (fn())) {} +#[rustfmt::skip] +fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} +fn _extern_c_fn(x: &mut extern "C" fn()) {} +fn _unsafe_fn(x: &mut unsafe fn()) {} +fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} +fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} +fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} + fn main() { let mut u = 0; let mut v = vec![0]; diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr index aa937c3f6..3e1415be0 100644 --- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr +++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr @@ -139,5 +139,65 @@ LL | pub async fn closure4(n: &mut usize) { | = warning: changing this function will impact semver compatibility -error: aborting due to 21 previous errors +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:306:18 + | +LL | fn _empty_tup(x: &mut (())) {} + | ^^^^^^^^^ help: consider changing to: `&()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:307:19 + | +LL | fn _single_tup(x: &mut ((i32,))) {} + | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:308:18 + | +LL | fn _multi_tup(x: &mut ((i32, u32))) {} + | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:309:11 + | +LL | fn _fn(x: &mut (fn())) {} + | ^^^^^^^^^^^ help: consider changing to: `&fn()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:311:23 + | +LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:312:20 + | +LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} + | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:313:18 + | +LL | fn _unsafe_fn(x: &mut unsafe fn()) {} + | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:314:25 + | +LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:315:20 + | +LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:316:20 + | +LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` + +error: aborting due to 31 previous errors diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed index 855498105..4ea711fd6 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.fixed +++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed @@ -18,4 +18,8 @@ fn main() { multiline string "; + + "no hashes"; + b"no hashes"; + c"no hashes"; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs index 06d497303..b6239f9b1 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.rs +++ b/src/tools/clippy/tests/ui/needless_raw_string.rs @@ -18,4 +18,8 @@ fn main() { multiline string "#; + + r"no hashes"; + br"no hashes"; + cr"no hashes"; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr index e6806b31b..276bc84c6 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr @@ -6,7 +6,7 @@ LL | r#"aaa"#; | = note: `-D clippy::needless-raw-strings` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]` -help: try +help: use a plain string literal instead | LL - r#"aaa"#; LL + "aaa"; @@ -18,7 +18,7 @@ error: unnecessary raw string literal LL | br#"aaa"#; | ^^^^^^^^^ | -help: try +help: use a plain byte string literal instead | LL - br#"aaa"#; LL + b"aaa"; @@ -30,7 +30,7 @@ error: unnecessary raw string literal LL | cr#"aaa"#; | ^^^^^^^^^ | -help: try +help: use a plain C string literal instead | LL - cr#"aaa"#; LL + c"aaa"; @@ -46,7 +46,7 @@ LL | | string LL | | "#; | |______^ | -help: try +help: use a plain string literal instead | LL ~ " LL | a @@ -55,5 +55,41 @@ LL | string LL ~ "; | -error: aborting due to 4 previous errors +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:22:5 + | +LL | r"no hashes"; + | ^^^^^^^^^^^^ + | +help: use a plain string literal instead + | +LL - r"no hashes"; +LL + "no hashes"; + | + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:23:5 + | +LL | br"no hashes"; + | ^^^^^^^^^^^^^ + | +help: use a plain byte string literal instead + | +LL - br"no hashes"; +LL + b"no hashes"; + | + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:24:5 + | +LL | cr"no hashes"; + | ^^^^^^^^^^^^^ + | +help: use a plain C string literal instead + | +LL - cr"no hashes"; +LL + c"no hashes"; + | + +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr index 4399c6555..017160b1a 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr @@ -6,7 +6,7 @@ LL | r#"\aaa"#; | = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]` -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r#"\aaa"#; LL + r"\aaa"; @@ -18,7 +18,7 @@ error: unnecessary hashes around raw string literal LL | r##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the string literal | LL - r##"Hello "world"!"##; LL + r#"Hello "world"!"#; @@ -30,7 +30,7 @@ error: unnecessary hashes around raw string literal LL | r######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the string literal | LL - r######" "### "## "# "######; LL + r####" "### "## "# "####; @@ -42,7 +42,7 @@ error: unnecessary hashes around raw string literal LL | r######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the string literal | LL - r######" "aa" "# "## "######; LL + r###" "aa" "# "## "###; @@ -54,7 +54,7 @@ error: unnecessary hashes around raw string literal LL | br#"\aaa"#; | ^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the byte string literal | LL - br#"\aaa"#; LL + br"\aaa"; @@ -66,7 +66,7 @@ error: unnecessary hashes around raw string literal LL | br##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the byte string literal | LL - br##"Hello "world"!"##; LL + br#"Hello "world"!"#; @@ -78,7 +78,7 @@ error: unnecessary hashes around raw string literal LL | br######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the byte string literal | LL - br######" "### "## "# "######; LL + br####" "### "## "# "####; @@ -90,7 +90,7 @@ error: unnecessary hashes around raw string literal LL | br######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the byte string literal | LL - br######" "aa" "# "## "######; LL + br###" "aa" "# "## "###; @@ -102,7 +102,7 @@ error: unnecessary hashes around raw string literal LL | cr#"\aaa"#; | ^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the C string literal | LL - cr#"\aaa"#; LL + cr"\aaa"; @@ -114,7 +114,7 @@ error: unnecessary hashes around raw string literal LL | cr##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the C string literal | LL - cr##"Hello "world"!"##; LL + cr#"Hello "world"!"#; @@ -126,7 +126,7 @@ error: unnecessary hashes around raw string literal LL | cr######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the C string literal | LL - cr######" "### "## "# "######; LL + cr####" "### "## "# "####; @@ -138,7 +138,7 @@ error: unnecessary hashes around raw string literal LL | cr######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the C string literal | LL - cr######" "aa" "# "## "######; LL + cr###" "aa" "# "## "###; @@ -154,7 +154,7 @@ LL | | string LL | | "#; | |______^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL ~ r" LL | \a @@ -169,7 +169,7 @@ error: unnecessary hashes around raw string literal LL | r###"rust"###; | ^^^^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r###"rust"###; LL + r"rust"; @@ -181,7 +181,7 @@ error: unnecessary hashes around raw string literal LL | r#"hello world"#; | ^^^^^^^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r#"hello world"#; LL + r"hello world"; diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index c3415a7df..f0113ca69 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -1,7 +1,6 @@ #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, - clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, clippy::let_unit_value, @@ -52,7 +51,7 @@ fn impure_else(arg: Option<i32>) { println!("return 1"); 1 }; - let _ = arg.map_or_else(|| side_effect(), |x| x); + let _ = arg.map_or_else(side_effect, |x| x); } fn test_map_or_else(arg: Option<u32>) { @@ -224,3 +223,17 @@ mod issue10729 { fn do_something(_value: &str) {} fn do_something2(_value: &mut str) {} } + +fn issue11429() { + use std::collections::HashMap; + + macro_rules! new_map { + () => {{ HashMap::new() }}; + } + + let opt: Option<HashMap<u8, u8>> = None; + + let mut _hashmap = opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone()); + + let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone()); +} diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 86537f620..18b7af443 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -1,7 +1,6 @@ #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, - clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let, clippy::let_unit_value, @@ -271,3 +270,21 @@ mod issue10729 { fn do_something(_value: &str) {} fn do_something2(_value: &mut str) {} } + +fn issue11429() { + use std::collections::HashMap; + + macro_rules! new_map { + () => {{ HashMap::new() }}; + } + + let opt: Option<HashMap<u8, u8>> = None; + + let mut _hashmap = if let Some(hm) = &opt { + hm.clone() + } else { + HashMap::new() + }; + + let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; +} diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index 6d7d02f8c..e36357bcb 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:12:5 + --> $DIR/option_if_let_else.rs:11:5 | LL | / if let Some(x) = string { LL | | (true, x) @@ -12,19 +12,19 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:30:13 + --> $DIR/option_if_let_else.rs:29:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:31:13 + --> $DIR/option_if_let_else.rs:30:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:32:13 + --> $DIR/option_if_let_else.rs:31:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -44,13 +44,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:38:13 + --> $DIR/option_if_let_else.rs:37:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:39:13 + --> $DIR/option_if_let_else.rs:38:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -70,7 +70,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:45:13 + --> $DIR/option_if_let_else.rs:44:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -90,7 +90,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:54:5 + --> $DIR/option_if_let_else.rs:53:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -109,7 +109,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:67:13 + --> $DIR/option_if_let_else.rs:66:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -118,10 +118,10 @@ LL | | } else { LL | | // map_or_else must be suggested LL | | side_effect() LL | | }; - | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)` + | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:76:13 + --> $DIR/option_if_let_else.rs:75:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -144,7 +144,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:109:13 + --> $DIR/option_if_let_else.rs:108:13 | LL | / if let Some(idx) = s.find('.') { LL | | vec![s[..idx].to_string(), s[idx..].to_string()] @@ -154,7 +154,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:120:5 + --> $DIR/option_if_let_else.rs:119:5 | LL | / if let Ok(binding) = variable { LL | | println!("Ok {binding}"); @@ -173,13 +173,13 @@ LL + }) | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:142:13 + --> $DIR/option_if_let_else.rs:141:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:152:13 + --> $DIR/option_if_let_else.rs:151:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -201,13 +201,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:180:13 + --> $DIR/option_if_let_else.rs:179:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:184:13 + --> $DIR/option_if_let_else.rs:183:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -227,7 +227,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:223:13 + --> $DIR/option_if_let_else.rs:222:13 | LL | let _ = match s { | _____________^ @@ -237,7 +237,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:227:13 + --> $DIR/option_if_let_else.rs:226:13 | LL | let _ = match Some(10) { | _____________^ @@ -247,7 +247,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:233:13 + --> $DIR/option_if_let_else.rs:232:13 | LL | let _ = match res { | _____________^ @@ -257,7 +257,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:237:13 + --> $DIR/option_if_let_else.rs:236:13 | LL | let _ = match res { | _____________^ @@ -267,13 +267,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:241:13 + --> $DIR/option_if_let_else.rs:240:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:258:9 + --> $DIR/option_if_let_else.rs:257:9 | LL | / match initial { LL | | Some(value) => do_something(value), @@ -282,7 +282,7 @@ LL | | } | |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:265:9 + --> $DIR/option_if_let_else.rs:264:9 | LL | / match initial { LL | | Some(value) => do_something2(value), @@ -290,5 +290,22 @@ LL | | None => {}, LL | | } | |_________^ help: try: `initial.as_mut().map_or({}, |value| do_something2(value))` -error: aborting due to 23 previous errors +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:283:24 + | +LL | let mut _hashmap = if let Some(hm) = &opt { + | ________________________^ +LL | | hm.clone() +LL | | } else { +LL | | HashMap::new() +LL | | }; + | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` + +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:289:19 + | +LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` + +error: aborting due to 25 previous errors diff --git a/src/tools/clippy/tests/ui/print_literal.fixed b/src/tools/clippy/tests/ui/print_literal.fixed index 88cd3a54b..a7157c07f 100644 --- a/src/tools/clippy/tests/ui/print_literal.fixed +++ b/src/tools/clippy/tests/ui/print_literal.fixed @@ -39,20 +39,30 @@ fn main() { // throw a warning println!("hello world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string println!("world hello"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // named args shouldn't change anything either println!("hello world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string println!("world hello"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion println!("file: {}", file!()); + + // Braces in unicode escapes should not be escaped + println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}"); + println!("\\\u{1234}"); + // This does not lint because it would have to suggest unescaping the character + println!(r"{}", "\u{ab123}"); + // These are not unicode escapes + println!("\\u{{ab123}} \\u{{{{"); + println!(r"\u{{ab123}} \u{{{{"); + println!("\\{{ab123}} \\u{{{{"); + println!("\\u{{ab123}}"); + println!("\\\\u{{1234}}"); + + println!("mixed: {{hello}} {world}"); } diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs index bd7444c96..4b04b4274 100644 --- a/src/tools/clippy/tests/ui/print_literal.rs +++ b/src/tools/clippy/tests/ui/print_literal.rs @@ -39,20 +39,30 @@ fn main() { // throw a warning println!("{0} {1}", "hello", "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string println!("{1} {0}", "hello", "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // named args shouldn't change anything either println!("{foo} {bar}", foo = "hello", bar = "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string println!("{bar} {foo}", foo = "hello", bar = "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion println!("file: {}", file!()); + + // Braces in unicode escapes should not be escaped + println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); + println!("{}", "\\\u{1234}"); + // This does not lint because it would have to suggest unescaping the character + println!(r"{}", "\u{ab123}"); + // These are not unicode escapes + println!("{}", r"\u{ab123} \u{{"); + println!(r"{}", r"\u{ab123} \u{{"); + println!("{}", r"\{ab123} \u{{"); + println!("{}", "\\u{ab123}"); + println!("{}", "\\\\u{1234}"); + + println!("mixed: {} {world}", "{hello}"); } diff --git a/src/tools/clippy/tests/ui/print_literal.stderr b/src/tools/clippy/tests/ui/print_literal.stderr index 1d9751b92..8c011d7bc 100644 --- a/src/tools/clippy/tests/ui/print_literal.stderr +++ b/src/tools/clippy/tests/ui/print_literal.stderr @@ -52,97 +52,145 @@ error: literal with an empty format string --> $DIR/print_literal.rs:40:25 | LL | println!("{0} {1}", "hello", "world"); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^ | help: try | LL - println!("{0} {1}", "hello", "world"); -LL + println!("hello {1}", "world"); +LL + println!("hello world"); | error: literal with an empty format string - --> $DIR/print_literal.rs:40:34 + --> $DIR/print_literal.rs:42:25 | -LL | println!("{0} {1}", "hello", "world"); - | ^^^^^^^ +LL | println!("{1} {0}", "hello", "world"); + | ^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{0} {1}", "hello", "world"); -LL + println!("{0} world", "hello"); +LL - println!("{1} {0}", "hello", "world"); +LL + println!("world hello"); | error: literal with an empty format string - --> $DIR/print_literal.rs:43:34 + --> $DIR/print_literal.rs:46:35 | -LL | println!("{1} {0}", "hello", "world"); - | ^^^^^^^ +LL | println!("{foo} {bar}", foo = "hello", bar = "world"); + | ^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{1} {0}", "hello", "world"); -LL + println!("world {0}", "hello"); +LL - println!("{foo} {bar}", foo = "hello", bar = "world"); +LL + println!("hello world"); | error: literal with an empty format string - --> $DIR/print_literal.rs:43:25 + --> $DIR/print_literal.rs:48:35 | -LL | println!("{1} {0}", "hello", "world"); - | ^^^^^^^ +LL | println!("{bar} {foo}", foo = "hello", bar = "world"); + | ^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{1} {0}", "hello", "world"); -LL + println!("{1} hello", "world"); +LL - println!("{bar} {foo}", foo = "hello", bar = "world"); +LL + println!("world hello"); | error: literal with an empty format string - --> $DIR/print_literal.rs:48:35 + --> $DIR/print_literal.rs:56:20 | -LL | println!("{foo} {bar}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{foo} {bar}", foo = "hello", bar = "world"); -LL + println!("hello {bar}", bar = "world"); +LL - println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); +LL + println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}"); | error: literal with an empty format string - --> $DIR/print_literal.rs:48:50 + --> $DIR/print_literal.rs:57:20 | -LL | println!("{foo} {bar}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | println!("{}", "\\\u{1234}"); + | ^^^^^^^^^^^^ | help: try | -LL - println!("{foo} {bar}", foo = "hello", bar = "world"); -LL + println!("{foo} world", foo = "hello"); +LL - println!("{}", "\\\u{1234}"); +LL + println!("\\\u{1234}"); | error: literal with an empty format string - --> $DIR/print_literal.rs:51:50 + --> $DIR/print_literal.rs:61:20 | -LL | println!("{bar} {foo}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | println!("{}", r"\u{ab123} \u{{"); + | ^^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{bar} {foo}", foo = "hello", bar = "world"); -LL + println!("world {foo}", foo = "hello"); +LL - println!("{}", r"\u{ab123} \u{{"); +LL + println!("\\u{{ab123}} \\u{{{{"); | error: literal with an empty format string - --> $DIR/print_literal.rs:51:35 + --> $DIR/print_literal.rs:62:21 | -LL | println!("{bar} {foo}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | println!(r"{}", r"\u{ab123} \u{{"); + | ^^^^^^^^^^^^^^^^^ | help: try | -LL - println!("{bar} {foo}", foo = "hello", bar = "world"); -LL + println!("{bar} hello", bar = "world"); +LL - println!(r"{}", r"\u{ab123} \u{{"); +LL + println!(r"\u{{ab123}} \u{{{{"); + | + +error: literal with an empty format string + --> $DIR/print_literal.rs:63:20 + | +LL | println!("{}", r"\{ab123} \u{{"); + | ^^^^^^^^^^^^^^^^ + | +help: try + | +LL - println!("{}", r"\{ab123} \u{{"); +LL + println!("\\{{ab123}} \\u{{{{"); + | + +error: literal with an empty format string + --> $DIR/print_literal.rs:64:20 + | +LL | println!("{}", "\\u{ab123}"); + | ^^^^^^^^^^^^ + | +help: try + | +LL - println!("{}", "\\u{ab123}"); +LL + println!("\\u{{ab123}}"); + | + +error: literal with an empty format string + --> $DIR/print_literal.rs:65:20 + | +LL | println!("{}", "\\\\u{1234}"); + | ^^^^^^^^^^^^^ + | +help: try + | +LL - println!("{}", "\\\\u{1234}"); +LL + println!("\\\\u{{1234}}"); + | + +error: literal with an empty format string + --> $DIR/print_literal.rs:67:35 + | +LL | println!("mixed: {} {world}", "{hello}"); + | ^^^^^^^^^ + | +help: try + | +LL - println!("mixed: {} {world}", "{hello}"); +LL + println!("mixed: {{hello}} {world}"); | -error: aborting due to 12 previous errors +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed index f23116a7e..f8af90927 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.fixed +++ b/src/tools/clippy/tests/ui/redundant_guards.fixed @@ -48,7 +48,7 @@ fn main() { Some(x) if let Some(1) = x => { x; .. - } + }, _ => todo!(), }; let y = 1; diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs index c0206b4ce..b46f8a620 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.rs +++ b/src/tools/clippy/tests/ui/redundant_guards.rs @@ -48,7 +48,7 @@ fn main() { Some(x) if let Some(1) = x => { x; .. - } + }, _ => todo!(), }; let y = 1; diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs index c5d93e436..182d067a5 100644 --- a/src/tools/clippy/tests/ui/redundant_locals.rs +++ b/src/tools/clippy/tests/ui/redundant_locals.rs @@ -117,4 +117,49 @@ fn macros() { let x = 1; let x = x; } + + let x = 10; + macro_rules! rebind_outer_macro { + ($x:ident) => { + let x = x; + }; + } + rebind_outer_macro!(y); +} + +struct WithDrop(usize); +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +struct InnerDrop(WithDrop); + +struct ComposeDrop { + d: WithDrop, +} + +struct WithoutDrop(usize); + +fn drop_trait() { + let a = WithDrop(1); + let b = WithDrop(2); + let a = a; +} + +fn without_drop() { + let a = WithoutDrop(1); + let b = WithoutDrop(2); + let a = a; +} + +fn drop_inner() { + let a = InnerDrop(WithDrop(1)); + let b = InnerDrop(WithDrop(2)); + let a = a; +} + +fn drop_compose() { + let a = ComposeDrop { d: WithDrop(1) }; + let b = ComposeDrop { d: WithDrop(1) }; + let a = a; } diff --git a/src/tools/clippy/tests/ui/redundant_locals.stderr b/src/tools/clippy/tests/ui/redundant_locals.stderr index 13b872e95..30ab4aa2e 100644 --- a/src/tools/clippy/tests/ui/redundant_locals.stderr +++ b/src/tools/clippy/tests/ui/redundant_locals.stderr @@ -1,137 +1,172 @@ -error: redundant redefinition of a binding - --> $DIR/redundant_locals.rs:11:9 +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:12:5 | -LL | let x = 1; - | ^ LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` +help: `x` is initially defined here + --> $DIR/redundant_locals.rs:11:9 + | +LL | let x = 1; + | ^ = note: `-D clippy::redundant-locals` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]` -error: redundant redefinition of a binding - --> $DIR/redundant_locals.rs:16:9 +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:17:5 | -LL | let mut x = 1; - | ^^^^^ LL | let mut x = x; | ^^^^^^^^^^^^^^ | - = help: remove the redefinition of `x` +help: `x` is initially defined here + --> $DIR/redundant_locals.rs:16:9 + | +LL | let mut x = 1; + | ^^^^^ -error: redundant redefinition of a binding +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:47:5 + | +LL | let x = x; + | ^^^^^^^^^^ + | +help: `x` is initially defined here --> $DIR/redundant_locals.rs:46:14 | LL | fn parameter(x: i32) { | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:52:5 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:51:9 | LL | let x = 1; | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:53:5 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:52:9 | LL | let x = x; | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:54:5 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:53:9 | LL | let x = x; | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:55:5 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:54:9 | LL | let x = x; | ^ -LL | let x = x; + +error: redundant redefinition of a binding `a` + --> $DIR/redundant_locals.rs:61:5 + | +LL | let a = a; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `a` is initially defined here --> $DIR/redundant_locals.rs:59:9 | LL | let a = 1; | ^ -LL | let b = 2; -LL | let a = a; + +error: redundant redefinition of a binding `b` + --> $DIR/redundant_locals.rs:62:5 + | +LL | let b = b; | ^^^^^^^^^^ | - = help: remove the redefinition of `a` - -error: redundant redefinition of a binding +help: `b` is initially defined here --> $DIR/redundant_locals.rs:60:9 | LL | let b = 2; | ^ -LL | let a = a; -LL | let b = b; - | ^^^^^^^^^^ - | - = help: remove the redefinition of `b` -error: redundant redefinition of a binding +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:68:9 + | +LL | let x = x; + | ^^^^^^^^^^ + | +help: `x` is initially defined here --> $DIR/redundant_locals.rs:67:13 | LL | let x = 1; | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:75:9 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:74:13 | LL | let x = 1; | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:78:9 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:77:6 | LL | |x: i32| { | ^ + +error: redundant redefinition of a binding `x` + --> $DIR/redundant_locals.rs:97:9 + | LL | let x = x; | ^^^^^^^^^^ | - = help: remove the redefinition of `x` - -error: redundant redefinition of a binding +help: `x` is initially defined here --> $DIR/redundant_locals.rs:94:9 | LL | let x = 1; | ^ -... -LL | let x = x; - | ^^^^^^^^^^ + +error: redundant redefinition of a binding `a` + --> $DIR/redundant_locals.rs:152:5 + | +LL | let a = a; + | ^^^^^^^^^^ | - = help: remove the redefinition of `x` +help: `a` is initially defined here + --> $DIR/redundant_locals.rs:150:9 + | +LL | let a = WithoutDrop(1); + | ^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed index 60f9fb6d4..c9b76262d 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed @@ -16,10 +16,15 @@ fn issue_11174<T>(boolean: bool, maybe_some: Option<T>) -> bool { fn issue_11174_edge_cases<T>(boolean: bool, boolean2: bool, maybe_some: Option<T>) { let _ = maybe_some.is_none() && (boolean || boolean2); // guard needs parentheses - let _ = match maybe_some { // can't use `matches!` here - // because `expr` metavars in macros don't allow let exprs - None if let Some(x) = Some(0) && x > 5 => true, - _ => false + let _ = match maybe_some { + // can't use `matches!` here + // because `expr` metavars in macros don't allow let exprs + None if let Some(x) = Some(0) + && x > 5 => + { + true + }, + _ => false, }; } diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs index 94bbb569c..a5f9caf65 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs @@ -16,10 +16,15 @@ fn issue_11174<T>(boolean: bool, maybe_some: Option<T>) -> bool { fn issue_11174_edge_cases<T>(boolean: bool, boolean2: bool, maybe_some: Option<T>) { let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses - let _ = match maybe_some { // can't use `matches!` here - // because `expr` metavars in macros don't allow let exprs - None if let Some(x) = Some(0) && x > 5 => true, - _ => false + let _ = match maybe_some { + // can't use `matches!` here + // because `expr` metavars in macros don't allow let exprs + None if let Some(x) = Some(0) + && x > 5 => + { + true + }, + _ => false, }; } diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr index fdf395d82..a75551c56 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr @@ -14,49 +14,49 @@ LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard nee | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:27:12 + --> $DIR/redundant_pattern_matching_option.rs:32:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:29:12 + --> $DIR/redundant_pattern_matching_option.rs:34:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:31:12 + --> $DIR/redundant_pattern_matching_option.rs:36:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:37:15 + --> $DIR/redundant_pattern_matching_option.rs:42:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:39:15 + --> $DIR/redundant_pattern_matching_option.rs:44:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:41:15 + --> $DIR/redundant_pattern_matching_option.rs:46:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:44:15 + --> $DIR/redundant_pattern_matching_option.rs:49:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:52:5 + --> $DIR/redundant_pattern_matching_option.rs:57:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -65,7 +65,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:57:5 + --> $DIR/redundant_pattern_matching_option.rs:62:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -74,7 +74,7 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:62:13 + --> $DIR/redundant_pattern_matching_option.rs:67:13 | LL | let _ = match None::<()> { | _____________^ @@ -84,55 +84,55 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:68:20 + --> $DIR/redundant_pattern_matching_option.rs:73:20 | LL | let _ = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:74:20 + --> $DIR/redundant_pattern_matching_option.rs:79:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:76:19 + --> $DIR/redundant_pattern_matching_option.rs:81:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:82:12 + --> $DIR/redundant_pattern_matching_option.rs:87:12 | LL | if let Some(..) = gen_opt() {} | -------^^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:97:12 + --> $DIR/redundant_pattern_matching_option.rs:102:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:99:12 + --> $DIR/redundant_pattern_matching_option.rs:104:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:101:15 + --> $DIR/redundant_pattern_matching_option.rs:106:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:103:15 + --> $DIR/redundant_pattern_matching_option.rs:108:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:105:5 + --> $DIR/redundant_pattern_matching_option.rs:110:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -141,7 +141,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:110:5 + --> $DIR/redundant_pattern_matching_option.rs:115:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -150,19 +150,19 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:118:12 + --> $DIR/redundant_pattern_matching_option.rs:123:12 | LL | if let None = *(&None::<()>) {} | -------^^^^----------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:119:12 + --> $DIR/redundant_pattern_matching_option.rs:124:12 | LL | if let None = *&None::<()> {} | -------^^^^--------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:125:5 + --> $DIR/redundant_pattern_matching_option.rs:130:5 | LL | / match x { LL | | Some(_) => true, @@ -171,7 +171,7 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:130:5 + --> $DIR/redundant_pattern_matching_option.rs:135:5 | LL | / match x { LL | | None => true, @@ -180,7 +180,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:135:5 + --> $DIR/redundant_pattern_matching_option.rs:140:5 | LL | / match x { LL | | Some(_) => false, @@ -189,7 +189,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:140:5 + --> $DIR/redundant_pattern_matching_option.rs:145:5 | LL | / match x { LL | | None => false, @@ -198,13 +198,13 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:155:13 + --> $DIR/redundant_pattern_matching_option.rs:160:13 | LL | let _ = matches!(x, Some(_)); | ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:157:13 + --> $DIR/redundant_pattern_matching_option.rs:162:13 | LL | let _ = matches!(x, None); | ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()` diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs index e25609f75..51fe346d0 100644 --- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs +++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs @@ -1,4 +1,5 @@ #![warn(clippy::rest_pat_in_fully_bound_structs)] +#![allow(clippy::struct_field_names)] struct A { a: i32, diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr index 2c221b4db..a62f1d0b6 100644 --- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr +++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr @@ -1,5 +1,5 @@ error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> $DIR/rest_pat_in_fully_bound_structs.rs:22:9 + --> $DIR/rest_pat_in_fully_bound_structs.rs:23:9 | LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint = help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]` error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> $DIR/rest_pat_in_fully_bound_structs.rs:24:9 + --> $DIR/rest_pat_in_fully_bound_structs.rs:25:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint = help: consider removing `..` from this binding error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> $DIR/rest_pat_in_fully_bound_structs.rs:31:9 + --> $DIR/rest_pat_in_fully_bound_structs.rs:32:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed index 8027c053f..a7555704f 100644 --- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed +++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed @@ -1,8 +1,12 @@ +//@aux-build:proc_macro_derive.rs #![warn(clippy::std_instead_of_core)] #![allow(unused_imports)] extern crate alloc; +#[macro_use] +extern crate proc_macro_derive; + #[warn(clippy::std_instead_of_core)] fn std_instead_of_core() { // Regular import @@ -55,6 +59,13 @@ fn alloc_instead_of_core() { //~^ ERROR: used import from `alloc` instead of `core` } +mod std_in_proc_macro_derive { + #[warn(clippy::alloc_instead_of_core)] + #[allow(unused)] + #[derive(ImplStructWithStdDisplay)] + struct B {} +} + fn main() { std_instead_of_core(); std_instead_of_alloc(); diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs index 63a096384..af7f3399f 100644 --- a/src/tools/clippy/tests/ui/std_instead_of_core.rs +++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs @@ -1,8 +1,12 @@ +//@aux-build:proc_macro_derive.rs #![warn(clippy::std_instead_of_core)] #![allow(unused_imports)] extern crate alloc; +#[macro_use] +extern crate proc_macro_derive; + #[warn(clippy::std_instead_of_core)] fn std_instead_of_core() { // Regular import @@ -55,6 +59,13 @@ fn alloc_instead_of_core() { //~^ ERROR: used import from `alloc` instead of `core` } +mod std_in_proc_macro_derive { + #[warn(clippy::alloc_instead_of_core)] + #[allow(unused)] + #[derive(ImplStructWithStdDisplay)] + struct B {} +} + fn main() { std_instead_of_core(); std_instead_of_alloc(); diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr index ca26f77bd..4f7bdc404 100644 --- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr +++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr @@ -1,5 +1,5 @@ error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:9:9 + --> $DIR/std_instead_of_core.rs:13:9 | LL | use std::hash::Hasher; | ^^^ help: consider importing the item from `core`: `core` @@ -8,49 +8,49 @@ LL | use std::hash::Hasher; = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:12:11 + --> $DIR/std_instead_of_core.rs:16:11 | LL | use ::std::hash::Hash; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:18:9 + --> $DIR/std_instead_of_core.rs:22:9 | LL | use std::fmt::{Debug, Result}; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:22:15 + --> $DIR/std_instead_of_core.rs:26:15 | LL | let ptr = std::ptr::null::<u32>(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:24:21 + --> $DIR/std_instead_of_core.rs:28:21 | LL | let ptr_mut = ::std::ptr::null_mut::<usize>(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:28:16 + --> $DIR/std_instead_of_core.rs:32:16 | LL | let cell = std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:30:27 + --> $DIR/std_instead_of_core.rs:34:27 | LL | let cell_absolute = ::std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> $DIR/std_instead_of_core.rs:39:9 + --> $DIR/std_instead_of_core.rs:43:9 | LL | use std::iter::Iterator; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `alloc` - --> $DIR/std_instead_of_core.rs:46:9 + --> $DIR/std_instead_of_core.rs:50:9 | LL | use std::vec; | ^^^ help: consider importing the item from `alloc`: `alloc` @@ -59,13 +59,13 @@ LL | use std::vec; = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]` error: used import from `std` instead of `alloc` - --> $DIR/std_instead_of_core.rs:48:9 + --> $DIR/std_instead_of_core.rs:52:9 | LL | use std::vec::Vec; | ^^^ help: consider importing the item from `alloc`: `alloc` error: used import from `alloc` instead of `core` - --> $DIR/std_instead_of_core.rs:54:9 + --> $DIR/std_instead_of_core.rs:58:9 | LL | use alloc::slice::from_ref; | ^^^^^ help: consider importing the item from `core`: `core` diff --git a/src/tools/clippy/tests/ui/struct_fields.rs b/src/tools/clippy/tests/ui/struct_fields.rs new file mode 100644 index 000000000..8b1a1446e --- /dev/null +++ b/src/tools/clippy/tests/ui/struct_fields.rs @@ -0,0 +1,331 @@ +//@aux-build:proc_macros.rs + +#![warn(clippy::struct_field_names)] +#![allow(unused)] + +#[macro_use] +extern crate proc_macros; + +struct Data1 { + field_data1: u8, + //~^ ERROR: field name ends with the struct's name + another: u8, + foo: u8, + bar: u8, +} + +struct Data2 { + another: u8, + foo: u8, + data2_field: u8, + //~^ ERROR: field name starts with the struct's name + bar: u8, +} + +struct StructData { + //~^ ERROR: all fields have the same postfix: `data` + movable_data: u8, + fixed_data: u8, + invisible_data: u8, +} + +struct DataStruct { + //~^ ERROR: all fields have the same prefix: `data` + data_movable: u8, + data_fixed: u8, + data_invisible: u8, +} + +struct DoublePrefix { + //~^ ERROR: all fields have the same prefix: `some_data` + some_data_a: bool, + some_data_b: bool, + some_data_c: bool, +} + +struct DoublePostfix { + //~^ ERROR: all fields have the same postfix: `some_data` + a_some_data: bool, + b_some_data: bool, + c_some_data: bool, +} + +#[allow(non_snake_case)] +struct NotSnakeCase { + //~^ ERROR: all fields have the same postfix: `someData` + a_someData: bool, + b_someData: bool, + c_someData: bool, +} +#[allow(non_snake_case)] +struct NotSnakeCase2 { + //~^ ERROR: all fields have the same prefix: `someData` + someData_c: bool, + someData_b: bool, + someData_a_b: bool, +} + +// no error, threshold is 3 fiels by default +struct Fooo { + foo: u8, + bar: u8, +} + +struct NonCaps { + //~^ ERROR: all fields have the same prefix: `prefix` + prefix_çš„: u8, + prefix_tea: u8, + prefix_cake: u8, +} + +// should not lint +#[allow(clippy::struct_field_names)] +pub mod allowed { + pub struct PubAllowed { + some_this: u8, + some_that: u8, + some_other_what: u8, + } +} + +// should not lint +struct SomeData { + foo: u8, + bar: bool, + path: u8, + answer: u8, +} + +// should not lint +pub struct NetworkLayer { + layer1: Vec<u8>, + layer2: Vec<u8>, + layer3: Vec<u8>, + layer4: Vec<u8>, +} + +//should not lint +struct North { + normal: u8, + no_left: u8, + no_right: u8, +} + +mod issue8324_from_enum_variant_names { + // 8324: enum_variant_names warns even if removing the suffix would leave an empty string + struct Phase { + pre_lookup: u8, + lookup: u8, + post_lookup: u8, + } +} + +mod issue9018_from_enum_variant_names { + struct DoLint { + //~^ ERROR: all fields have the same prefix: `_type` + _type_create: u8, + _type_read: u8, + _type_update: u8, + _type_destroy: u8, + } + + struct DoLint2 { + //~^ ERROR: all fields have the same prefix: `__type` + __type_create: u8, + __type_read: u8, + __type_update: u8, + __type_destroy: u8, + } + + struct DoLint3 { + //~^ ERROR: all fields have the same prefix: `___type` + ___type_create: u8, + ___type_read: u8, + ___type_update: u8, + ___type_destroy: u8, + } + + struct DoLint4 { + //~^ ERROR: all fields have the same postfix: `_` + create_: u8, + read_: u8, + update_: u8, + destroy_: u8, + } + + struct DoLint5 { + //~^ ERROR: all fields have the same postfix: `__` + create__: u8, + read__: u8, + update__: u8, + destroy__: u8, + } + + struct DoLint6 { + //~^ ERROR: all fields have the same postfix: `___` + create___: u8, + read___: u8, + update___: u8, + destroy___: u8, + } + + struct DoLintToo { + //~^ ERROR: all fields have the same postfix: `type` + _create_type: u8, + _update_type: u8, + _delete_type: u8, + } + + struct DoNotLint { + _foo: u8, + _bar: u8, + _baz: u8, + } + + struct DoNotLint2 { + __foo: u8, + __bar: u8, + __baz: u8, + } +} + +mod allow_attributes_on_fields { + struct Struct { + #[allow(clippy::struct_field_names)] + struct_starts_with: u8, + #[allow(clippy::struct_field_names)] + ends_with_struct: u8, + foo: u8, + } +} + +// food field should not lint +struct Foo { + food: i32, + a: i32, + b: i32, +} + +struct Proxy { + proxy: i32, + //~^ ERROR: field name starts with the struct's name + unrelated1: bool, + unrelated2: bool, +} + +// should not lint +pub struct RegexT { + __buffer: i32, + __allocated: i32, + __used: i32, +} + +mod macro_tests { + macro_rules! mk_struct { + () => { + struct MacroStruct { + some_a: i32, + some_b: i32, + some_c: i32, + } + }; + } + mk_struct!(); + //~^ ERROR: all fields have the same prefix: `some` + + macro_rules! mk_struct2 { + () => { + struct Macrobaz { + macrobaz_a: i32, + some_b: i32, + some_c: i32, + } + }; + } + mk_struct2!(); + //~^ ERROR: field name starts with the struct's name + + macro_rules! mk_struct_with_names { + ($struct_name:ident, $field:ident) => { + struct $struct_name { + $field: i32, + other_something: i32, + other_field: i32, + } + }; + } + // expands to `struct Foo { foo: i32, ... }` + mk_struct_with_names!(Foo, foo); + //~^ ERROR: field name starts with the struct's name + + // expands to a struct with all fields starting with `other` but should not + // be linted because some fields come from the macro definition and the other from the input + mk_struct_with_names!(Some, other_data); + + // should not lint when names come from different places + macro_rules! mk_struct_with_field_name { + ($field_name:ident) => { + struct Baz { + one: i32, + two: i32, + $field_name: i32, + } + }; + } + mk_struct_with_field_name!(baz_three); + + // should not lint when names come from different places + macro_rules! mk_struct_with_field_name { + ($field_name:ident) => { + struct Bazilisk { + baz_one: i32, + baz_two: i32, + $field_name: i32, + } + }; + } + mk_struct_with_field_name!(baz_three); + + macro_rules! mk_struct_full_def { + ($struct_name:ident, $field1:ident, $field2:ident, $field3:ident) => { + struct $struct_name { + $field1: i32, + $field2: i32, + $field3: i32, + } + }; + } + mk_struct_full_def!(PrefixData, some_data, some_meta, some_other); + //~^ ERROR: all fields have the same prefix: `some` +} + +// should not lint on external code +external! { + struct DataExternal { + field_data1: u8, + another: u8, + foo: u8, + bar: u8, + } + + struct NotSnakeCaseExternal { + someData_c: bool, + someData_b: bool, + someData_a_b: bool, + } + + struct DoublePrefixExternal { + some_data_a: bool, + some_data_b: bool, + some_data_c: bool, + } + + struct StructDataExternal { + movable_data: u8, + fixed_data: u8, + invisible_data: u8, + } + +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/struct_fields.stderr b/src/tools/clippy/tests/ui/struct_fields.stderr new file mode 100644 index 000000000..4ca57715b --- /dev/null +++ b/src/tools/clippy/tests/ui/struct_fields.stderr @@ -0,0 +1,265 @@ +error: field name ends with the struct's name + --> $DIR/struct_fields.rs:10:5 + | +LL | field_data1: u8, + | ^^^^^^^^^^^^^^^ + | + = note: `-D clippy::struct-field-names` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]` + +error: field name starts with the struct's name + --> $DIR/struct_fields.rs:20:5 + | +LL | data2_field: u8, + | ^^^^^^^^^^^^^^^ + +error: all fields have the same postfix: `data` + --> $DIR/struct_fields.rs:25:1 + | +LL | / struct StructData { +LL | | +LL | | movable_data: u8, +LL | | fixed_data: u8, +LL | | invisible_data: u8, +LL | | } + | |_^ + | + = help: remove the postfixes + +error: all fields have the same prefix: `data` + --> $DIR/struct_fields.rs:32:1 + | +LL | / struct DataStruct { +LL | | +LL | | data_movable: u8, +LL | | data_fixed: u8, +LL | | data_invisible: u8, +LL | | } + | |_^ + | + = help: remove the prefixes + +error: all fields have the same prefix: `some_data` + --> $DIR/struct_fields.rs:39:1 + | +LL | / struct DoublePrefix { +LL | | +LL | | some_data_a: bool, +LL | | some_data_b: bool, +LL | | some_data_c: bool, +LL | | } + | |_^ + | + = help: remove the prefixes + +error: all fields have the same postfix: `some_data` + --> $DIR/struct_fields.rs:46:1 + | +LL | / struct DoublePostfix { +LL | | +LL | | a_some_data: bool, +LL | | b_some_data: bool, +LL | | c_some_data: bool, +LL | | } + | |_^ + | + = help: remove the postfixes + +error: all fields have the same postfix: `someData` + --> $DIR/struct_fields.rs:54:1 + | +LL | / struct NotSnakeCase { +LL | | +LL | | a_someData: bool, +LL | | b_someData: bool, +LL | | c_someData: bool, +LL | | } + | |_^ + | + = help: remove the postfixes + +error: all fields have the same prefix: `someData` + --> $DIR/struct_fields.rs:61:1 + | +LL | / struct NotSnakeCase2 { +LL | | +LL | | someData_c: bool, +LL | | someData_b: bool, +LL | | someData_a_b: bool, +LL | | } + | |_^ + | + = help: remove the prefixes + +error: all fields have the same prefix: `prefix` + --> $DIR/struct_fields.rs:74:1 + | +LL | / struct NonCaps { +LL | | +LL | | prefix_çš„: u8, +LL | | prefix_tea: u8, +LL | | prefix_cake: u8, +LL | | } + | |_^ + | + = help: remove the prefixes + +error: all fields have the same prefix: `_type` + --> $DIR/struct_fields.rs:124:5 + | +LL | / struct DoLint { +LL | | +LL | | _type_create: u8, +LL | | _type_read: u8, +LL | | _type_update: u8, +LL | | _type_destroy: u8, +LL | | } + | |_____^ + | + = help: remove the prefixes + +error: all fields have the same prefix: `__type` + --> $DIR/struct_fields.rs:132:5 + | +LL | / struct DoLint2 { +LL | | +LL | | __type_create: u8, +LL | | __type_read: u8, +LL | | __type_update: u8, +LL | | __type_destroy: u8, +LL | | } + | |_____^ + | + = help: remove the prefixes + +error: all fields have the same prefix: `___type` + --> $DIR/struct_fields.rs:140:5 + | +LL | / struct DoLint3 { +LL | | +LL | | ___type_create: u8, +LL | | ___type_read: u8, +LL | | ___type_update: u8, +LL | | ___type_destroy: u8, +LL | | } + | |_____^ + | + = help: remove the prefixes + +error: all fields have the same postfix: `_` + --> $DIR/struct_fields.rs:148:5 + | +LL | / struct DoLint4 { +LL | | +LL | | create_: u8, +LL | | read_: u8, +LL | | update_: u8, +LL | | destroy_: u8, +LL | | } + | |_____^ + | + = help: remove the postfixes + +error: all fields have the same postfix: `__` + --> $DIR/struct_fields.rs:156:5 + | +LL | / struct DoLint5 { +LL | | +LL | | create__: u8, +LL | | read__: u8, +LL | | update__: u8, +LL | | destroy__: u8, +LL | | } + | |_____^ + | + = help: remove the postfixes + +error: all fields have the same postfix: `___` + --> $DIR/struct_fields.rs:164:5 + | +LL | / struct DoLint6 { +LL | | +LL | | create___: u8, +LL | | read___: u8, +LL | | update___: u8, +LL | | destroy___: u8, +LL | | } + | |_____^ + | + = help: remove the postfixes + +error: all fields have the same postfix: `type` + --> $DIR/struct_fields.rs:172:5 + | +LL | / struct DoLintToo { +LL | | +LL | | _create_type: u8, +LL | | _update_type: u8, +LL | | _delete_type: u8, +LL | | } + | |_____^ + | + = help: remove the postfixes + +error: field name starts with the struct's name + --> $DIR/struct_fields.rs:210:5 + | +LL | proxy: i32, + | ^^^^^^^^^^ + +error: all fields have the same prefix: `some` + --> $DIR/struct_fields.rs:226:13 + | +LL | / struct MacroStruct { +LL | | some_a: i32, +LL | | some_b: i32, +LL | | some_c: i32, +LL | | } + | |_____________^ +... +LL | mk_struct!(); + | ------------ in this macro invocation + | + = help: remove the prefixes + = note: this error originates in the macro `mk_struct` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: field name starts with the struct's name + --> $DIR/struct_fields.rs:239:17 + | +LL | macrobaz_a: i32, + | ^^^^^^^^^^^^^^^ +... +LL | mk_struct2!(); + | ------------- in this macro invocation + | + = note: this error originates in the macro `mk_struct2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: field name starts with the struct's name + --> $DIR/struct_fields.rs:251:17 + | +LL | $field: i32, + | ^^^^^^^^^^^ +... +LL | mk_struct_with_names!(Foo, foo); + | ------------------------------- in this macro invocation + | + = note: this error originates in the macro `mk_struct_with_names` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: all fields have the same prefix: `some` + --> $DIR/struct_fields.rs:291:13 + | +LL | / struct $struct_name { +LL | | $field1: i32, +LL | | $field2: i32, +LL | | $field3: i32, +LL | | } + | |_____________^ +... +LL | mk_struct_full_def!(PrefixData, some_data, some_meta, some_other); + | ----------------------------------------------------------------- in this macro invocation + | + = help: remove the prefixes + = note: this error originates in the macro `mk_struct_full_def` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 21 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.fixed b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.fixed new file mode 100644 index 000000000..9668a6b99 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.fixed @@ -0,0 +1,6 @@ +#![warn(clippy::unnecessary_fallible_conversions)] + +fn main() { + let _: i64 = 0i32.into(); + let _: i64 = 0i32.into(); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.rs b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.rs new file mode 100644 index 000000000..9fa6c08b1 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.rs @@ -0,0 +1,6 @@ +#![warn(clippy::unnecessary_fallible_conversions)] + +fn main() { + let _: i64 = 0i32.try_into().unwrap(); + let _: i64 = 0i32.try_into().expect("can't happen"); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr new file mode 100644 index 000000000..b918fdf77 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr @@ -0,0 +1,17 @@ +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions.rs:4:23 + | +LL | let _: i64 = 0i32.try_into().unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: use: `into()` + | + = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions.rs:5:23 + | +LL | let _: i64 = 0i32.try_into().expect("can't happen"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `into()` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.rs new file mode 100644 index 000000000..68e617cc0 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.rs @@ -0,0 +1,43 @@ +//@aux-build:proc_macros.rs +//@no-rustfix +#![warn(clippy::unnecessary_fallible_conversions)] + +extern crate proc_macros; + +struct Foo; +impl TryFrom<i32> for Foo { + type Error = (); + fn try_from(_: i32) -> Result<Self, Self::Error> { + Ok(Foo) + } +} +impl From<i64> for Foo { + fn from(_: i64) -> Self { + Foo + } +} + +fn main() { + // `Foo` only implements `TryFrom<i32>` and not `From<i32>`, so don't lint + let _: Result<Foo, _> = 0i32.try_into(); + let _: Result<Foo, _> = i32::try_into(0i32); + let _: Result<Foo, _> = Foo::try_from(0i32); + + // ... it does impl From<i64> however + let _: Result<Foo, _> = 0i64.try_into(); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result<Foo, _> = i64::try_into(0i64); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result<Foo, _> = Foo::try_from(0i64); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + + let _: Result<i64, _> = 0i32.try_into(); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result<i64, _> = i32::try_into(0i32); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + let _: Result<i64, _> = <_>::try_from(0i32); + //~^ ERROR: use of a fallible conversion when an infallible one could be used + + // From a macro + let _: Result<i64, _> = proc_macros::external!(0i32).try_into(); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr new file mode 100644 index 000000000..286decf8f --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr @@ -0,0 +1,41 @@ +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:27:34 + | +LL | let _: Result<Foo, _> = 0i64.try_into(); + | ^^^^^^^^ help: use: `into` + | + = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:29:29 + | +LL | let _: Result<Foo, _> = i64::try_into(0i64); + | ^^^^^^^^^^^^^ help: use: `Into::into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:31:29 + | +LL | let _: Result<Foo, _> = Foo::try_from(0i64); + | ^^^^^^^^^^^^^ help: use: `From::from` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:34:34 + | +LL | let _: Result<i64, _> = 0i32.try_into(); + | ^^^^^^^^ help: use: `into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:36:29 + | +LL | let _: Result<i64, _> = i32::try_into(0i32); + | ^^^^^^^^^^^^^ help: use: `Into::into` + +error: use of a fallible conversion when an infallible one could be used + --> $DIR/unnecessary_fallible_conversions_unfixable.rs:38:29 + | +LL | let _: Result<i64, _> = <_>::try_from(0i32); + | ^^^^^^^^^^^^^ help: use: `From::from` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed index 304e7b7fd..4778eaefd 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed @@ -5,6 +5,7 @@ #![allow(clippy::map_identity)] #![allow(clippy::needless_borrow)] #![allow(clippy::unnecessary_literal_unwrap)] +#![allow(clippy::unit_arg)] use std::ops::Deref; @@ -76,6 +77,8 @@ fn main() { let _ = opt.ok_or(2); let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); let _ = cond.then_some(astronomers_pi); + let _ = true.then_some({}); + let _ = true.then_some({}); // Should lint - Builtin deref let r = &1; diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs index ddfa6bb3e..d4b7fd31b 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs @@ -5,6 +5,7 @@ #![allow(clippy::map_identity)] #![allow(clippy::needless_borrow)] #![allow(clippy::unnecessary_literal_unwrap)] +#![allow(clippy::unit_arg)] use std::ops::Deref; @@ -76,6 +77,8 @@ fn main() { let _ = opt.ok_or_else(|| 2); let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); let _ = cond.then(|| astronomers_pi); + let _ = true.then(|| -> _ {}); + let _ = true.then(|| {}); // Should lint - Builtin deref let r = &1; diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr index 4f1ca3748..1b0db4759 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr @@ -1,5 +1,5 @@ error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:68:13 + --> $DIR/unnecessary_lazy_eval.rs:69:13 | LL | let _ = opt.unwrap_or_else(|| 2); | ^^^^-------------------- @@ -10,7 +10,7 @@ LL | let _ = opt.unwrap_or_else(|| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:69:13 + --> $DIR/unnecessary_lazy_eval.rs:70:13 | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | ^^^^--------------------------------- @@ -18,7 +18,7 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:70:13 + --> $DIR/unnecessary_lazy_eval.rs:71:13 | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | ^^^^------------------------------------- @@ -26,7 +26,7 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:72:13 + --> $DIR/unnecessary_lazy_eval.rs:73:13 | LL | let _ = opt.and_then(|_| ext_opt); | ^^^^--------------------- @@ -34,7 +34,7 @@ LL | let _ = opt.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:73:13 + --> $DIR/unnecessary_lazy_eval.rs:74:13 | LL | let _ = opt.or_else(|| ext_opt); | ^^^^------------------- @@ -42,7 +42,7 @@ LL | let _ = opt.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:74:13 + --> $DIR/unnecessary_lazy_eval.rs:75:13 | LL | let _ = opt.or_else(|| None); | ^^^^---------------- @@ -50,7 +50,7 @@ LL | let _ = opt.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:75:13 + --> $DIR/unnecessary_lazy_eval.rs:76:13 | LL | let _ = opt.get_or_insert_with(|| 2); | ^^^^------------------------ @@ -58,7 +58,7 @@ LL | let _ = opt.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:76:13 + --> $DIR/unnecessary_lazy_eval.rs:77:13 | LL | let _ = opt.ok_or_else(|| 2); | ^^^^---------------- @@ -66,7 +66,7 @@ LL | let _ = opt.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:77:13 + --> $DIR/unnecessary_lazy_eval.rs:78:13 | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | ^^^^^^^^^^^^^^^^^------------------------------- @@ -74,15 +74,31 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))` error: unnecessary closure used with `bool::then` - --> $DIR/unnecessary_lazy_eval.rs:78:13 + --> $DIR/unnecessary_lazy_eval.rs:79:13 | LL | let _ = cond.then(|| astronomers_pi); | ^^^^^----------------------- | | | help: use `then_some(..)` instead: `then_some(astronomers_pi)` +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:80:13 + | +LL | let _ = true.then(|| -> _ {}); + | ^^^^^---------------- + | | + | help: use `then_some(..)` instead: `then_some({})` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:81:13 + | +LL | let _ = true.then(|| {}); + | ^^^^^----------- + | | + | help: use `then_some(..)` instead: `then_some({})` + error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:82:13 + --> $DIR/unnecessary_lazy_eval.rs:85:13 | LL | let _ = Some(1).unwrap_or_else(|| *r); | ^^^^^^^^--------------------- @@ -90,7 +106,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *r); | help: use `unwrap_or(..)` instead: `unwrap_or(*r)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:84:13 + --> $DIR/unnecessary_lazy_eval.rs:87:13 | LL | let _ = Some(1).unwrap_or_else(|| *b); | ^^^^^^^^--------------------- @@ -98,7 +114,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *b); | help: use `unwrap_or(..)` instead: `unwrap_or(*b)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:86:13 + --> $DIR/unnecessary_lazy_eval.rs:89:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | ^^^^^^^^^^^^^^^^^--------------------- @@ -106,7 +122,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | help: use `unwrap_or(..)` instead: `unwrap_or(&r)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:87:13 + --> $DIR/unnecessary_lazy_eval.rs:90:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | ^^^^^^^^^^^^^^^^^--------------------- @@ -114,7 +130,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | help: use `unwrap_or(..)` instead: `unwrap_or(&b)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:90:13 + --> $DIR/unnecessary_lazy_eval.rs:93:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); | ^^^^^^^^^-------------------- @@ -122,7 +138,7 @@ LL | let _ = Some(10).unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:91:13 + --> $DIR/unnecessary_lazy_eval.rs:94:13 | LL | let _ = Some(10).and_then(|_| ext_opt); | ^^^^^^^^^--------------------- @@ -130,7 +146,7 @@ LL | let _ = Some(10).and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:92:28 + --> $DIR/unnecessary_lazy_eval.rs:95:28 | LL | let _: Option<usize> = None.or_else(|| ext_opt); | ^^^^^------------------- @@ -138,7 +154,7 @@ LL | let _: Option<usize> = None.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:93:13 + --> $DIR/unnecessary_lazy_eval.rs:96:13 | LL | let _ = None.get_or_insert_with(|| 2); | ^^^^^------------------------ @@ -146,7 +162,7 @@ LL | let _ = None.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:94:35 + --> $DIR/unnecessary_lazy_eval.rs:97:35 | LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); | ^^^^^---------------- @@ -154,7 +170,7 @@ LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:95:28 + --> $DIR/unnecessary_lazy_eval.rs:98:28 | LL | let _: Option<usize> = None.or_else(|| None); | ^^^^^---------------- @@ -162,7 +178,7 @@ LL | let _: Option<usize> = None.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:98:13 + --> $DIR/unnecessary_lazy_eval.rs:101:13 | LL | let _ = deep.0.unwrap_or_else(|| 2); | ^^^^^^^-------------------- @@ -170,7 +186,7 @@ LL | let _ = deep.0.unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:99:13 + --> $DIR/unnecessary_lazy_eval.rs:102:13 | LL | let _ = deep.0.and_then(|_| ext_opt); | ^^^^^^^--------------------- @@ -178,7 +194,7 @@ LL | let _ = deep.0.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:100:13 + --> $DIR/unnecessary_lazy_eval.rs:103:13 | LL | let _ = deep.0.or_else(|| None); | ^^^^^^^---------------- @@ -186,7 +202,7 @@ LL | let _ = deep.0.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:101:13 + --> $DIR/unnecessary_lazy_eval.rs:104:13 | LL | let _ = deep.0.get_or_insert_with(|| 2); | ^^^^^^^------------------------ @@ -194,7 +210,7 @@ LL | let _ = deep.0.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:102:13 + --> $DIR/unnecessary_lazy_eval.rs:105:13 | LL | let _ = deep.0.ok_or_else(|| 2); | ^^^^^^^---------------- @@ -202,7 +218,7 @@ LL | let _ = deep.0.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:132:28 + --> $DIR/unnecessary_lazy_eval.rs:135:28 | LL | let _: Option<usize> = None.or_else(|| Some(3)); | ^^^^^------------------- @@ -210,7 +226,7 @@ LL | let _: Option<usize> = None.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:133:13 + --> $DIR/unnecessary_lazy_eval.rs:136:13 | LL | let _ = deep.0.or_else(|| Some(3)); | ^^^^^^^------------------- @@ -218,7 +234,7 @@ LL | let _ = deep.0.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:134:13 + --> $DIR/unnecessary_lazy_eval.rs:137:13 | LL | let _ = opt.or_else(|| Some(3)); | ^^^^------------------- @@ -226,7 +242,7 @@ LL | let _ = opt.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:140:13 + --> $DIR/unnecessary_lazy_eval.rs:143:13 | LL | let _ = res2.unwrap_or_else(|_| 2); | ^^^^^--------------------- @@ -234,7 +250,7 @@ LL | let _ = res2.unwrap_or_else(|_| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:141:13 + --> $DIR/unnecessary_lazy_eval.rs:144:13 | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | ^^^^^---------------------------------- @@ -242,7 +258,7 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:142:13 + --> $DIR/unnecessary_lazy_eval.rs:145:13 | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | ^^^^^-------------------------------------- @@ -250,7 +266,7 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:164:35 + --> $DIR/unnecessary_lazy_eval.rs:167:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); | ^^^^-------------------- @@ -258,7 +274,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); | help: use `and(..)` instead: `and(Err(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:165:35 + --> $DIR/unnecessary_lazy_eval.rs:168:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); | ^^^^--------------------------------- @@ -266,7 +282,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); | help: use `and(..)` instead: `and(Err(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:166:35 + --> $DIR/unnecessary_lazy_eval.rs:169:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)); | ^^^^------------------------------------- @@ -274,7 +290,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)) | help: use `and(..)` instead: `and(Err(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:168:35 + --> $DIR/unnecessary_lazy_eval.rs:171:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); | ^^^^------------------ @@ -282,7 +298,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); | help: use `or(..)` instead: `or(Ok(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:169:35 + --> $DIR/unnecessary_lazy_eval.rs:172:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); | ^^^^------------------------------- @@ -290,7 +306,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); | help: use `or(..)` instead: `or(Ok(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:170:35 + --> $DIR/unnecessary_lazy_eval.rs:173:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); | ^^^^----------------------------------- @@ -298,7 +314,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:171:35 + --> $DIR/unnecessary_lazy_eval.rs:174:35 | LL | let _: Result<usize, usize> = res. | ___________________________________^ @@ -312,5 +328,5 @@ LL | | or_else(|_| Ok(ext_str.some_field)); | | | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` -error: aborting due to 38 previous errors +error: aborting due to 40 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs index 33685bfb7..412d4aaaf 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs @@ -25,3 +25,8 @@ fn main() { let arr = [(Some(1),)]; Some(&0).and_then(|&i| arr[i].0); } + +fn issue11672() { + // Return type annotation helps type inference and removing it can break code + let _ = true.then(|| -> &[u8] { &[] }); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 27fa560d4..95b02be91 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -25,5 +25,13 @@ LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | | | help: use `unwrap_or(..)` instead: `unwrap_or(2)` -error: aborting due to 3 previous errors +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval_unfixable.rs:31:13 + | +LL | let _ = true.then(|| -> &[u8] { &[] }); + | ^^^^^------------------------- + | | + | help: use `then_some(..)` instead: `then_some({ &[] })` + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed index 87df1f8cb..b17343aa9 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed @@ -23,7 +23,7 @@ fn unwrap_option_none() { let _val: u16 = 234; let _val: u16 = 234; let _val: u16 = { 234 }; - let _val: u16 = { 234 }; + let _val: u16 = { 234 }; panic!(); panic!("this always happens"); @@ -31,7 +31,7 @@ fn unwrap_option_none() { 234; 234; { 234 }; - { 234 }; + { 234 }; } fn unwrap_result_ok() { diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr index 013907f59..4940091be 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr @@ -116,7 +116,7 @@ LL | let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); help: remove the `None` and `unwrap_or_else()` | LL - let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); -LL + let _val: u16 = { 234 }; +LL + let _val: u16 = { 234 }; | error: used `unwrap()` on `None` value @@ -187,7 +187,7 @@ LL | None::<u16>.unwrap_or_else(|| -> u16 { 234 }); help: remove the `None` and `unwrap_or_else()` | LL - None::<u16>.unwrap_or_else(|| -> u16 { 234 }); -LL + { 234 }; +LL + { 234 }; | error: used `unwrap()` on `Ok` value diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed index 67faabc53..2dd1d7466 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed @@ -1,4 +1,10 @@ -#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)] +#![allow( + clippy::needless_borrow, + clippy::needless_borrows_for_generic_args, + clippy::ptr_arg, + clippy::manual_async_fn, + clippy::needless_lifetimes +)] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] use std::borrow::Cow; @@ -506,3 +512,18 @@ mod issue_10033 { } } } + +mod issue_11952 { + use core::future::{Future, IntoFuture}; + + fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> { + async move { + let _y = y; + Ok(()) + } + } + + fn bar() { + IntoFuture::into_future(foo([], &0)); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs index 99f913642..17fad3340 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs @@ -1,4 +1,10 @@ -#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)] +#![allow( + clippy::needless_borrow, + clippy::needless_borrows_for_generic_args, + clippy::ptr_arg, + clippy::manual_async_fn, + clippy::needless_lifetimes +)] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] use std::borrow::Cow; @@ -506,3 +512,18 @@ mod issue_10033 { } } } + +mod issue_11952 { + use core::future::{Future, IntoFuture}; + + fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> { + async move { + let _y = y; + Ok(()) + } + } + + fn bar() { + IntoFuture::into_future(foo([].to_vec(), &0)); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr index d8971b51d..ad6fa422b 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr @@ -1,11 +1,11 @@ error: redundant clone - --> $DIR/unnecessary_to_owned.rs:148:64 + --> $DIR/unnecessary_to_owned.rs:154:64 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/unnecessary_to_owned.rs:148:20 + --> $DIR/unnecessary_to_owned.rs:154:20 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,55 +13,55 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()) = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> $DIR/unnecessary_to_owned.rs:149:40 + --> $DIR/unnecessary_to_owned.rs:155:40 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/unnecessary_to_owned.rs:149:21 + --> $DIR/unnecessary_to_owned.rs:155:21 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/unnecessary_to_owned.rs:150:48 + --> $DIR/unnecessary_to_owned.rs:156:48 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/unnecessary_to_owned.rs:150:19 + --> $DIR/unnecessary_to_owned.rs:156:19 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/unnecessary_to_owned.rs:151:35 + --> $DIR/unnecessary_to_owned.rs:157:35 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/unnecessary_to_owned.rs:151:18 + --> $DIR/unnecessary_to_owned.rs:157:18 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/unnecessary_to_owned.rs:152:39 + --> $DIR/unnecessary_to_owned.rs:158: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:152:20 + --> $DIR/unnecessary_to_owned.rs:158:20 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^^^^^^^^^ error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:57:36 + --> $DIR/unnecessary_to_owned.rs:63:36 | LL | require_c_str(&Cow::from(c_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this @@ -70,415 +70,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:58:19 + --> $DIR/unnecessary_to_owned.rs:64:19 | LL | require_c_str(&c_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_os_string` - --> $DIR/unnecessary_to_owned.rs:60:20 + --> $DIR/unnecessary_to_owned.rs:66:20 | LL | require_os_str(&os_str.to_os_string()); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:61:38 + --> $DIR/unnecessary_to_owned.rs:67:38 | LL | require_os_str(&Cow::from(os_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:62:20 + --> $DIR/unnecessary_to_owned.rs:68:20 | LL | require_os_str(&os_str.to_owned()); | ^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_path_buf` - --> $DIR/unnecessary_to_owned.rs:64:18 + --> $DIR/unnecessary_to_owned.rs:70:18 | LL | require_path(&path.to_path_buf()); | ^^^^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:65:34 + --> $DIR/unnecessary_to_owned.rs:71:34 | LL | require_path(&Cow::from(path).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:66:18 + --> $DIR/unnecessary_to_owned.rs:72:18 | LL | require_path(&path.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:68:17 + --> $DIR/unnecessary_to_owned.rs:74:17 | LL | require_str(&s.to_string()); | ^^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:69:30 + --> $DIR/unnecessary_to_owned.rs:75:30 | LL | require_str(&Cow::from(s).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:70:17 + --> $DIR/unnecessary_to_owned.rs:76:17 | LL | require_str(&s.to_owned()); | ^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:71:17 + --> $DIR/unnecessary_to_owned.rs:77:17 | LL | require_str(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:73:19 + --> $DIR/unnecessary_to_owned.rs:79:19 | LL | require_slice(&slice.to_vec()); | ^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:74:36 + --> $DIR/unnecessary_to_owned.rs:80:36 | LL | require_slice(&Cow::from(slice).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:75:19 + --> $DIR/unnecessary_to_owned.rs:81:19 | LL | require_slice(&array.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:76:19 + --> $DIR/unnecessary_to_owned.rs:82:19 | LL | require_slice(&array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:77:19 + --> $DIR/unnecessary_to_owned.rs:83:19 | LL | require_slice(&slice.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> $DIR/unnecessary_to_owned.rs:80:42 + --> $DIR/unnecessary_to_owned.rs:86:42 | LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:83:25 + --> $DIR/unnecessary_to_owned.rs:89:25 | LL | require_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:84:26 + --> $DIR/unnecessary_to_owned.rs:90:26 | LL | require_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:85:24 + --> $DIR/unnecessary_to_owned.rs:91:24 | LL | require_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:86:23 + --> $DIR/unnecessary_to_owned.rs:92:23 | LL | require_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:87:25 + --> $DIR/unnecessary_to_owned.rs:93:25 | LL | require_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:89:30 + --> $DIR/unnecessary_to_owned.rs:95:30 | LL | require_impl_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:90:31 + --> $DIR/unnecessary_to_owned.rs:96:31 | LL | require_impl_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:91:29 + --> $DIR/unnecessary_to_owned.rs:97:29 | LL | require_impl_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:92:28 + --> $DIR/unnecessary_to_owned.rs:98:28 | LL | require_impl_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:93:30 + --> $DIR/unnecessary_to_owned.rs:99:30 | LL | require_impl_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:95:29 + --> $DIR/unnecessary_to_owned.rs:101:29 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:95:43 + --> $DIR/unnecessary_to_owned.rs:101:43 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:96:29 + --> $DIR/unnecessary_to_owned.rs:102:29 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:96:47 + --> $DIR/unnecessary_to_owned.rs:102:47 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:98:26 + --> $DIR/unnecessary_to_owned.rs:104:26 | LL | require_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:99:27 + --> $DIR/unnecessary_to_owned.rs:105:27 | LL | require_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:100:25 + --> $DIR/unnecessary_to_owned.rs:106:25 | LL | require_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:101:24 + --> $DIR/unnecessary_to_owned.rs:107:24 | LL | require_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:102:24 + --> $DIR/unnecessary_to_owned.rs:108:24 | LL | require_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:103:26 + --> $DIR/unnecessary_to_owned.rs:109:26 | LL | require_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:104:26 + --> $DIR/unnecessary_to_owned.rs:110:26 | LL | require_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:105:26 + --> $DIR/unnecessary_to_owned.rs:111:26 | LL | require_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:107:31 + --> $DIR/unnecessary_to_owned.rs:113:31 | LL | require_impl_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:108:32 + --> $DIR/unnecessary_to_owned.rs:114:32 | LL | require_impl_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:109:30 + --> $DIR/unnecessary_to_owned.rs:115:30 | LL | require_impl_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:110:29 + --> $DIR/unnecessary_to_owned.rs:116:29 | LL | require_impl_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:111:29 + --> $DIR/unnecessary_to_owned.rs:117:29 | LL | require_impl_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:112:31 + --> $DIR/unnecessary_to_owned.rs:118:31 | LL | require_impl_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:113:31 + --> $DIR/unnecessary_to_owned.rs:119:31 | LL | require_impl_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:114:31 + --> $DIR/unnecessary_to_owned.rs:120:31 | LL | require_impl_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:116:30 + --> $DIR/unnecessary_to_owned.rs:122:30 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:116:44 + --> $DIR/unnecessary_to_owned.rs:122:44 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:117:30 + --> $DIR/unnecessary_to_owned.rs:123:30 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:117:44 + --> $DIR/unnecessary_to_owned.rs:123:44 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:118:30 + --> $DIR/unnecessary_to_owned.rs:124:30 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:118:44 + --> $DIR/unnecessary_to_owned.rs:124:44 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:119:30 + --> $DIR/unnecessary_to_owned.rs:125:30 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:119:48 + --> $DIR/unnecessary_to_owned.rs:125:48 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:120:30 + --> $DIR/unnecessary_to_owned.rs:126:30 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:120:52 + --> $DIR/unnecessary_to_owned.rs:126:52 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:121:30 + --> $DIR/unnecessary_to_owned.rs:127:30 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:121:48 + --> $DIR/unnecessary_to_owned.rs:127:48 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:123:20 + --> $DIR/unnecessary_to_owned.rs:129:20 | LL | let _ = x.join(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:125:13 + --> $DIR/unnecessary_to_owned.rs:131:13 | LL | let _ = slice.to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:126:13 + --> $DIR/unnecessary_to_owned.rs:132:13 | LL | let _ = slice.to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:127:13 + --> $DIR/unnecessary_to_owned.rs:133:13 | LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:128:13 + --> $DIR/unnecessary_to_owned.rs:134:13 | LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:130:13 + --> $DIR/unnecessary_to_owned.rs:136:13 | LL | let _ = IntoIterator::into_iter(slice.to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:131:13 + --> $DIR/unnecessary_to_owned.rs:137:13 | LL | let _ = IntoIterator::into_iter(slice.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:132:13 + --> $DIR/unnecessary_to_owned.rs:138:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> $DIR/unnecessary_to_owned.rs:133:13 + --> $DIR/unnecessary_to_owned.rs:139:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:195:14 + --> $DIR/unnecessary_to_owned.rs:201:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -494,28 +494,34 @@ LL + let path = match get_file_path(t) { | error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:218:14 + --> $DIR/unnecessary_to_owned.rs:224:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()` error: unnecessary use of `to_vec` - --> $DIR/unnecessary_to_owned.rs:223:14 + --> $DIR/unnecessary_to_owned.rs:229:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:270:24 + --> $DIR/unnecessary_to_owned.rs:276:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` error: unnecessary use of `to_string` - --> $DIR/unnecessary_to_owned.rs:378:12 + --> $DIR/unnecessary_to_owned.rs:384:12 | LL | id("abc".to_string()) | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` -error: aborting due to 79 previous errors +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:527:37 + | +LL | IntoFuture::into_future(foo([].to_vec(), &0)); + | ^^^^^^^^^^^ help: use: `[]` + +error: aborting due to 80 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs index 373b18470..5ad117eb8 100644 --- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs +++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)] #![warn(clippy::unnecessary_safety_doc)] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs index 71722e9af..7ec8a3adb 100644 --- a/src/tools/clippy/tests/ui/unused_async.rs +++ b/src/tools/clippy/tests/ui/unused_async.rs @@ -1,5 +1,4 @@ #![warn(clippy::unused_async)] -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr index 077e8cacc..c97a76a55 100644 --- a/src/tools/clippy/tests/ui/unused_async.stderr +++ b/src/tools/clippy/tests/ui/unused_async.stderr @@ -1,5 +1,5 @@ error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:13:5 + --> $DIR/unused_async.rs:12:5 | LL | / async fn async_block_await() { LL | | @@ -11,7 +11,7 @@ LL | | } | = help: consider removing the `async` from this function note: `await` used in an async block, which does not require the enclosing function to be `async` - --> $DIR/unused_async.rs:16:23 + --> $DIR/unused_async.rs:15:23 | LL | ready(()).await; | ^^^^^ @@ -19,7 +19,7 @@ LL | ready(()).await; = help: to override `-D warnings` add `#[allow(clippy::unused_async)]` error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:46:5 + --> $DIR/unused_async.rs:45:5 | LL | async fn f3() {} | ^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | async fn f3() {} = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:59:1 + --> $DIR/unused_async.rs:58:1 | LL | / async fn foo() -> i32 { LL | | @@ -38,7 +38,7 @@ LL | | } = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:71:5 + --> $DIR/unused_async.rs:70:5 | LL | / async fn unused(&self) -> i32 { LL | | diff --git a/src/tools/clippy/tests/ui/unused_enumerate_index.fixed b/src/tools/clippy/tests/ui/unused_enumerate_index.fixed new file mode 100644 index 000000000..d079807ab --- /dev/null +++ b/src/tools/clippy/tests/ui/unused_enumerate_index.fixed @@ -0,0 +1,58 @@ +#![allow(unused)] +#![warn(clippy::unused_enumerate_index)] + +use std::iter::Enumerate; + +fn main() { + let v = [1, 2, 3]; + for x in v.iter() { + println!("{x}"); + } + + struct Dummy1; + impl Dummy1 { + fn enumerate(self) -> Vec<usize> { + vec![] + } + } + let dummy = Dummy1; + for x in dummy.enumerate() { + println!("{x}"); + } + + struct Dummy2; + impl Dummy2 { + fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> { + vec![1, 2].into_iter().enumerate() + } + } + let dummy = Dummy2; + for (_, x) in dummy.enumerate() { + println!("{x}"); + } + + let mut with_used_iterator = [1, 2, 3].into_iter().enumerate(); + with_used_iterator.next(); + for (_, x) in with_used_iterator { + println!("{x}"); + } + + struct Dummy3(std::vec::IntoIter<usize>); + + impl Iterator for Dummy3 { + type Item = usize; + + fn next(&mut self) -> Option<Self::Item> { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } + } + + let dummy = Dummy3(vec![1, 2, 3].into_iter()); + for x in dummy { + println!("{x}"); + } +} diff --git a/src/tools/clippy/tests/ui/unused_enumerate_index.rs b/src/tools/clippy/tests/ui/unused_enumerate_index.rs new file mode 100644 index 000000000..2d524da76 --- /dev/null +++ b/src/tools/clippy/tests/ui/unused_enumerate_index.rs @@ -0,0 +1,58 @@ +#![allow(unused)] +#![warn(clippy::unused_enumerate_index)] + +use std::iter::Enumerate; + +fn main() { + let v = [1, 2, 3]; + for (_, x) in v.iter().enumerate() { + println!("{x}"); + } + + struct Dummy1; + impl Dummy1 { + fn enumerate(self) -> Vec<usize> { + vec![] + } + } + let dummy = Dummy1; + for x in dummy.enumerate() { + println!("{x}"); + } + + struct Dummy2; + impl Dummy2 { + fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> { + vec![1, 2].into_iter().enumerate() + } + } + let dummy = Dummy2; + for (_, x) in dummy.enumerate() { + println!("{x}"); + } + + let mut with_used_iterator = [1, 2, 3].into_iter().enumerate(); + with_used_iterator.next(); + for (_, x) in with_used_iterator { + println!("{x}"); + } + + struct Dummy3(std::vec::IntoIter<usize>); + + impl Iterator for Dummy3 { + type Item = usize; + + fn next(&mut self) -> Option<Self::Item> { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } + } + + let dummy = Dummy3(vec![1, 2, 3].into_iter()); + for (_, x) in dummy.enumerate() { + println!("{x}"); + } +} diff --git a/src/tools/clippy/tests/ui/unused_enumerate_index.stderr b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr new file mode 100644 index 000000000..b575fbbc4 --- /dev/null +++ b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr @@ -0,0 +1,26 @@ +error: you seem to use `.enumerate()` and immediately discard the index + --> $DIR/unused_enumerate_index.rs:8:19 + | +LL | for (_, x) in v.iter().enumerate() { + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unused-enumerate-index` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]` +help: remove the `.enumerate()` call + | +LL | for x in v.iter() { + | ~ ~~~~~~~~ + +error: you seem to use `.enumerate()` and immediately discard the index + --> $DIR/unused_enumerate_index.rs:55:19 + | +LL | for (_, x) in dummy.enumerate() { + | ^^^^^^^^^^^^^^^^^ + | +help: remove the `.enumerate()` call + | +LL | for x in dummy { + | ~ ~~~~~ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.rs b/src/tools/clippy/tests/ui/useless_conversion_try.rs index a5feefbe0..803d3b39f 100644 --- a/src/tools/clippy/tests/ui/useless_conversion_try.rs +++ b/src/tools/clippy/tests/ui/useless_conversion_try.rs @@ -1,5 +1,5 @@ #![deny(clippy::useless_conversion)] -#![allow(clippy::needless_if)] +#![allow(clippy::needless_if, clippy::unnecessary_fallible_conversions)] fn test_generic<T: Copy>(val: T) -> T { let _ = T::try_from(val).unwrap(); diff --git a/src/tools/clippy/tests/ui/waker_clone_wake.fixed b/src/tools/clippy/tests/ui/waker_clone_wake.fixed new file mode 100644 index 000000000..9c02b9a90 --- /dev/null +++ b/src/tools/clippy/tests/ui/waker_clone_wake.fixed @@ -0,0 +1,29 @@ +#[derive(Clone)] +pub struct Custom; + +impl Custom { + pub fn wake(self) {} +} + +macro_rules! mac { + ($cx:ident) => { + $cx.waker() + }; +} + +pub fn wake(cx: &mut std::task::Context) { + cx.waker().wake_by_ref(); + + mac!(cx).wake_by_ref(); +} + +pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { + c.clone().wake(); + + let w = cx.waker().clone(); + w.wake(); + + cx.waker().clone().wake_by_ref(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/waker_clone_wake.rs b/src/tools/clippy/tests/ui/waker_clone_wake.rs new file mode 100644 index 000000000..edc3bbd8f --- /dev/null +++ b/src/tools/clippy/tests/ui/waker_clone_wake.rs @@ -0,0 +1,29 @@ +#[derive(Clone)] +pub struct Custom; + +impl Custom { + pub fn wake(self) {} +} + +macro_rules! mac { + ($cx:ident) => { + $cx.waker() + }; +} + +pub fn wake(cx: &mut std::task::Context) { + cx.waker().clone().wake(); + + mac!(cx).clone().wake(); +} + +pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { + c.clone().wake(); + + let w = cx.waker().clone(); + w.wake(); + + cx.waker().clone().wake_by_ref(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/waker_clone_wake.stderr b/src/tools/clippy/tests/ui/waker_clone_wake.stderr new file mode 100644 index 000000000..f1abf4d9c --- /dev/null +++ b/src/tools/clippy/tests/ui/waker_clone_wake.stderr @@ -0,0 +1,17 @@ +error: cloning a `Waker` only to wake it + --> $DIR/waker_clone_wake.rs:15:5 + | +LL | cx.waker().clone().wake(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `cx.waker().wake_by_ref()` + | + = note: `-D clippy::waker-clone-wake` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::waker_clone_wake)]` + +error: cloning a `Waker` only to wake it + --> $DIR/waker_clone_wake.rs:17:5 + | +LL | mac!(cx).clone().wake(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `mac!(cx).wake_by_ref()` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed index 2828f9d04..6fdd728b9 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed @@ -69,6 +69,34 @@ mod struct_mod { } } +// issue 9942 +mod underscore_mod { + // allow use of `deref` so that `clippy --fix` includes `Deref`. + #![allow(noop_method_call)] + + mod exports_underscore { + pub use std::ops::Deref as _; + pub fn dummy() {} + } + + mod exports_underscore_ish { + pub use std::ops::Deref as _Deref; + pub fn dummy() {} + } + + fn does_not_lint() { + use self::exports_underscore::*; + let _ = (&0).deref(); + dummy(); + } + + fn does_lint() { + use self::exports_underscore_ish::{_Deref, dummy}; + let _ = (&0).deref(); + dummy(); + } +} + fn main() { foo(); multi_foo(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports.rs b/src/tools/clippy/tests/ui/wildcard_imports.rs index cbe70e505..20e06d4b3 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.rs +++ b/src/tools/clippy/tests/ui/wildcard_imports.rs @@ -69,6 +69,34 @@ mod struct_mod { } } +// issue 9942 +mod underscore_mod { + // allow use of `deref` so that `clippy --fix` includes `Deref`. + #![allow(noop_method_call)] + + mod exports_underscore { + pub use std::ops::Deref as _; + pub fn dummy() {} + } + + mod exports_underscore_ish { + pub use std::ops::Deref as _Deref; + pub fn dummy() {} + } + + fn does_not_lint() { + use self::exports_underscore::*; + let _ = (&0).deref(); + dummy(); + } + + fn does_lint() { + use self::exports_underscore_ish::*; + let _ = (&0).deref(); + dummy(); + } +} + fn main() { foo(); multi_foo(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr index 3c750815b..01a541477 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr @@ -38,55 +38,61 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:97:13 + --> $DIR/wildcard_imports.rs:94:13 + | +LL | use self::exports_underscore_ish::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `self::exports_underscore_ish::{_Deref, dummy}` + +error: usage of wildcard import + --> $DIR/wildcard_imports.rs:125:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:103:75 + --> $DIR/wildcard_imports.rs:131:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:104:13 + --> $DIR/wildcard_imports.rs:132:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:116:20 + --> $DIR/wildcard_imports.rs:144:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:116:30 + --> $DIR/wildcard_imports.rs:144:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:123:13 + --> $DIR/wildcard_imports.rs:151:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:152:9 + --> $DIR/wildcard_imports.rs:180:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:161:9 + --> $DIR/wildcard_imports.rs:189:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:162:9 + --> $DIR/wildcard_imports.rs:190:9 | LL | use crate:: fn_mod:: | _________^ @@ -94,40 +100,40 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:173:13 + --> $DIR/wildcard_imports.rs:201:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:208:17 + --> $DIR/wildcard_imports.rs:236:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:216:13 + --> $DIR/wildcard_imports.rs:244:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:225:17 + --> $DIR/wildcard_imports.rs:253:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:234:13 + --> $DIR/wildcard_imports.rs:262:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:242:13 + --> $DIR/wildcard_imports.rs:270:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` -error: aborting due to 21 previous errors +error: aborting due to 22 previous errors diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed index b27281fa2..6a9fe007d 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed @@ -64,6 +64,34 @@ mod struct_mod { } } +// issue 9942 +mod underscore_mod { + // allow use of `deref` so that `clippy --fix` includes `Deref`. + #![allow(noop_method_call)] + + mod exports_underscore { + pub use std::ops::Deref as _; + pub fn dummy() {} + } + + mod exports_underscore_ish { + pub use std::ops::Deref as _Deref; + pub fn dummy() {} + } + + fn does_not_lint() { + use exports_underscore::*; + let _ = (&0).deref(); + dummy(); + } + + fn does_lint() { + use exports_underscore_ish::{_Deref, dummy}; + let _ = (&0).deref(); + dummy(); + } +} + fn main() { foo(); multi_foo(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr index 709a665d6..e39f240a4 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr @@ -38,55 +38,61 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:91:13 + --> $DIR/wildcard_imports_2021.rs:89:13 + | +LL | use exports_underscore_ish::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}` + +error: usage of wildcard import + --> $DIR/wildcard_imports_2021.rs:119:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:97:75 + --> $DIR/wildcard_imports_2021.rs:125:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:98:13 + --> $DIR/wildcard_imports_2021.rs:126:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:110:20 + --> $DIR/wildcard_imports_2021.rs:138:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:110:30 + --> $DIR/wildcard_imports_2021.rs:138:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:117:13 + --> $DIR/wildcard_imports_2021.rs:145:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:146:9 + --> $DIR/wildcard_imports_2021.rs:174:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:155:9 + --> $DIR/wildcard_imports_2021.rs:183:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:156:9 + --> $DIR/wildcard_imports_2021.rs:184:9 | LL | use crate:: fn_mod:: | _________^ @@ -94,40 +100,40 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:167:13 + --> $DIR/wildcard_imports_2021.rs:195:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:202:17 + --> $DIR/wildcard_imports_2021.rs:230:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:210:13 + --> $DIR/wildcard_imports_2021.rs:238:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:219:17 + --> $DIR/wildcard_imports_2021.rs:247:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:228:13 + --> $DIR/wildcard_imports_2021.rs:256:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:236:13 + --> $DIR/wildcard_imports_2021.rs:264:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` -error: aborting due to 21 previous errors +error: aborting due to 22 previous errors diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed index b27281fa2..6a9fe007d 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed @@ -64,6 +64,34 @@ mod struct_mod { } } +// issue 9942 +mod underscore_mod { + // allow use of `deref` so that `clippy --fix` includes `Deref`. + #![allow(noop_method_call)] + + mod exports_underscore { + pub use std::ops::Deref as _; + pub fn dummy() {} + } + + mod exports_underscore_ish { + pub use std::ops::Deref as _Deref; + pub fn dummy() {} + } + + fn does_not_lint() { + use exports_underscore::*; + let _ = (&0).deref(); + dummy(); + } + + fn does_lint() { + use exports_underscore_ish::{_Deref, dummy}; + let _ = (&0).deref(); + dummy(); + } +} + fn main() { foo(); multi_foo(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr index 709a665d6..e39f240a4 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr @@ -38,55 +38,61 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:91:13 + --> $DIR/wildcard_imports_2021.rs:89:13 + | +LL | use exports_underscore_ish::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}` + +error: usage of wildcard import + --> $DIR/wildcard_imports_2021.rs:119:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:97:75 + --> $DIR/wildcard_imports_2021.rs:125:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:98:13 + --> $DIR/wildcard_imports_2021.rs:126:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:110:20 + --> $DIR/wildcard_imports_2021.rs:138:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:110:30 + --> $DIR/wildcard_imports_2021.rs:138:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:117:13 + --> $DIR/wildcard_imports_2021.rs:145:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:146:9 + --> $DIR/wildcard_imports_2021.rs:174:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:155:9 + --> $DIR/wildcard_imports_2021.rs:183:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:156:9 + --> $DIR/wildcard_imports_2021.rs:184:9 | LL | use crate:: fn_mod:: | _________^ @@ -94,40 +100,40 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:167:13 + --> $DIR/wildcard_imports_2021.rs:195:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:202:17 + --> $DIR/wildcard_imports_2021.rs:230:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:210:13 + --> $DIR/wildcard_imports_2021.rs:238:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:219:17 + --> $DIR/wildcard_imports_2021.rs:247:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:228:13 + --> $DIR/wildcard_imports_2021.rs:256:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:236:13 + --> $DIR/wildcard_imports_2021.rs:264:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` -error: aborting due to 21 previous errors +error: aborting due to 22 previous errors diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs index 7dd2103ec..18ebc0f51 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs @@ -64,6 +64,34 @@ mod struct_mod { } } +// issue 9942 +mod underscore_mod { + // allow use of `deref` so that `clippy --fix` includes `Deref`. + #![allow(noop_method_call)] + + mod exports_underscore { + pub use std::ops::Deref as _; + pub fn dummy() {} + } + + mod exports_underscore_ish { + pub use std::ops::Deref as _Deref; + pub fn dummy() {} + } + + fn does_not_lint() { + use exports_underscore::*; + let _ = (&0).deref(); + dummy(); + } + + fn does_lint() { + use exports_underscore_ish::*; + let _ = (&0).deref(); + dummy(); + } +} + fn main() { foo(); multi_foo(); diff --git a/src/tools/clippy/tests/ui/write_literal.fixed b/src/tools/clippy/tests/ui/write_literal.fixed index ee577574d..3d216b76c 100644 --- a/src/tools/clippy/tests/ui/write_literal.fixed +++ b/src/tools/clippy/tests/ui/write_literal.fixed @@ -43,16 +43,22 @@ fn main() { // throw a warning writeln!(v, "hello world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string writeln!(v, "world hello"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // named args shouldn't change anything either writeln!(v, "hello world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string writeln!(v, "world hello"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string + + // #10128 + writeln!(v, "hello {0} world", 2); + //~^ ERROR: literal with an empty format string + writeln!(v, "world {0} hello", 2); + //~^ ERROR: literal with an empty format string + writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4); + //~^ ERROR: literal with an empty format string + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); + //~^ ERROR: literal with an empty format string } diff --git a/src/tools/clippy/tests/ui/write_literal.rs b/src/tools/clippy/tests/ui/write_literal.rs index 588e8fd41..79d6daa2e 100644 --- a/src/tools/clippy/tests/ui/write_literal.rs +++ b/src/tools/clippy/tests/ui/write_literal.rs @@ -43,16 +43,22 @@ fn main() { // throw a warning writeln!(v, "{0} {1}", "hello", "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string writeln!(v, "{1} {0}", "hello", "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // named args shouldn't change anything either writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string + + // #10128 + writeln!(v, "{0} {1} {2}", "hello", 2, "world"); + //~^ ERROR: literal with an empty format string + writeln!(v, "{2} {1} {0}", "hello", 2, "world"); + //~^ ERROR: literal with an empty format string + writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); + //~^ ERROR: literal with an empty format string + writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); + //~^ ERROR: literal with an empty format string } diff --git a/src/tools/clippy/tests/ui/write_literal.stderr b/src/tools/clippy/tests/ui/write_literal.stderr index 372a54cf7..ee0d536e9 100644 --- a/src/tools/clippy/tests/ui/write_literal.stderr +++ b/src/tools/clippy/tests/ui/write_literal.stderr @@ -52,96 +52,96 @@ error: literal with an empty format string --> $DIR/write_literal.rs:44:28 | LL | writeln!(v, "{0} {1}", "hello", "world"); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^ | help: try | LL - writeln!(v, "{0} {1}", "hello", "world"); -LL + writeln!(v, "hello {1}", "world"); +LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> $DIR/write_literal.rs:44:37 + --> $DIR/write_literal.rs:46:28 | -LL | writeln!(v, "{0} {1}", "hello", "world"); - | ^^^^^^^ +LL | writeln!(v, "{1} {0}", "hello", "world"); + | ^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{0} {1}", "hello", "world"); -LL + writeln!(v, "{0} world", "hello"); +LL - writeln!(v, "{1} {0}", "hello", "world"); +LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> $DIR/write_literal.rs:47:37 + --> $DIR/write_literal.rs:50:38 | -LL | writeln!(v, "{1} {0}", "hello", "world"); - | ^^^^^^^ +LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); + | ^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{1} {0}", "hello", "world"); -LL + writeln!(v, "world {0}", "hello"); +LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); +LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> $DIR/write_literal.rs:47:28 + --> $DIR/write_literal.rs:52:38 | -LL | writeln!(v, "{1} {0}", "hello", "world"); - | ^^^^^^^ +LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); + | ^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{1} {0}", "hello", "world"); -LL + writeln!(v, "{1} hello", "world"); +LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); +LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> $DIR/write_literal.rs:52:38 + --> $DIR/write_literal.rs:56:32 | -LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | writeln!(v, "{0} {1} {2}", "hello", 2, "world"); + | ^^^^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); -LL + writeln!(v, "hello {bar}", bar = "world"); +LL - writeln!(v, "{0} {1} {2}", "hello", 2, "world"); +LL + writeln!(v, "hello {0} world", 2); | error: literal with an empty format string - --> $DIR/write_literal.rs:52:53 + --> $DIR/write_literal.rs:58:32 | -LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | writeln!(v, "{2} {1} {0}", "hello", 2, "world"); + | ^^^^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); -LL + writeln!(v, "{foo} world", foo = "hello"); +LL - writeln!(v, "{2} {1} {0}", "hello", 2, "world"); +LL + writeln!(v, "world {0} hello", 2); | error: literal with an empty format string - --> $DIR/write_literal.rs:55:53 + --> $DIR/write_literal.rs:60:39 | -LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); + | ^^^^^^^ | help: try | -LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); -LL + writeln!(v, "world {foo}", foo = "hello"); +LL - writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); +LL + writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4); | error: literal with an empty format string - --> $DIR/write_literal.rs:55:38 + --> $DIR/write_literal.rs:62:41 | -LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); - | ^^^^^^^ +LL | writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); + | ^^^^^^^^^^^^^^^^^^^^^^ | help: try | -LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); -LL + writeln!(v, "{bar} hello", bar = "world"); +LL - writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); +LL + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); | error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/write_literal_2.rs b/src/tools/clippy/tests/ui/write_literal_2.rs index aa0c13c13..b2ed552d4 100644 --- a/src/tools/clippy/tests/ui/write_literal_2.rs +++ b/src/tools/clippy/tests/ui/write_literal_2.rs @@ -1,6 +1,6 @@ //@no-rustfix: overlapping suggestions #![allow(unused_must_use)] -#![warn(clippy::needless_raw_strings, clippy::write_literal)] +#![warn(clippy::write_literal)] use std::io::Write; @@ -11,9 +11,7 @@ fn main() { //~^ ERROR: literal with an empty format string //~| NOTE: `-D clippy::write-literal` implied by `-D warnings` writeln!(v, r"{}", r"{hello}"); - //~^ ERROR: unnecessary raw string literal - //~| NOTE: `-D clippy::needless-raw-strings` implied by `-D warnings` - //~| ERROR: literal with an empty format string + //~^ ERROR: literal with an empty format string writeln!(v, "{}", '\''); //~^ ERROR: literal with an empty format string writeln!(v, "{}", '"'); @@ -26,17 +24,14 @@ fn main() { v, "some {}", "hello \ - //~^ ERROR: literal with an empty format string - world!" + world!", + //~^^ ERROR: literal with an empty format string ); writeln!( v, "some {}\ {} \\ {}", - "1", - "2", - "3", - //~^ ERROR: literal with an empty format string + "1", "2", "3", ); writeln!(v, "{}", "\\"); //~^ ERROR: literal with an empty format string @@ -51,7 +46,6 @@ fn main() { // hard mode writeln!(v, r#"{}{}"#, '#', '"'); //~^ ERROR: literal with an empty format string - //~| ERROR: literal with an empty format string // should not lint writeln!(v, r"{}", "\r"); } diff --git a/src/tools/clippy/tests/ui/write_literal_2.stderr b/src/tools/clippy/tests/ui/write_literal_2.stderr index 6d382a267..81ef49de0 100644 --- a/src/tools/clippy/tests/ui/write_literal_2.stderr +++ b/src/tools/clippy/tests/ui/write_literal_2.stderr @@ -1,14 +1,3 @@ -error: unnecessary raw string literal - --> $DIR/write_literal_2.rs:13:24 - | -LL | writeln!(v, r"{}", r"{hello}"); - | -^^^^^^^^^ - | | - | help: use a string literal instead: `"{hello}"` - | - = note: `-D clippy::needless-raw-strings` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]` - error: literal with an empty format string --> $DIR/write_literal_2.rs:10:23 | @@ -36,7 +25,7 @@ LL + writeln!(v, r"{{hello}}"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:17:23 + --> $DIR/write_literal_2.rs:15:23 | LL | writeln!(v, "{}", '\''); | ^^^^ @@ -48,7 +37,7 @@ LL + writeln!(v, "'"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:19:23 + --> $DIR/write_literal_2.rs:17:23 | LL | writeln!(v, "{}", '"'); | ^^^ @@ -60,13 +49,13 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:21:24 + --> $DIR/write_literal_2.rs:19:24 | LL | writeln!(v, r"{}", '"'); | ^^^ error: literal with an empty format string - --> $DIR/write_literal_2.rs:23:24 + --> $DIR/write_literal_2.rs:21:24 | LL | writeln!(v, r"{}", '\''); | ^^^^ @@ -78,59 +67,32 @@ LL + writeln!(v, r"'"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:28:9 + --> $DIR/write_literal_2.rs:26:9 | LL | / "hello \ -LL | | -LL | | world!" +LL | | world!", | |_______________^ | help: try | LL ~ "some hello \ -LL + -LL ~ world!" +LL ~ world!", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:36:9 + --> $DIR/write_literal_2.rs:34:9 | -LL | "1", - | ^^^ +LL | "1", "2", "3", + | ^^^^^^^^^^^^^ | help: try | LL ~ "some 1\ -LL ~ {} \\ {}", +LL ~ 2 \\ 3", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:37:9 - | -LL | "2", - | ^^^ - | -help: try - | -LL ~ 2 \\ {}", -LL ~ "1", - | - -error: literal with an empty format string - --> $DIR/write_literal_2.rs:38:9 - | -LL | "3", - | ^^^ - | -help: try - | -LL ~ {} \\ 3", -LL | "1", -LL ~ "2", - | - -error: literal with an empty format string - --> $DIR/write_literal_2.rs:41:23 + --> $DIR/write_literal_2.rs:36:23 | LL | writeln!(v, "{}", "\\"); | ^^^^ @@ -142,7 +104,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:43:24 + --> $DIR/write_literal_2.rs:38:24 | LL | writeln!(v, r"{}", "\\"); | ^^^^ @@ -154,7 +116,7 @@ LL + writeln!(v, r"\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:45:26 + --> $DIR/write_literal_2.rs:40:26 | LL | writeln!(v, r#"{}"#, "\\"); | ^^^^ @@ -166,7 +128,7 @@ LL + writeln!(v, r#"\"#); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:47:23 + --> $DIR/write_literal_2.rs:42:23 | LL | writeln!(v, "{}", r"\"); | ^^^^ @@ -178,7 +140,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:49:23 + --> $DIR/write_literal_2.rs:44:23 | LL | writeln!(v, "{}", "\r"); | ^^^^ @@ -190,16 +152,10 @@ LL + writeln!(v, "\r"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:52:28 - | -LL | writeln!(v, r#"{}{}"#, '#', '"'); - | ^^^ - -error: literal with an empty format string - --> $DIR/write_literal_2.rs:52:33 + --> $DIR/write_literal_2.rs:47:28 | LL | writeln!(v, r#"{}{}"#, '#', '"'); - | ^^^ + | ^^^^^^^^ -error: aborting due to 18 previous errors +error: aborting due to 14 previous errors diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs index c721e9969..eba5405e6 100644 --- a/src/tools/clippy/tests/versioncheck.rs +++ b/src/tools/clippy/tests/versioncheck.rs @@ -26,6 +26,7 @@ fn consistent_clippy_crate_versions() { let paths = [ "declare_clippy_lint/Cargo.toml", + "clippy_config/Cargo.toml", "clippy_lints/Cargo.toml", "clippy_utils/Cargo.toml", ]; |