From 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:50 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- .../clippy/tests/ui-internal/custom_ice_message.rs | 3 +- .../tests/ui-internal/custom_ice_message.stderr | 4 +- .../tests/ui-toml/expect_used/expect_used.rs | 12 + .../ui-toml/pub_crate_missing_docs/clippy.toml | 1 + .../pub_crate_missing_doc.rs | 59 +++ .../pub_crate_missing_doc.stderr | 52 ++ .../toml_unknown_key/conf_unknown_key.stderr | 1 + .../tests/ui-toml/unwrap_used/unwrap_used.rs | 6 + .../tests/ui-toml/unwrap_used/unwrap_used.stderr | 10 +- .../clippy/tests/ui/arithmetic_side_effects.rs | 27 + .../clippy/tests/ui/arithmetic_side_effects.stderr | 198 ++++---- src/tools/clippy/tests/ui/auxiliary/macro_rules.rs | 19 + .../clippy/tests/ui/bool_assert_comparison.fixed | 171 +++++++ .../clippy/tests/ui/bool_assert_comparison.rs | 53 +- .../clippy/tests/ui/bool_assert_comparison.stderr | 353 +++++++++++-- src/tools/clippy/tests/ui/box_default.fixed | 18 + src/tools/clippy/tests/ui/box_default.rs | 18 + src/tools/clippy/tests/ui/box_default.stderr | 14 +- src/tools/clippy/tests/ui/bytes_nth.fixed | 6 +- src/tools/clippy/tests/ui/bytes_nth.rs | 2 +- src/tools/clippy/tests/ui/bytes_nth.stderr | 10 +- src/tools/clippy/tests/ui/cast.rs | 1 + src/tools/clippy/tests/ui/cast.stderr | 163 +++++- src/tools/clippy/tests/ui/cast_size.stderr | 53 ++ src/tools/clippy/tests/ui/crashes/ice-2774.stderr | 5 + .../clippy/tests/ui/crashes/ice-rust-107877.rs | 17 + .../crashes/needless_lifetimes_impl_trait.stderr | 5 + .../crashes/needless_pass_by_value-w-late-bound.rs | 9 + .../needless_pass_by_value-w-late-bound.stderr | 15 + src/tools/clippy/tests/ui/doc/doc-fixable.fixed | 2 +- src/tools/clippy/tests/ui/doc/doc-fixable.rs | 4 +- src/tools/clippy/tests/ui/doc/doc-fixable.stderr | 24 +- src/tools/clippy/tests/ui/entry.fixed | 14 + src/tools/clippy/tests/ui/entry.rs | 14 + .../clippy/tests/ui/explicit_auto_deref.fixed | 14 + src/tools/clippy/tests/ui/explicit_auto_deref.rs | 14 + .../tests/ui/extra_unused_type_parameters.rs | 110 +++++ .../tests/ui/extra_unused_type_parameters.stderr | 75 +++ src/tools/clippy/tests/ui/format.fixed | 6 + src/tools/clippy/tests/ui/format.rs | 6 + src/tools/clippy/tests/ui/format.stderr | 30 +- src/tools/clippy/tests/ui/impl_trait_in_params.rs | 17 + .../clippy/tests/ui/impl_trait_in_params.stderr | 25 + src/tools/clippy/tests/ui/large_digit_groups.fixed | 4 +- .../clippy/tests/ui/large_digit_groups.stderr | 20 +- src/tools/clippy/tests/ui/len_without_is_empty.rs | 46 ++ .../clippy/tests/ui/let_underscore_untyped.rs | 54 ++ .../clippy/tests/ui/let_underscore_untyped.stderr | 51 ++ src/tools/clippy/tests/ui/literals.stderr | 10 +- .../tests/ui/manual_assert.edition2018.fixed | 35 +- .../tests/ui/manual_assert.edition2018.stderr | 67 ++- src/tools/clippy/tests/ui/manual_let_else.rs | 11 + src/tools/clippy/tests/ui/manual_let_else_match.rs | 29 +- .../clippy/tests/ui/manual_let_else_match.stderr | 15 +- .../clippy/tests/ui/map_flatten_fixable.fixed | 1 + src/tools/clippy/tests/ui/map_flatten_fixable.rs | 1 + .../clippy/tests/ui/map_flatten_fixable.stderr | 18 +- .../ui/match_wildcard_for_single_variants.fixed | 2 +- .../ui/match_wildcard_for_single_variants.stderr | 8 +- src/tools/clippy/tests/ui/methods.rs | 1 + src/tools/clippy/tests/ui/methods.stderr | 4 +- src/tools/clippy/tests/ui/missing_doc_impl.stderr | 4 +- .../clippy/tests/ui/module_name_repetitions.stderr | 20 +- .../tests/ui/multiple_unsafe_ops_per_block.rs | 119 +++++ .../tests/ui/multiple_unsafe_ops_per_block.stderr | 129 +++++ .../clippy/tests/ui/must_use_candidates.fixed | 2 +- src/tools/clippy/tests/ui/must_use_candidates.rs | 2 +- src/tools/clippy/tests/ui/needless_lifetimes.fixed | 548 +++++++++++++++++++++ src/tools/clippy/tests/ui/needless_lifetimes.rs | 52 +- .../clippy/tests/ui/needless_lifetimes.stderr | 391 ++++++++++++--- .../clippy/tests/ui/needless_range_loop.stderr | 8 +- src/tools/clippy/tests/ui/needless_return.fixed | 20 + src/tools/clippy/tests/ui/needless_return.rs | 20 + src/tools/clippy/tests/ui/needless_return.stderr | 126 +++-- src/tools/clippy/tests/ui/never_loop.rs | 45 ++ src/tools/clippy/tests/ui/never_loop.stderr | 15 +- src/tools/clippy/tests/ui/new_without_default.rs | 7 +- .../clippy/tests/ui/new_without_default.stderr | 14 +- .../clippy/tests/ui/no_mangle_with_rust_abi.fixed | 48 ++ .../clippy/tests/ui/no_mangle_with_rust_abi.rs | 48 ++ .../clippy/tests/ui/no_mangle_with_rust_abi.stderr | 45 ++ src/tools/clippy/tests/ui/question_mark_used.rs | 15 + .../clippy/tests/ui/question_mark_used.stderr | 11 + .../clippy/tests/ui/redundant_field_names.fixed | 2 +- src/tools/clippy/tests/ui/redundant_field_names.rs | 2 +- src/tools/clippy/tests/ui/regex.rs | 4 + src/tools/clippy/tests/ui/regex.stderr | 66 ++- .../tests/ui/seek_to_start_instead_of_rewind.fixed | 4 +- .../tests/ui/seek_to_start_instead_of_rewind.rs | 4 +- .../tests/ui/significant_drop_tightening.fixed | 84 ++++ .../clippy/tests/ui/significant_drop_tightening.rs | 80 +++ .../tests/ui/significant_drop_tightening.stderr | 94 ++++ .../tests/ui/suspicious_command_arg_space.rs | 10 + .../tests/ui/suspicious_command_arg_space.stderr | 25 + .../clippy/tests/ui/suspicious_to_owned.stderr | 43 +- src/tools/clippy/tests/ui/swap.fixed | 24 +- src/tools/clippy/tests/ui/swap.rs | 29 +- src/tools/clippy/tests/ui/swap.stderr | 65 ++- src/tools/clippy/tests/ui/track-diagnostics.stderr | 2 +- .../clippy/tests/ui/transmute_int_to_non_zero.rs | 41 ++ .../tests/ui/transmute_int_to_non_zero.stderr | 64 +++ .../ui/transmutes_expressible_as_ptr_casts.fixed | 2 + .../ui/transmutes_expressible_as_ptr_casts.rs | 2 + .../ui/transmutes_expressible_as_ptr_casts.stderr | 10 +- .../clippy/tests/ui/type_repetition_in_bounds.rs | 1 + .../tests/ui/type_repetition_in_bounds.stderr | 8 +- .../clippy/tests/ui/uninlined_format_args.fixed | 4 + src/tools/clippy/tests/ui/uninlined_format_args.rs | 4 + .../clippy/tests/ui/unnecessary_safety_comment.rs | 17 + src/tools/clippy/tests/ui/unreadable_literal.fixed | 2 +- .../clippy/tests/ui/unreadable_literal.stderr | 10 +- src/tools/clippy/tests/ui/unused_io_amount.rs | 8 + src/tools/clippy/tests/ui/unused_io_amount.stderr | 44 +- .../clippy/tests/ui/wildcard_enum_match_arm.fixed | 2 +- .../clippy/tests/ui/wildcard_enum_match_arm.stderr | 4 +- 115 files changed, 3975 insertions(+), 512 deletions(-) create mode 100644 src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/clippy.toml create mode 100644 src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs create mode 100644 src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr create mode 100644 src/tools/clippy/tests/ui/bool_assert_comparison.fixed create mode 100644 src/tools/clippy/tests/ui/crashes/ice-rust-107877.rs create mode 100644 src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs create mode 100644 src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr create mode 100644 src/tools/clippy/tests/ui/extra_unused_type_parameters.rs create mode 100644 src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr create mode 100644 src/tools/clippy/tests/ui/impl_trait_in_params.rs create mode 100644 src/tools/clippy/tests/ui/impl_trait_in_params.stderr create mode 100644 src/tools/clippy/tests/ui/let_underscore_untyped.rs create mode 100644 src/tools/clippy/tests/ui/let_underscore_untyped.stderr create mode 100644 src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs create mode 100644 src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr create mode 100644 src/tools/clippy/tests/ui/needless_lifetimes.fixed create mode 100644 src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed create mode 100644 src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs create mode 100644 src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr create mode 100644 src/tools/clippy/tests/ui/question_mark_used.rs create mode 100644 src/tools/clippy/tests/ui/question_mark_used.stderr create mode 100644 src/tools/clippy/tests/ui/significant_drop_tightening.fixed create mode 100644 src/tools/clippy/tests/ui/significant_drop_tightening.rs create mode 100644 src/tools/clippy/tests/ui/significant_drop_tightening.stderr create mode 100644 src/tools/clippy/tests/ui/suspicious_command_arg_space.rs create mode 100644 src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr create mode 100644 src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs create mode 100644 src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr (limited to 'src/tools/clippy/tests') diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs index 4be04f77f..837811bdf 100644 --- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs +++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs @@ -1,8 +1,9 @@ // rustc-env:RUST_BACKTRACE=0 // normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo" -// normalize-stderr-test: "internal_lints.rs:\d*:\d*" -> "internal_lints.rs" +// normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs" // normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints" // normalize-stderr-test: "'rustc'" -> "''" +// normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr index 2ba589066..7ed0ef027 100644 --- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr +++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr @@ -1,4 +1,4 @@ -thread '' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints/produce_ice.rs:28:9 +thread '' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints/produce_ice.rs note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic @@ -9,5 +9,3 @@ note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy note: Clippy version: foo -query stack during panic: -end of query stack diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs index bff97d97d..89f142a15 100644 --- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs +++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs @@ -16,6 +16,18 @@ fn main() { expect_result(); } +#[test] +fn test_expect_option() { + let opt = Some(0); + let _ = opt.expect(""); +} + +#[test] +fn test_expect_result() { + let res: Result = Ok(0); + let _ = res.expect(""); +} + #[cfg(test)] mod issue9612 { // should not lint in `#[cfg(test)]` modules diff --git a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/clippy.toml b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/clippy.toml new file mode 100644 index 000000000..ec210a987 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/clippy.toml @@ -0,0 +1 @@ +missing-docs-in-crate-items = true 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 new file mode 100644 index 000000000..830d71f61 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs @@ -0,0 +1,59 @@ +//! this is crate +#![allow(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + +/// this is mod +mod my_mod { + /// some docs + fn priv_with_docs() {} + fn priv_no_docs() {} + /// some docs + pub(crate) fn crate_with_docs() {} + pub(crate) fn crate_no_docs() {} + /// some docs + pub(super) fn super_with_docs() {} + pub(super) fn super_no_docs() {} + + mod my_sub { + /// some docs + fn sub_priv_with_docs() {} + fn sub_priv_no_docs() {} + /// some docs + pub(crate) fn sub_crate_with_docs() {} + pub(crate) fn sub_crate_no_docs() {} + /// some docs + pub(super) fn sub_super_with_docs() {} + pub(super) fn sub_super_no_docs() {} + } + + /// some docs + pub(crate) struct CrateStructWithDocs { + /// some docs + pub(crate) crate_field_with_docs: (), + pub(crate) crate_field_no_docs: (), + /// some docs + priv_field_with_docs: (), + priv_field_no_docs: (), + } + + pub(crate) struct CrateStructNoDocs { + /// some docs + pub(crate) crate_field_with_docs: (), + pub(crate) crate_field_no_docs: (), + /// some docs + priv_field_with_docs: (), + priv_field_no_docs: (), + } +} + +/// some docs +type CrateTypedefWithDocs = String; +type CrateTypedefNoDocs = String; +/// some docs +pub type PubTypedefWithDocs = String; +pub type PubTypedefNoDocs = String; + +fn main() { + my_mod::crate_with_docs(); + my_mod::crate_no_docs(); +} 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 new file mode 100644 index 000000000..a47418705 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr @@ -0,0 +1,52 @@ +error: missing documentation for a function + --> $DIR/pub_crate_missing_doc.rs:12:5 + | +LL | pub(crate) fn crate_no_docs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` + +error: missing documentation for a function + --> $DIR/pub_crate_missing_doc.rs:15:5 + | +LL | pub(super) fn super_no_docs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/pub_crate_missing_doc.rs:23:9 + | +LL | pub(crate) fn sub_crate_no_docs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a struct field + --> $DIR/pub_crate_missing_doc.rs:33:9 + | +LL | pub(crate) crate_field_no_docs: (), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a struct + --> $DIR/pub_crate_missing_doc.rs:39:5 + | +LL | / pub(crate) struct CrateStructNoDocs { +LL | | /// some docs +LL | | pub(crate) crate_field_with_docs: (), +LL | | pub(crate) crate_field_no_docs: (), +... | +LL | | priv_field_no_docs: (), +LL | | } + | |_____^ + +error: missing documentation for a struct field + --> $DIR/pub_crate_missing_doc.rs:42:9 + | +LL | pub(crate) crate_field_no_docs: (), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a type alias + --> $DIR/pub_crate_missing_doc.rs:51:1 + | +LL | type CrateTypedefNoDocs = String; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + 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 a22c6a5a0..6a246afac 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 @@ -33,6 +33,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie max-struct-bools max-suggested-slice-pattern-length max-trait-bounds + missing-docs-in-crate-items msrv pass-by-value-size-limit single-char-binding-names-threshold diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs index bc8e8c1f0..6525ea5bf 100644 --- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs +++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs @@ -66,6 +66,12 @@ fn main() { } } +#[test] +fn test() { + let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let _ = boxed_slice.get(1).unwrap(); +} + #[cfg(test)] mod issue9612 { // should not lint in `#[cfg(test)]` modules diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr index 94b5ef663..8a32750e3 100644 --- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -188,10 +188,16 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:84:17 + --> $DIR/unwrap_used.rs:72:13 + | +LL | let _ = boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/unwrap_used.rs:90:17 | LL | let _ = Box::new([0]).get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&Box::new([0])[1]` -error: aborting due to 27 previous errors +error: aborting due to 28 previous errors diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index 918cf81c6..2611e3a78 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -13,6 +13,9 @@ use core::num::{Saturating, Wrapping}; +const ONE: i32 = 1; +const ZERO: i32 = 0; + #[derive(Clone, Copy)] pub struct Custom; @@ -182,6 +185,10 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n += &0; _n -= 0; _n -= &0; + _n += ZERO; + _n += &ZERO; + _n -= ZERO; + _n -= &ZERO; _n /= 99; _n /= &99; _n %= 99; @@ -190,10 +197,18 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n *= &0; _n *= 1; _n *= &1; + _n *= ZERO; + _n *= &ZERO; + _n *= ONE; + _n *= &ONE; _n += -0; _n += &-0; _n -= -0; _n -= &-0; + _n += -ZERO; + _n += &-ZERO; + _n -= -ZERO; + _n -= &-ZERO; _n /= -99; _n /= &-99; _n %= -99; @@ -208,10 +223,18 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n = _n + &0; _n = 0 + _n; _n = &0 + _n; + _n = _n + ZERO; + _n = _n + &ZERO; + _n = ZERO + _n; + _n = &ZERO + _n; _n = _n - 0; _n = _n - &0; _n = 0 - _n; _n = &0 - _n; + _n = _n - ZERO; + _n = _n - &ZERO; + _n = ZERO - _n; + _n = &ZERO - _n; _n = _n / 99; _n = _n / &99; _n = _n % 99; @@ -222,6 +245,10 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n = &0 * _n; _n = _n * 1; _n = _n * &1; + _n = ZERO * _n; + _n = &ZERO * _n; + _n = _n * ONE; + _n = _n * &ONE; _n = 1 * _n; _n = &1 * _n; _n = 23 + 85; diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr index 5e349f6b4..17a2448fb 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr @@ -1,5 +1,5 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:243:5 + --> $DIR/arithmetic_side_effects.rs:270:5 | LL | _n += 1; | ^^^^^^^ @@ -7,589 +7,589 @@ LL | _n += 1; = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:244:5 + --> $DIR/arithmetic_side_effects.rs:271:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:245:5 + --> $DIR/arithmetic_side_effects.rs:272:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:246:5 + --> $DIR/arithmetic_side_effects.rs:273:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:247:5 + --> $DIR/arithmetic_side_effects.rs:274:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:248:5 + --> $DIR/arithmetic_side_effects.rs:275:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:249:5 + --> $DIR/arithmetic_side_effects.rs:276:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:250:5 + --> $DIR/arithmetic_side_effects.rs:277:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:251:5 + --> $DIR/arithmetic_side_effects.rs:278:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:252:5 + --> $DIR/arithmetic_side_effects.rs:279:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:253:5 + --> $DIR/arithmetic_side_effects.rs:280:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:254:5 + --> $DIR/arithmetic_side_effects.rs:281:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:255:5 + --> $DIR/arithmetic_side_effects.rs:282:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:256:5 + --> $DIR/arithmetic_side_effects.rs:283:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:257:5 + --> $DIR/arithmetic_side_effects.rs:284:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:258:5 + --> $DIR/arithmetic_side_effects.rs:285:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:259:5 + --> $DIR/arithmetic_side_effects.rs:286:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:260:5 + --> $DIR/arithmetic_side_effects.rs:287:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:261:5 + --> $DIR/arithmetic_side_effects.rs:288:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:262:5 + --> $DIR/arithmetic_side_effects.rs:289:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:263:5 + --> $DIR/arithmetic_side_effects.rs:290:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:264:5 + --> $DIR/arithmetic_side_effects.rs:291:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:265:5 + --> $DIR/arithmetic_side_effects.rs:292:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:266:5 + --> $DIR/arithmetic_side_effects.rs:293:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:267:5 + --> $DIR/arithmetic_side_effects.rs:294:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:268:5 + --> $DIR/arithmetic_side_effects.rs:295:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:269:5 + --> $DIR/arithmetic_side_effects.rs:296:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:270:5 + --> $DIR/arithmetic_side_effects.rs:297:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:271:5 + --> $DIR/arithmetic_side_effects.rs:298:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:272:5 + --> $DIR/arithmetic_side_effects.rs:299:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:273:5 + --> $DIR/arithmetic_side_effects.rs:300:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:274:5 + --> $DIR/arithmetic_side_effects.rs:301:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:275:5 + --> $DIR/arithmetic_side_effects.rs:302:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:276:5 + --> $DIR/arithmetic_side_effects.rs:303:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:277:5 + --> $DIR/arithmetic_side_effects.rs:304:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:278:5 + --> $DIR/arithmetic_side_effects.rs:305:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:279:5 + --> $DIR/arithmetic_side_effects.rs:306:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:280:5 + --> $DIR/arithmetic_side_effects.rs:307:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:281:5 + --> $DIR/arithmetic_side_effects.rs:308:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:282:5 + --> $DIR/arithmetic_side_effects.rs:309:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:285:10 + --> $DIR/arithmetic_side_effects.rs:312:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:286:10 + --> $DIR/arithmetic_side_effects.rs:313:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:287:10 + --> $DIR/arithmetic_side_effects.rs:314:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:288:10 + --> $DIR/arithmetic_side_effects.rs:315:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:289:10 + --> $DIR/arithmetic_side_effects.rs:316:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:290:10 + --> $DIR/arithmetic_side_effects.rs:317:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:291:10 + --> $DIR/arithmetic_side_effects.rs:318:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:292:10 + --> $DIR/arithmetic_side_effects.rs:319:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:293:10 + --> $DIR/arithmetic_side_effects.rs:320:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:294:10 + --> $DIR/arithmetic_side_effects.rs:321:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:295:10 + --> $DIR/arithmetic_side_effects.rs:322:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:296:10 + --> $DIR/arithmetic_side_effects.rs:323:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:297:10 + --> $DIR/arithmetic_side_effects.rs:324:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:298:10 + --> $DIR/arithmetic_side_effects.rs:325:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:299:10 + --> $DIR/arithmetic_side_effects.rs:326:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:300:10 + --> $DIR/arithmetic_side_effects.rs:327:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:301:10 + --> $DIR/arithmetic_side_effects.rs:328:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:302:10 + --> $DIR/arithmetic_side_effects.rs:329:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:303:10 + --> $DIR/arithmetic_side_effects.rs:330:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:304:15 + --> $DIR/arithmetic_side_effects.rs:331:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:305:15 + --> $DIR/arithmetic_side_effects.rs:332:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:306:15 + --> $DIR/arithmetic_side_effects.rs:333:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:307:15 + --> $DIR/arithmetic_side_effects.rs:334:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:308:15 + --> $DIR/arithmetic_side_effects.rs:335:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:309:15 + --> $DIR/arithmetic_side_effects.rs:336:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:310:15 + --> $DIR/arithmetic_side_effects.rs:337:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:311:15 + --> $DIR/arithmetic_side_effects.rs:338:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:312:15 + --> $DIR/arithmetic_side_effects.rs:339:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:313:15 + --> $DIR/arithmetic_side_effects.rs:340:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:314:15 + --> $DIR/arithmetic_side_effects.rs:341:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:315:15 + --> $DIR/arithmetic_side_effects.rs:342:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:316:15 + --> $DIR/arithmetic_side_effects.rs:343:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:317:15 + --> $DIR/arithmetic_side_effects.rs:344:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:318:15 + --> $DIR/arithmetic_side_effects.rs:345:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:319:15 + --> $DIR/arithmetic_side_effects.rs:346:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:320:15 + --> $DIR/arithmetic_side_effects.rs:347:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:321:15 + --> $DIR/arithmetic_side_effects.rs:348:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:322:15 + --> $DIR/arithmetic_side_effects.rs:349:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:325:10 + --> $DIR/arithmetic_side_effects.rs:352:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:326:10 + --> $DIR/arithmetic_side_effects.rs:353:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:327:15 + --> $DIR/arithmetic_side_effects.rs:354:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:328:15 + --> $DIR/arithmetic_side_effects.rs:355:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:337:5 + --> $DIR/arithmetic_side_effects.rs:364:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:338:5 + --> $DIR/arithmetic_side_effects.rs:365:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:340:5 + --> $DIR/arithmetic_side_effects.rs:367:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:341:5 + --> $DIR/arithmetic_side_effects.rs:368:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:342:5 + --> $DIR/arithmetic_side_effects.rs:369:5 | LL | i >> 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:343:5 + --> $DIR/arithmetic_side_effects.rs:370:5 | LL | i << 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:352:5 + --> $DIR/arithmetic_side_effects.rs:379:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:353:5 + --> $DIR/arithmetic_side_effects.rs:380:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:354:5 + --> $DIR/arithmetic_side_effects.rs:381:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:356:5 + --> $DIR/arithmetic_side_effects.rs:383:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:358:5 + --> $DIR/arithmetic_side_effects.rs:385:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:359:5 + --> $DIR/arithmetic_side_effects.rs:386:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:361:5 + --> $DIR/arithmetic_side_effects.rs:388:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:363:5 + --> $DIR/arithmetic_side_effects.rs:390:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:364:5 + --> $DIR/arithmetic_side_effects.rs:391:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:365:5 + --> $DIR/arithmetic_side_effects.rs:392:5 | LL | i <<= 3; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:366:5 + --> $DIR/arithmetic_side_effects.rs:393:5 | LL | i >>= 2; | ^^^^^^^ diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs index 1e5f20e8c..a13af5652 100644 --- a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs +++ b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs @@ -149,3 +149,22 @@ macro_rules! almost_complete_range { let _ = '0'..'9'; }; } + +#[macro_export] +macro_rules! unsafe_macro { + () => { + unsafe { + *core::ptr::null::<()>(); + *core::ptr::null::<()>(); + } + }; +} + +#[macro_export] +macro_rules! needless_lifetime { + () => { + fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + }; +} diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.fixed b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed new file mode 100644 index 000000000..b8dd92906 --- /dev/null +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed @@ -0,0 +1,171 @@ +// run-rustfix + +#![allow(unused, clippy::assertions_on_constants)] +#![warn(clippy::bool_assert_comparison)] + +use std::ops::Not; + +macro_rules! a { + () => { + true + }; +} +macro_rules! b { + () => { + true + }; +} + +// Implements the Not trait but with an output type +// that's not bool. Should not suggest a rewrite +#[derive(Debug, Clone, Copy)] +enum ImplNotTraitWithoutBool { + VariantX(bool), + VariantY(u32), +} + +impl PartialEq for ImplNotTraitWithoutBool { + fn eq(&self, other: &bool) -> bool { + match *self { + ImplNotTraitWithoutBool::VariantX(b) => b == *other, + _ => false, + } + } +} + +impl Not for ImplNotTraitWithoutBool { + type Output = Self; + + fn not(self) -> Self::Output { + match self { + ImplNotTraitWithoutBool::VariantX(b) => ImplNotTraitWithoutBool::VariantX(!b), + ImplNotTraitWithoutBool::VariantY(0) => ImplNotTraitWithoutBool::VariantY(1), + ImplNotTraitWithoutBool::VariantY(_) => ImplNotTraitWithoutBool::VariantY(0), + } + } +} + +// This type implements the Not trait with an Output of +// type bool. Using assert!(..) must be suggested +#[derive(Debug, Clone, Copy)] +struct ImplNotTraitWithBool; + +impl PartialEq for ImplNotTraitWithBool { + fn eq(&self, other: &bool) -> bool { + false + } +} + +impl Not for ImplNotTraitWithBool { + type Output = bool; + + fn not(self) -> Self::Output { + true + } +} + +#[derive(Debug)] +struct NonCopy; + +impl PartialEq for NonCopy { + fn eq(&self, other: &bool) -> bool { + false + } +} + +impl Not for NonCopy { + type Output = bool; + + fn not(self) -> Self::Output { + true + } +} + +fn main() { + let a = ImplNotTraitWithoutBool::VariantX(true); + let b = ImplNotTraitWithBool; + + assert_eq!("a".len(), 1); + assert!(!"a".is_empty()); + assert!("".is_empty()); + assert!("".is_empty()); + assert_eq!(a!(), b!()); + assert_eq!(a!(), "".is_empty()); + assert_eq!("".is_empty(), b!()); + assert_eq!(a, true); + assert!(b); + + assert_ne!("a".len(), 1); + assert!("a".is_empty()); + assert!(!"".is_empty()); + assert!(!"".is_empty()); + assert_ne!(a!(), b!()); + assert_ne!(a!(), "".is_empty()); + assert_ne!("".is_empty(), b!()); + assert_ne!(a, true); + assert!(!b); + + debug_assert_eq!("a".len(), 1); + debug_assert!(!"a".is_empty()); + debug_assert!("".is_empty()); + debug_assert!("".is_empty()); + debug_assert_eq!(a!(), b!()); + debug_assert_eq!(a!(), "".is_empty()); + debug_assert_eq!("".is_empty(), b!()); + debug_assert_eq!(a, true); + debug_assert!(b); + + debug_assert_ne!("a".len(), 1); + debug_assert!("a".is_empty()); + debug_assert!(!"".is_empty()); + debug_assert!(!"".is_empty()); + debug_assert_ne!(a!(), b!()); + debug_assert_ne!(a!(), "".is_empty()); + debug_assert_ne!("".is_empty(), b!()); + debug_assert_ne!(a, true); + debug_assert!(!b); + + // assert with error messages + assert_eq!("a".len(), 1, "tadam {}", 1); + assert_eq!("a".len(), 1, "tadam {}", true); + assert!(!"a".is_empty(), "tadam {}", 1); + assert!(!"a".is_empty(), "tadam {}", true); + assert!(!"a".is_empty(), "tadam {}", true); + assert_eq!(a, true, "tadam {}", false); + + debug_assert_eq!("a".len(), 1, "tadam {}", 1); + debug_assert_eq!("a".len(), 1, "tadam {}", true); + debug_assert!(!"a".is_empty(), "tadam {}", 1); + debug_assert!(!"a".is_empty(), "tadam {}", true); + debug_assert!(!"a".is_empty(), "tadam {}", true); + debug_assert_eq!(a, true, "tadam {}", false); + + assert!(a!()); + assert!(b!()); + + use debug_assert_eq as renamed; + renamed!(a, true); + debug_assert!(b); + + let non_copy = NonCopy; + assert_eq!(non_copy, true); + // changing the above to `assert!(non_copy)` would cause a `borrow of moved value` + println!("{non_copy:?}"); + + macro_rules! in_macro { + ($v:expr) => {{ + assert_eq!($v, true); + }}; + } + in_macro!(a); + + assert!("".is_empty()); + assert!("".is_empty()); + assert!(!"requires negation".is_empty()); + assert!(!"requires negation".is_empty()); + + debug_assert!("".is_empty()); + debug_assert!("".is_empty()); + debug_assert!(!"requires negation".is_empty()); + debug_assert!(!"requires negation".is_empty()); +} diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.rs b/src/tools/clippy/tests/ui/bool_assert_comparison.rs index ec4d6f3ff..0a8ad34fd 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.rs +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.rs @@ -1,3 +1,6 @@ +// run-rustfix + +#![allow(unused, clippy::assertions_on_constants)] #![warn(clippy::bool_assert_comparison)] use std::ops::Not; @@ -15,7 +18,7 @@ macro_rules! b { // Implements the Not trait but with an output type // that's not bool. Should not suggest a rewrite -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] enum ImplNotTraitWithoutBool { VariantX(bool), VariantY(u32), @@ -44,7 +47,7 @@ impl Not for ImplNotTraitWithoutBool { // This type implements the Not trait with an Output of // type bool. Using assert!(..) must be suggested -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] struct ImplNotTraitWithBool; impl PartialEq for ImplNotTraitWithBool { @@ -61,6 +64,23 @@ impl Not for ImplNotTraitWithBool { } } +#[derive(Debug)] +struct NonCopy; + +impl PartialEq for NonCopy { + fn eq(&self, other: &bool) -> bool { + false + } +} + +impl Not for NonCopy { + type Output = bool; + + fn not(self) -> Self::Output { + true + } +} + fn main() { let a = ImplNotTraitWithoutBool::VariantX(true); let b = ImplNotTraitWithBool; @@ -119,4 +139,33 @@ fn main() { debug_assert_eq!("a".is_empty(), false, "tadam {}", true); debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); debug_assert_eq!(a, true, "tadam {}", false); + + assert_eq!(a!(), true); + assert_eq!(true, b!()); + + use debug_assert_eq as renamed; + renamed!(a, true); + renamed!(b, true); + + let non_copy = NonCopy; + assert_eq!(non_copy, true); + // changing the above to `assert!(non_copy)` would cause a `borrow of moved value` + println!("{non_copy:?}"); + + macro_rules! in_macro { + ($v:expr) => {{ + assert_eq!($v, true); + }}; + } + in_macro!(a); + + assert_eq!("".is_empty(), true); + assert_ne!("".is_empty(), false); + assert_ne!("requires negation".is_empty(), true); + assert_eq!("requires negation".is_empty(), false); + + debug_assert_eq!("".is_empty(), true); + debug_assert_ne!("".is_empty(), false); + debug_assert_ne!("requires negation".is_empty(), true); + debug_assert_eq!("requires negation".is_empty(), false); } diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index 377d51be4..89cefc95a 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -1,136 +1,399 @@ error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:69:5 + --> $DIR/bool_assert_comparison.rs:89:5 | LL | assert_eq!("a".is_empty(), false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::bool-assert-comparison` implied by `-D warnings` +help: replace it with `assert!(..)` + | +LL - assert_eq!("a".is_empty(), false); +LL + assert!(!"a".is_empty()); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:70:5 + --> $DIR/bool_assert_comparison.rs:90:5 | LL | assert_eq!("".is_empty(), true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!("".is_empty(), true); +LL + assert!("".is_empty()); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:71:5 + --> $DIR/bool_assert_comparison.rs:91:5 | LL | assert_eq!(true, "".is_empty()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(true, "".is_empty()); +LL + assert!("".is_empty()); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:76:5 + --> $DIR/bool_assert_comparison.rs:96:5 | LL | assert_eq!(b, true); - | ^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(b, true); +LL + assert!(b); + | error: used `assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:79:5 + --> $DIR/bool_assert_comparison.rs:99:5 | LL | assert_ne!("a".is_empty(), false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!("a".is_empty(), false); +LL + assert!("a".is_empty()); + | error: used `assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:80:5 + --> $DIR/bool_assert_comparison.rs:100:5 | LL | assert_ne!("".is_empty(), true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!("".is_empty(), true); +LL + assert!(!"".is_empty()); + | error: used `assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:81:5 + --> $DIR/bool_assert_comparison.rs:101:5 | LL | assert_ne!(true, "".is_empty()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!(true, "".is_empty()); +LL + assert!(!"".is_empty()); + | error: used `assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:86:5 + --> $DIR/bool_assert_comparison.rs:106:5 | LL | assert_ne!(b, true); - | ^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!(b, true); +LL + assert!(!b); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:89:5 + --> $DIR/bool_assert_comparison.rs:109:5 | LL | debug_assert_eq!("a".is_empty(), false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("a".is_empty(), false); +LL + debug_assert!(!"a".is_empty()); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:90:5 + --> $DIR/bool_assert_comparison.rs:110:5 | LL | debug_assert_eq!("".is_empty(), true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("".is_empty(), true); +LL + debug_assert!("".is_empty()); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:91:5 + --> $DIR/bool_assert_comparison.rs:111:5 | LL | debug_assert_eq!(true, "".is_empty()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!(true, "".is_empty()); +LL + debug_assert!("".is_empty()); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:96:5 + --> $DIR/bool_assert_comparison.rs:116:5 | LL | debug_assert_eq!(b, true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!(b, true); +LL + debug_assert!(b); + | error: used `debug_assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:99:5 + --> $DIR/bool_assert_comparison.rs:119:5 | LL | debug_assert_ne!("a".is_empty(), false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!("a".is_empty(), false); +LL + debug_assert!("a".is_empty()); + | error: used `debug_assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:100:5 + --> $DIR/bool_assert_comparison.rs:120:5 | LL | debug_assert_ne!("".is_empty(), true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!("".is_empty(), true); +LL + debug_assert!(!"".is_empty()); + | error: used `debug_assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:101:5 + --> $DIR/bool_assert_comparison.rs:121:5 | LL | debug_assert_ne!(true, "".is_empty()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!(true, "".is_empty()); +LL + debug_assert!(!"".is_empty()); + | error: used `debug_assert_ne!` with a literal bool - --> $DIR/bool_assert_comparison.rs:106:5 + --> $DIR/bool_assert_comparison.rs:126:5 | LL | debug_assert_ne!(b, true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!(b, true); +LL + debug_assert!(!b); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:111:5 + --> $DIR/bool_assert_comparison.rs:131:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!("a".is_empty(), false, "tadam {}", 1); +LL + assert!(!"a".is_empty(), "tadam {}", 1); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:112:5 + --> $DIR/bool_assert_comparison.rs:132:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!("a".is_empty(), false, "tadam {}", true); +LL + assert!(!"a".is_empty(), "tadam {}", true); + | error: used `assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:113:5 + --> $DIR/bool_assert_comparison.rs:133:5 | LL | assert_eq!(false, "a".is_empty(), "tadam {}", true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(false, "a".is_empty(), "tadam {}", true); +LL + assert!(!"a".is_empty(), "tadam {}", true); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:118:5 + --> $DIR/bool_assert_comparison.rs:138:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("a".is_empty(), false, "tadam {}", 1); +LL + debug_assert!(!"a".is_empty(), "tadam {}", 1); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:119:5 + --> $DIR/bool_assert_comparison.rs:139:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("a".is_empty(), false, "tadam {}", true); +LL + debug_assert!(!"a".is_empty(), "tadam {}", true); + | error: used `debug_assert_eq!` with a literal bool - --> $DIR/bool_assert_comparison.rs:120:5 + --> $DIR/bool_assert_comparison.rs:140:5 | LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); +LL + debug_assert!(!"a".is_empty(), "tadam {}", true); + | + +error: used `assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:143:5 + | +LL | assert_eq!(a!(), true); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(a!(), true); +LL + assert!(a!()); + | + +error: used `assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:144:5 + | +LL | assert_eq!(true, b!()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(true, b!()); +LL + assert!(b!()); + | + +error: used `debug_assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:148:5 + | +LL | renamed!(b, true); + | ^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - renamed!(b, true); +LL + debug_assert!(b); + | + +error: used `assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:162:5 + | +LL | assert_eq!("".is_empty(), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!("".is_empty(), true); +LL + assert!("".is_empty()); + | + +error: used `assert_ne!` with a literal bool + --> $DIR/bool_assert_comparison.rs:163:5 + | +LL | assert_ne!("".is_empty(), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!("".is_empty(), false); +LL + assert!("".is_empty()); + | + +error: used `assert_ne!` with a literal bool + --> $DIR/bool_assert_comparison.rs:164:5 + | +LL | assert_ne!("requires negation".is_empty(), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_ne!("requires negation".is_empty(), true); +LL + assert!(!"requires negation".is_empty()); + | + +error: used `assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:165:5 + | +LL | assert_eq!("requires negation".is_empty(), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!("requires negation".is_empty(), false); +LL + assert!(!"requires negation".is_empty()); + | + +error: used `debug_assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:167:5 + | +LL | debug_assert_eq!("".is_empty(), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("".is_empty(), true); +LL + debug_assert!("".is_empty()); + | + +error: used `debug_assert_ne!` with a literal bool + --> $DIR/bool_assert_comparison.rs:168:5 + | +LL | debug_assert_ne!("".is_empty(), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!("".is_empty(), false); +LL + debug_assert!("".is_empty()); + | + +error: used `debug_assert_ne!` with a literal bool + --> $DIR/bool_assert_comparison.rs:169:5 + | +LL | debug_assert_ne!("requires negation".is_empty(), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_ne!("requires negation".is_empty(), true); +LL + debug_assert!(!"requires negation".is_empty()); + | + +error: used `debug_assert_eq!` with a literal bool + --> $DIR/bool_assert_comparison.rs:170:5 + | +LL | debug_assert_eq!("requires negation".is_empty(), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `debug_assert!(..)` + | +LL - debug_assert_eq!("requires negation".is_empty(), false); +LL + debug_assert!(!"requires negation".is_empty()); + | -error: aborting due to 22 previous errors +error: aborting due to 33 previous errors diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed index 7e9f074fd..59c0baf87 100644 --- a/src/tools/clippy/tests/ui/box_default.fixed +++ b/src/tools/clippy/tests/ui/box_default.fixed @@ -33,6 +33,7 @@ fn main() { let _vec4: Box<_> = Box::>::default(); let _more = ret_ty_fn(); call_ty_fn(Box::default()); + issue_10381(); } fn ret_ty_fn() -> Box { @@ -65,3 +66,20 @@ fn issue_10089() { let _ = Box::::default(); }; } + +fn issue_10381() { + #[derive(Default)] + pub struct Foo {} + pub trait Bar {} + impl Bar for Foo {} + + fn maybe_get_bar(i: u32) -> Option> { + if i % 2 == 0 { + Some(Box::::default()) + } else { + None + } + } + + assert!(maybe_get_bar(2).is_some()); +} diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs index 5c8d0b835..f7d832193 100644 --- a/src/tools/clippy/tests/ui/box_default.rs +++ b/src/tools/clippy/tests/ui/box_default.rs @@ -33,6 +33,7 @@ fn main() { let _vec4: Box<_> = Box::new(Vec::from([false; 0])); let _more = ret_ty_fn(); call_ty_fn(Box::new(u8::default())); + issue_10381(); } fn ret_ty_fn() -> Box { @@ -65,3 +66,20 @@ fn issue_10089() { let _ = Box::new(WeirdPathed::default()); }; } + +fn issue_10381() { + #[derive(Default)] + pub struct Foo {} + pub trait Bar {} + impl Bar for Foo {} + + fn maybe_get_bar(i: u32) -> Option> { + if i % 2 == 0 { + Some(Box::new(Foo::default())) + } else { + None + } + } + + assert!(maybe_get_bar(2).is_some()); +} diff --git a/src/tools/clippy/tests/ui/box_default.stderr b/src/tools/clippy/tests/ui/box_default.stderr index 249eb340f..78e17b9f0 100644 --- a/src/tools/clippy/tests/ui/box_default.stderr +++ b/src/tools/clippy/tests/ui/box_default.stderr @@ -73,22 +73,28 @@ LL | call_ty_fn(Box::new(u8::default())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:39:5 + --> $DIR/box_default.rs:40:5 | LL | Box::new(bool::default()) | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:56:28 + --> $DIR/box_default.rs:57:28 | LL | let _: Box = Box::new(ImplementsDefault::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:65:17 + --> $DIR/box_default.rs:66:17 | LL | let _ = Box::new(WeirdPathed::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` -error: aborting due to 15 previous errors +error: `Box::new(_)` of default value + --> $DIR/box_default.rs:78:18 + | +LL | Some(Box::new(Foo::default())) + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` + +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/bytes_nth.fixed b/src/tools/clippy/tests/ui/bytes_nth.fixed index b1fb2e16b..a35c679af 100644 --- a/src/tools/clippy/tests/ui/bytes_nth.fixed +++ b/src/tools/clippy/tests/ui/bytes_nth.fixed @@ -5,7 +5,7 @@ fn main() { let s = String::from("String"); - let _ = s.as_bytes().get(3); - let _ = &s.as_bytes().get(3); - let _ = s[..].as_bytes().get(3); + let _ = s.as_bytes().get(3).copied(); + let _ = &s.as_bytes()[3]; + let _ = s[..].as_bytes().get(3).copied(); } diff --git a/src/tools/clippy/tests/ui/bytes_nth.rs b/src/tools/clippy/tests/ui/bytes_nth.rs index 034c54e6a..1ecffea53 100644 --- a/src/tools/clippy/tests/ui/bytes_nth.rs +++ b/src/tools/clippy/tests/ui/bytes_nth.rs @@ -6,6 +6,6 @@ fn main() { let s = String::from("String"); let _ = s.bytes().nth(3); - let _ = &s.bytes().nth(3); + let _ = &s.bytes().nth(3).unwrap(); let _ = s[..].bytes().nth(3); } diff --git a/src/tools/clippy/tests/ui/bytes_nth.stderr b/src/tools/clippy/tests/ui/bytes_nth.stderr index 9851d4791..e8b150278 100644 --- a/src/tools/clippy/tests/ui/bytes_nth.stderr +++ b/src/tools/clippy/tests/ui/bytes_nth.stderr @@ -2,21 +2,21 @@ error: called `.bytes().nth()` on a `String` --> $DIR/bytes_nth.rs:8:13 | LL | let _ = s.bytes().nth(3); - | ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)` + | ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3).copied()` | = note: `-D clippy::bytes-nth` implied by `-D warnings` -error: called `.bytes().nth()` on a `String` +error: called `.bytes().nth().unwrap()` on a `String` --> $DIR/bytes_nth.rs:9:14 | -LL | let _ = &s.bytes().nth(3); - | ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)` +LL | let _ = &s.bytes().nth(3).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]` error: called `.bytes().nth()` on a `str` --> $DIR/bytes_nth.rs:10:13 | LL | let _ = s[..].bytes().nth(3); - | ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3)` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()` error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs index e6031e9ad..8b2673c2a 100644 --- a/src/tools/clippy/tests/ui/cast.rs +++ b/src/tools/clippy/tests/ui/cast.rs @@ -28,6 +28,7 @@ fn main() { 1i32 as u8; 1f64 as isize; 1f64 as usize; + 1f32 as u32 as u16; // Test clippy::cast_possible_wrap 1u8 as i8; 1u16 as i16; diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr index 0c63b4af3..451078de2 100644 --- a/src/tools/clippy/tests/ui/cast.stderr +++ b/src/tools/clippy/tests/ui/cast.stderr @@ -42,13 +42,24 @@ error: casting `f32` to `i32` may truncate the value LL | 1f32 as i32; | ^^^^^^^^^^^ | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... = note: `-D clippy::cast-possible-truncation` implied by `-D warnings` +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1f32); + | ~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value --> $DIR/cast.rs:25:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1f32); + | ~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may lose the sign of the value --> $DIR/cast.rs:25:5 @@ -63,30 +74,60 @@ error: casting `f64` to `f32` may truncate the value | LL | 1f64 as f32; | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | f32::try_from(1f64); + | ~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `i8` may truncate the value --> $DIR/cast.rs:27:5 | LL | 1i32 as i8; | ^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from(1i32); + | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value --> $DIR/cast.rs:28:5 | LL | 1i32 as u8; | ^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u8::try_from(1i32); + | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value --> $DIR/cast.rs:29:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1f64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `usize` may truncate the value --> $DIR/cast.rs:30:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1f64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `usize` may lose the sign of the value --> $DIR/cast.rs:30:5 @@ -94,8 +135,38 @@ error: casting `f64` to `usize` may lose the sign of the value LL | 1f64 as usize; | ^^^^^^^^^^^^^ +error: casting `u32` to `u16` may truncate the value + --> $DIR/cast.rs:31:5 + | +LL | 1f32 as u32 as u16; + | ^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u16::try_from(1f32 as u32); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: casting `f32` to `u32` may truncate the value + --> $DIR/cast.rs:31:5 + | +LL | 1f32 as u32 as u16; + | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1f32) as u16; + | ~~~~~~~~~~~~~~~~~~~ + +error: casting `f32` to `u32` may lose the sign of the value + --> $DIR/cast.rs:31:5 + | +LL | 1f32 as u32 as u16; + | ^^^^^^^^^^^ + error: casting `u8` to `i8` may wrap around the value - --> $DIR/cast.rs:32:5 + --> $DIR/cast.rs:33:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -103,61 +174,79 @@ LL | 1u8 as i8; = note: `-D clippy::cast-possible-wrap` implied by `-D warnings` error: casting `u16` to `i16` may wrap around the value - --> $DIR/cast.rs:33:5 + --> $DIR/cast.rs:34:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> $DIR/cast.rs:34:5 + --> $DIR/cast.rs:35:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> $DIR/cast.rs:35:5 + --> $DIR/cast.rs:36:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> $DIR/cast.rs:36:5 + --> $DIR/cast.rs:37:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> $DIR/cast.rs:39:5 + --> $DIR/cast.rs:40:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> $DIR/cast.rs:41:5 + --> $DIR/cast.rs:42:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> $DIR/cast.rs:108:5 + --> $DIR/cast.rs:109:5 | LL | (-99999999999i64).min(1) as i8; // should be linted because signed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from((-99999999999i64).min(1)); // should be linted because signed + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> $DIR/cast.rs:120:5 + --> $DIR/cast.rs:121:5 | LL | 999999u64.clamp(0, 256) as u8; // should still be linted | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u8::try_from(999999u64.clamp(0, 256)); // should still be linted + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> $DIR/cast.rs:141:21 + --> $DIR/cast.rs:142:21 | LL | let _ = self as u8; | ^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = u8::try_from(self); + | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> $DIR/cast.rs:142:21 + --> $DIR/cast.rs:143:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -165,46 +254,82 @@ LL | let _ = Self::B as u8; = note: `-D clippy::cast-enum-truncation` implied by `-D warnings` error: casting `main::E5` to `i8` may truncate the value - --> $DIR/cast.rs:178:21 + --> $DIR/cast.rs:179:21 | LL | let _ = self as i8; | ^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = i8::try_from(self); + | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> $DIR/cast.rs:179:21 + --> $DIR/cast.rs:180:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> $DIR/cast.rs:193:21 + --> $DIR/cast.rs:194:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = i16::try_from(self); + | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> $DIR/cast.rs:208:21 + --> $DIR/cast.rs:209:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = usize::try_from(self); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> $DIR/cast.rs:249:21 + --> $DIR/cast.rs:250:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = u16::try_from(self); + | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:257:13 + --> $DIR/cast.rs:258:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let c = u8::try_from((q >> 16)); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:260:13 + --> $DIR/cast.rs:261:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | let c = u8::try_from((q / 1000)); + | ~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 33 previous errors +error: aborting due to 36 previous errors diff --git a/src/tools/clippy/tests/ui/cast_size.stderr b/src/tools/clippy/tests/ui/cast_size.stderr index 95552f2e2..6d2d49d9e 100644 --- a/src/tools/clippy/tests/ui/cast_size.stderr +++ b/src/tools/clippy/tests/ui/cast_size.stderr @@ -4,7 +4,12 @@ error: casting `isize` to `i8` may truncate the value LL | 1isize as i8; | ^^^^^^^^^^^^ | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... = note: `-D clippy::cast-possible-truncation` implied by `-D warnings` +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> $DIR/cast_size.rs:15:5 @@ -37,24 +42,48 @@ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wi | LL | 1isize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size.rs:20:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size.rs:21:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size.rs:22:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size.rs:22:5 @@ -69,18 +98,36 @@ error: casting `i64` to `isize` may truncate the value on targets with 32-bit wi | LL | 1i64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size.rs:25:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size.rs:26:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> $DIR/cast_size.rs:26:5 @@ -93,6 +140,12 @@ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wi | LL | 1u64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size.rs:28:5 diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr index 1f26c7f4d..c5ea0b16d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr @@ -5,6 +5,11 @@ LL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::needless-lifetimes` implied by `-D warnings` +help: elide the lifetimes + | +LL - pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { +LL + pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) { + | error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-rust-107877.rs b/src/tools/clippy/tests/ui/crashes/ice-rust-107877.rs new file mode 100644 index 000000000..7f5bae60d --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-rust-107877.rs @@ -0,0 +1,17 @@ +#![allow(dead_code)] + +struct Foo; + +impl<'a> std::convert::TryFrom<&'a String> for Foo { + type Error = std::convert::Infallible; + + fn try_from(_: &'a String) -> Result { + Ok(Foo) + } +} + +fn find(_: impl std::convert::TryInto) {} + +fn main() { + find(&String::new()); +} diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr index 875d5ab4f..0b0e0ad26 100644 --- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr +++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr @@ -9,6 +9,11 @@ note: the lint level is defined here | LL | #![deny(clippy::needless_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: elide the lifetimes + | +LL - fn baz<'a>(&'a self) -> impl Foo + 'a { +LL + fn baz(&self) -> impl Foo + '_ { + | error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs new file mode 100644 index 000000000..dd3d8b8b6 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/107147 + +#![warn(clippy::needless_pass_by_value)] + +struct Foo<'a>(&'a [(); 100]); + +fn test(x: Foo<'_>) {} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr new file mode 100644 index 000000000..7a0a64897 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr @@ -0,0 +1,15 @@ +error: this argument is passed by value, but not consumed in the function body + --> $DIR/needless_pass_by_value-w-late-bound.rs:7:12 + | +LL | fn test(x: Foo<'_>) {} + | ^^^^^^^ help: consider taking a reference instead: `&Foo<'_>` + | +help: consider marking this type as `Copy` + --> $DIR/needless_pass_by_value-w-late-bound.rs:5:1 + | +LL | struct Foo<'a>(&'a [(); 100]); + | ^^^^^^^^^^^^^^ + = note: `-D clippy::needless-pass-by-value` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index 747801b40..ecb0bf364 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -78,7 +78,7 @@ fn test_allowed() { /// This test has [a `link_with_underscores`][chunked-example] inside it. See #823. /// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues) /// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link]. -/// It can also be [`inline_link2`]. +/// It can also be [inline_link2]. A link to [StackOverflow](https://stackoverflow.com) is also acceptable. /// /// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example /// [inline_link]: https://foobar diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index f3cf96615..11c48dd10 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -75,10 +75,10 @@ fn test_units() { fn test_allowed() { } -/// This test has [a link_with_underscores][chunked-example] inside it. See #823. +/// This test has [a `link_with_underscores`][chunked-example] inside it. See #823. /// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues) /// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link]. -/// It can also be [inline_link2]. +/// It can also be [inline_link2]. A link to [StackOverflow](https://stackoverflow.com) is also acceptable. /// /// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example /// [inline_link]: https://foobar diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr index 40345370c..6c67c903c 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr @@ -142,28 +142,6 @@ help: try LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:78:22 - | -LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823. - | ^^^^^^^^^^^^^^^^^^^^^ - | -help: try - | -LL | /// This test has [a `link_with_underscores`][chunked-example] inside it. See #823. - | ~~~~~~~~~~~~~~~~~~~~~~~ - -error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:81:21 - | -LL | /// It can also be [inline_link2]. - | ^^^^^^^^^^^^ - | -help: try - | -LL | /// It can also be [`inline_link2`]. - | ~~~~~~~~~~~~~~ - error: item in documentation is missing backticks --> $DIR/doc-fixable.rs:91:5 | @@ -329,5 +307,5 @@ help: try LL | /// An iterator over `mycrate::Collection`'s values. | ~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 30 previous errors +error: aborting due to 28 previous errors diff --git a/src/tools/clippy/tests/ui/entry.fixed b/src/tools/clippy/tests/ui/entry.fixed index 79c29c04e..dbe09e0ff 100644 --- a/src/tools/clippy/tests/ui/entry.fixed +++ b/src/tools/clippy/tests/ui/entry.fixed @@ -152,4 +152,18 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa }); } +// Issue 10331 +// do not suggest a bad expansion because the compiler unrolls the first +// occurrence of the loop +pub fn issue_10331() { + let mut m = HashMap::new(); + let mut i = 0; + let mut x = 0; + while !m.contains_key(&x) { + m.insert(x, i); + i += 1; + x += 1; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/entry.rs b/src/tools/clippy/tests/ui/entry.rs index 2d7985457..30fed34fc 100644 --- a/src/tools/clippy/tests/ui/entry.rs +++ b/src/tools/clippy/tests/ui/entry.rs @@ -156,4 +156,18 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa } } +// Issue 10331 +// do not suggest a bad expansion because the compiler unrolls the first +// occurrence of the loop +pub fn issue_10331() { + let mut m = HashMap::new(); + let mut i = 0; + let mut x = 0; + while !m.contains_key(&x) { + m.insert(x, i); + i += 1; + x += 1; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed index 475fae5e8..5d40c8504 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed @@ -269,6 +269,9 @@ fn main() { trait WithAssoc { type Assoc: ?Sized; + fn to_assoc(&self) -> &Self::Assoc { + panic!() + } } impl WithAssoc for String { type Assoc = str; @@ -281,4 +284,15 @@ fn main() { // Issue #9901 fn takes_ref(_: &i32) {} takes_ref(*Box::new(&0i32)); + + // Issue #10384 + impl<'a> WithAssoc for &'a u32 { + type Assoc = dyn core::fmt::Display; + fn to_assoc(&self) -> &Self::Assoc { + *self + } + } + fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc { + *x + } } diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs index c1894258f..79e03f4d7 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs @@ -269,6 +269,9 @@ fn main() { trait WithAssoc { type Assoc: ?Sized; + fn to_assoc(&self) -> &Self::Assoc { + panic!() + } } impl WithAssoc for String { type Assoc = str; @@ -281,4 +284,15 @@ fn main() { // Issue #9901 fn takes_ref(_: &i32) {} takes_ref(*Box::new(&0i32)); + + // Issue #10384 + impl<'a> WithAssoc for &'a u32 { + type Assoc = dyn core::fmt::Display; + fn to_assoc(&self) -> &Self::Assoc { + *self + } + } + fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc { + *x + } } diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs new file mode 100644 index 000000000..480174342 --- /dev/null +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs @@ -0,0 +1,110 @@ +#![allow(unused, clippy::needless_lifetimes)] +#![warn(clippy::extra_unused_type_parameters)] + +fn unused_ty(x: u8) { + unimplemented!() +} + +fn unused_multi(x: u8) { + unimplemented!() +} + +fn unused_with_lt<'a, T>(x: &'a u8) { + unimplemented!() +} + +fn used_ty(x: T, y: u8) {} + +fn used_ref<'a, T>(x: &'a T) {} + +fn used_ret(x: u8) -> T { + T::default() +} + +fn unused_bounded(x: U) { + unimplemented!(); +} + +fn unused_where_clause(x: U) +where + T: Default, +{ + unimplemented!(); +} + +fn some_unused, E>(b: B, c: C) { + unimplemented!(); +} + +fn used_opaque(iter: impl Iterator) -> usize { + iter.count() +} + +fn used_ret_opaque() -> impl Iterator { + std::iter::empty() +} + +fn used_vec_box(x: Vec>) {} + +fn used_body() -> String { + T::default().to_string() +} + +fn used_closure() -> impl Fn() { + || println!("{}", T::default().to_string()) +} + +struct S; + +impl S { + fn unused_ty_impl(&self) { + unimplemented!() + } +} + +// Don't lint on trait methods +trait Foo { + fn bar(&self); +} + +impl Foo for S { + fn bar(&self) {} +} + +fn skip_index(iter: Iter, index: usize) -> impl Iterator +where + Iter: Iterator, +{ + iter.enumerate() + .filter_map(move |(i, a)| if i == index { None } else { Some(a) }) +} + +fn unused_opaque(dummy: impl Default) { + unimplemented!() +} + +mod unexported_trait_bounds { + mod private { + pub trait Private {} + } + + fn priv_trait_bound() { + unimplemented!(); + } + + fn unused_with_priv_trait_bound() { + unimplemented!(); + } +} + +mod issue10319 { + fn assert_send() {} + + fn assert_send_where() + where + T: Send, + { + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr new file mode 100644 index 000000000..86c88fc9b --- /dev/null +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr @@ -0,0 +1,75 @@ +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:4:13 + | +LL | fn unused_ty(x: u8) { + | ^^^ + | + = help: consider removing the parameter + = note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings` + +error: type parameters go unused in function definition + --> $DIR/extra_unused_type_parameters.rs:8:16 + | +LL | fn unused_multi(x: u8) { + | ^^^^^^ + | + = help: consider removing the parameters + +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:12:23 + | +LL | fn unused_with_lt<'a, T>(x: &'a u8) { + | ^ + | + = help: consider removing the parameter + +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:24:19 + | +LL | fn unused_bounded(x: U) { + | ^^^^^^^^^^^ + | + = help: consider removing the parameter + +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:28:24 + | +LL | fn unused_where_clause(x: U) + | ^^ + | + = help: consider removing the parameter + +error: type parameters go unused in function definition + --> $DIR/extra_unused_type_parameters.rs:35:16 + | +LL | fn some_unused, E>(b: B, c: C) { + | ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | + = help: consider removing the parameters + +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:60:22 + | +LL | fn unused_ty_impl(&self) { + | ^^^ + | + = help: consider removing the parameter + +error: type parameters go unused in function definition + --> $DIR/extra_unused_type_parameters.rs:82:17 + | +LL | fn unused_opaque(dummy: impl Default) { + | ^^^^^^ + | + = help: consider removing the parameters + +error: type parameter goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:95:58 + | +LL | fn unused_with_priv_trait_bound() { + | ^ + | + = help: consider removing the parameter + +error: aborting due to 9 previous errors + diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed index beedf2c1d..cd2f70ee8 100644 --- a/src/tools/clippy/tests/ui/format.fixed +++ b/src/tools/clippy/tests/ui/format.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -9,6 +10,8 @@ clippy::uninlined_format_args )] +extern crate proc_macro_with_span; + struct Foo(pub String); macro_rules! foo { @@ -87,4 +90,7 @@ fn main() { let _ = abc.to_string(); let xx = "xx"; let _ = xx.to_string(); + + // Issue #10148 + println!(proc_macro_with_span::with_span!(""something "")); } diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs index e805f1818..c22345a79 100644 --- a/src/tools/clippy/tests/ui/format.rs +++ b/src/tools/clippy/tests/ui/format.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -9,6 +10,8 @@ clippy::uninlined_format_args )] +extern crate proc_macro_with_span; + struct Foo(pub String); macro_rules! foo { @@ -89,4 +92,7 @@ fn main() { let _ = format!("{abc}"); let xx = "xx"; let _ = format!("{xx}"); + + // Issue #10148 + println!(proc_macro_with_span::with_span!(""something "")); } diff --git a/src/tools/clippy/tests/ui/format.stderr b/src/tools/clippy/tests/ui/format.stderr index 0ef0ac655..a0e5d5c8a 100644 --- a/src/tools/clippy/tests/ui/format.stderr +++ b/src/tools/clippy/tests/ui/format.stderr @@ -1,5 +1,5 @@ error: useless use of `format!` - --> $DIR/format.rs:19:5 + --> $DIR/format.rs:22:5 | LL | format!("foo"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` @@ -7,19 +7,19 @@ LL | format!("foo"); = note: `-D clippy::useless-format` implied by `-D warnings` error: useless use of `format!` - --> $DIR/format.rs:20:5 + --> $DIR/format.rs:23:5 | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:21:5 + --> $DIR/format.rs:24:5 | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:22:5 + --> $DIR/format.rs:25:5 | LL | / format!( LL | | r##"foo {{}} @@ -34,67 +34,67 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> $DIR/format.rs:27:13 + --> $DIR/format.rs:30:13 | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> $DIR/format.rs:29:5 + --> $DIR/format.rs:32:5 | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> $DIR/format.rs:37:5 + --> $DIR/format.rs:40:5 | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> $DIR/format.rs:67:5 + --> $DIR/format.rs:70:5 | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> $DIR/format.rs:69:5 + --> $DIR/format.rs:72:5 | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> $DIR/format.rs:73:18 + --> $DIR/format.rs:76:18 | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> $DIR/format.rs:77:22 + --> $DIR/format.rs:80:22 | LL | let _s: String = format!("{}", &*v.join("/n")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()` error: useless use of `format!` - --> $DIR/format.rs:83:13 + --> $DIR/format.rs:86:13 | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:85:13 + --> $DIR/format.rs:88:13 | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:89:13 + --> $DIR/format.rs:92:13 | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> $DIR/format.rs:91:13 + --> $DIR/format.rs:94:13 | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.rs b/src/tools/clippy/tests/ui/impl_trait_in_params.rs new file mode 100644 index 000000000..07560101a --- /dev/null +++ b/src/tools/clippy/tests/ui/impl_trait_in_params.rs @@ -0,0 +1,17 @@ +#![allow(unused)] +#![warn(clippy::impl_trait_in_params)] + +pub trait Trait {} +pub trait AnotherTrait {} + +// Should warn +pub fn a(_: impl Trait) {} +pub fn c(_: C, _: impl Trait) {} +fn d(_: impl AnotherTrait) {} + +// Shouldn't warn + +pub fn b(_: B) {} +fn e>(_: T) {} + +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 new file mode 100644 index 000000000..acfcc2144 --- /dev/null +++ b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr @@ -0,0 +1,25 @@ +error: '`impl Trait` used as a function parameter' + --> $DIR/impl_trait_in_params.rs:8:13 + | +LL | pub fn a(_: impl Trait) {} + | ^^^^^^^^^^ + | + = note: `-D clippy::impl-trait-in-params` implied by `-D warnings` +help: add a type paremeter + | +LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {} + | +++++++++++++++++++++++++++++++ + +error: '`impl Trait` used as a function parameter' + --> $DIR/impl_trait_in_params.rs:9:29 + | +LL | pub fn c(_: C, _: impl Trait) {} + | ^^^^^^^^^^ + | +help: add a type paremeter + | +LL | pub fn c(_: C, _: impl Trait) {} + | +++++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/large_digit_groups.fixed b/src/tools/clippy/tests/ui/large_digit_groups.fixed index 3430c137e..ea18dac06 100644 --- a/src/tools/clippy/tests/ui/large_digit_groups.fixed +++ b/src/tools/clippy/tests/ui/large_digit_groups.fixed @@ -11,7 +11,7 @@ fn main() { let _good = ( 0b1011_i64, 0o1_234_u32, - 0x0123_4567, + 0x1_234_567, 1_2345_6789, 1234_f32, 1_234.12_f32, @@ -19,7 +19,7 @@ fn main() { 1.123_4_f32, ); let _bad = ( - 0b11_0110_i64, + 0b1_10110_i64, 0xdead_beef_usize, 123_456_f32, 123_456.12_f32, diff --git a/src/tools/clippy/tests/ui/large_digit_groups.stderr b/src/tools/clippy/tests/ui/large_digit_groups.stderr index 13d108b56..19c0fae98 100644 --- a/src/tools/clippy/tests/ui/large_digit_groups.stderr +++ b/src/tools/clippy/tests/ui/large_digit_groups.stderr @@ -1,22 +1,10 @@ -error: digits of hex or binary literal not grouped by four - --> $DIR/large_digit_groups.rs:14:9 - | -LL | 0x1_234_567, - | ^^^^^^^^^^^ help: consider: `0x0123_4567` - | - = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings` - -error: digits of hex or binary literal not grouped by four - --> $DIR/large_digit_groups.rs:22:9 - | -LL | 0b1_10110_i64, - | ^^^^^^^^^^^^^ help: consider: `0b11_0110_i64` - -error: digits of hex or binary literal not grouped by four +error: digits of hex, binary or octal literal not in groups of equal size --> $DIR/large_digit_groups.rs:23:9 | LL | 0xd_e_adbee_f_usize, | ^^^^^^^^^^^^^^^^^^^ help: consider: `0xdead_beef_usize` + | + = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings` error: digit groups should be smaller --> $DIR/large_digit_groups.rs:24:9 @@ -44,5 +32,5 @@ error: digit groups should be smaller LL | 1_23456.12345_6_f64, | ^^^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_456_f64` -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.rs b/src/tools/clippy/tests/ui/len_without_is_empty.rs index 78397c2af..b5dec6c46 100644 --- a/src/tools/clippy/tests/ui/len_without_is_empty.rs +++ b/src/tools/clippy/tests/ui/len_without_is_empty.rs @@ -282,4 +282,50 @@ impl AsyncLen { } } +// issue #9520 +pub struct NonStandardLenAndIsEmptySignature; +impl NonStandardLenAndIsEmptySignature { + // don't lint + pub fn len(&self, something: usize) -> usize { + something + } + + pub fn is_empty(&self, something: usize) -> bool { + something == 0 + } +} + +// test case for #9520 with generics in the function signature +pub trait TestResource { + type NonStandardSignatureWithGenerics: Copy; + fn lookup_content(&self, item: Self::NonStandardSignatureWithGenerics) -> Result, String>; +} +pub struct NonStandardSignatureWithGenerics(u32); +impl NonStandardSignatureWithGenerics { + pub fn is_empty(self, resource: &T) -> bool + where + T: TestResource, + U: Copy + From, + { + if let Ok(Some(content)) = resource.lookup_content(self.into()) { + content.is_empty() + } else { + true + } + } + + // test case for #9520 with generics in the function signature + pub fn len(self, resource: &T) -> usize + where + T: TestResource, + U: Copy + From, + { + if let Ok(Some(content)) = resource.lookup_content(self.into()) { + content.len() + } else { + 0_usize + } + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.rs b/src/tools/clippy/tests/ui/let_underscore_untyped.rs new file mode 100644 index 000000000..bcb33c5c7 --- /dev/null +++ b/src/tools/clippy/tests/ui/let_underscore_untyped.rs @@ -0,0 +1,54 @@ +#![allow(unused)] +#![warn(clippy::let_underscore_untyped)] + +use std::future::Future; +use std::{boxed::Box, fmt::Display}; + +fn a() -> u32 { + 1 +} + +fn b(x: T) -> T { + x +} + +fn c() -> impl Display { + 1 +} + +fn d(x: &u32) -> &u32 { + x +} + +fn e() -> Result { + Ok(1) +} + +fn f() -> Box { + Box::new(1) +} + +fn main() { + let _ = a(); + let _ = b(1); + let _ = c(); + let _ = d(&1); + let _ = e(); + let _ = f(); + + _ = a(); + _ = b(1); + _ = c(); + _ = d(&1); + _ = e(); + _ = f(); + + let _: u32 = a(); + let _: u32 = b(1); + let _: &u32 = d(&1); + let _: Result<_, _> = e(); + let _: Box<_> = f(); + + #[allow(clippy::let_underscore_untyped)] + let _ = a(); +} diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr new file mode 100644 index 000000000..36c3d1214 --- /dev/null +++ b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr @@ -0,0 +1,51 @@ +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:32:5 + | +LL | let _ = a(); + | ^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + = note: `-D clippy::let-underscore-untyped` implied by `-D warnings` + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:33:5 + | +LL | let _ = b(1); + | ^^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:34:5 + | +LL | let _ = c(); + | ^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:35:5 + | +LL | let _ = d(&1); + | ^^^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:36:5 + | +LL | let _ = e(); + | ^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:37:5 + | +LL | let _ = f(); + | ^^^^^^^^^^^^ + | + = help: consider adding a type annotation or removing the `let` keyword + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr index 603d47bac..9bc7948c7 100644 --- a/src/tools/clippy/tests/ui/literals.stderr +++ b/src/tools/clippy/tests/ui/literals.stderr @@ -121,7 +121,7 @@ error: digits grouped inconsistently by underscores LL | let fail23 = 3__16___23; | ^^^^^^^^^^ help: consider: `31_623` -error: digits of hex or binary literal not grouped by four +error: digits of hex, binary or octal literal not in groups of equal size --> $DIR/literals.rs:38:18 | LL | let fail24 = 0xAB_ABC_AB; @@ -129,12 +129,6 @@ LL | let fail24 = 0xAB_ABC_AB; | = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings` -error: digits of hex or binary literal not grouped by four - --> $DIR/literals.rs:39:18 - | -LL | let fail25 = 0b01_100_101; - | ^^^^^^^^^^^^ help: consider: `0b0110_0101` - error: this is a decimal constant --> $DIR/literals.rs:46:13 | @@ -168,5 +162,5 @@ help: if you mean to use a decimal constant, remove the `0` to avoid confusion LL | let _ = 89; | ~~ -error: aborting due to 21 previous errors +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed index 638320dd6..8c7e919bf 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed @@ -29,9 +29,7 @@ fn main() { panic!("qaqaq{:?}", a); } assert!(a.is_empty(), "qaqaq{:?}", a); - if !a.is_empty() { - panic!("qwqwq"); - } + assert!(a.is_empty(), "qwqwq"); if a.len() == 3 { println!("qwq"); println!("qwq"); @@ -46,21 +44,11 @@ fn main() { println!("qwq"); } let b = vec![1, 2, 3]; - if b.is_empty() { - panic!("panic1"); - } - if b.is_empty() && a.is_empty() { - panic!("panic2"); - } - if a.is_empty() && !b.is_empty() { - panic!("panic3"); - } - if b.is_empty() || a.is_empty() { - panic!("panic4"); - } - if a.is_empty() || !b.is_empty() { - panic!("panic5"); - } + assert!(!b.is_empty(), "panic1"); + assert!(!(b.is_empty() && a.is_empty()), "panic2"); + assert!(!(a.is_empty() && !b.is_empty()), "panic3"); + assert!(!(b.is_empty() || a.is_empty()), "panic4"); + assert!(!(a.is_empty() || !b.is_empty()), "panic5"); assert!(!a.is_empty(), "with expansion {}", one!()); if a.is_empty() { let _ = 0; @@ -71,12 +59,11 @@ fn main() { fn issue7730(a: u8) { // Suggestion should preserve comment - if a > 2 { - // comment - /* this is a + // comment +/* this is a multiline comment */ - /// Doc comment - panic!("panic with comment") // comment after `panic!` - } +/// Doc comment +// comment after `panic!` +assert!(!(a > 2), "panic with comment"); } diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr index 1f2e1e308..3555ac292 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr +++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr @@ -8,6 +8,54 @@ LL | | } | = note: `-D clippy::manual-assert` implied by `-D warnings` +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:34:5 + | +LL | / if !a.is_empty() { +LL | | panic!("qwqwq"); +LL | | } + | |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");` + +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:51:5 + | +LL | / if b.is_empty() { +LL | | panic!("panic1"); +LL | | } + | |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");` + +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:54:5 + | +LL | / if b.is_empty() && a.is_empty() { +LL | | panic!("panic2"); +LL | | } + | |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");` + +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:57:5 + | +LL | / if a.is_empty() && !b.is_empty() { +LL | | panic!("panic3"); +LL | | } + | |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");` + +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:60:5 + | +LL | / if b.is_empty() || a.is_empty() { +LL | | panic!("panic4"); +LL | | } + | |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");` + +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:63:5 + | +LL | / if a.is_empty() || !b.is_empty() { +LL | | panic!("panic5"); +LL | | } + | |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");` + error: only a `panic!` in `if`-then statement --> $DIR/manual_assert.rs:66:5 | @@ -16,5 +64,22 @@ LL | | panic!("with expansion {}", one!()) LL | | } | |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());` -error: aborting due to 2 previous errors +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:78:5 + | +LL | / if a > 2 { +LL | | // comment +LL | | /* this is a +LL | | multiline +... | +LL | | panic!("panic with comment") // comment after `panic!` +LL | | } + | |_____^ + | +help: try instead + | +LL | assert!(!(a > 2), "panic with comment"); + | + +error: aborting due to 9 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 48a162c13..d175597a4 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.rs +++ b/src/tools/clippy/tests/ui/manual_let_else.rs @@ -248,4 +248,15 @@ fn not_fire() { Some(value) => value, _ => macro_call!(), }; + + // Issue 10296 + // The let/else block in the else part is not divergent despite the presence of return + let _x = if let Some(x) = Some(1) { + x + } else { + let Some(_z) = Some(3) else { + return + }; + 1 + }; } 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 28caed9d7..73b746791 100644 --- a/src/tools/clippy/tests/ui/manual_let_else_match.rs +++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs @@ -42,13 +42,13 @@ fn fire() { loop { // More complex pattern for the identity arm and diverging arm let v = match h() { - (Some(_), Some(_)) | (None, None) => continue, (Some(v), None) | (None, Some(v)) => v, + (Some(_), Some(_)) | (None, None) => continue, }; // Custom enums are supported as long as the "else" arm is a simple _ let v = match build_enum() { - _ => continue, Variant::Bar(v) | Variant::Baz(v) => v, + _ => continue, }; } @@ -71,6 +71,12 @@ fn fire() { Variant::Bar(_) | Variant::Baz(_) => (), _ => return, }; + + let data = [1_u8, 2, 3, 4, 0, 0, 0, 0]; + let data = match data.as_slice() { + [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, + _ => return, + }; } fn not_fire() { @@ -125,4 +131,23 @@ fn not_fire() { Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v, Err(Variant::Foo) => return, }; + + // Issue 10241 + // The non-divergent arm arrives in second position and + // may cover values already matched in the first arm. + let v = match h() { + (Some(_), Some(_)) | (None, None) => return, + (Some(v), _) | (None, Some(v)) => v, + }; + + let v = match build_enum() { + _ => return, + Variant::Bar(v) | Variant::Baz(v) => v, + }; + + let data = [1_u8, 2, 3, 4, 0, 0, 0, 0]; + let data = match data.as_slice() { + [] | [0, 0] => return, + [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data, + }; } 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 cd5e9a9ac..7abaa0b85 100644 --- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr +++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr @@ -22,8 +22,8 @@ error: this could be rewritten as `let...else` --> $DIR/manual_let_else_match.rs:44:9 | LL | / let v = match h() { -LL | | (Some(_), Some(_)) | (None, None) => continue, LL | | (Some(v), None) | (None, Some(v)) => v, +LL | | (Some(_), Some(_)) | (None, None) => continue, LL | | }; | |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };` @@ -31,8 +31,8 @@ error: this could be rewritten as `let...else` --> $DIR/manual_let_else_match.rs:49:9 | LL | / let v = match build_enum() { -LL | | _ => continue, LL | | Variant::Bar(v) | Variant::Baz(v) => v, +LL | | _ => continue, LL | | }; | |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };` @@ -63,5 +63,14 @@ LL | | _ => return, LL | | }; | |______^ help: consider writing: `let (Variant::Bar(_) | Variant::Baz(_)) = f else { return };` -error: aborting due to 7 previous errors +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else_match.rs:76:5 + | +LL | / let data = match data.as_slice() { +LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, +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 8 previous errors diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed index 53628ef65..8e2f11389 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed @@ -1,6 +1,7 @@ // run-rustfix #![warn(clippy::all, clippy::pedantic)] +#![allow(clippy::let_underscore_untyped)] #![allow(clippy::missing_docs_in_private_items)] #![allow(clippy::map_identity)] #![allow(clippy::redundant_closure)] diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs index 76016c8ed..a783a99c4 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs @@ -1,6 +1,7 @@ // run-rustfix #![warn(clippy::all, clippy::pedantic)] +#![allow(clippy::let_underscore_untyped)] #![allow(clippy::missing_docs_in_private_items)] #![allow(clippy::map_identity)] #![allow(clippy::redundant_closure)] diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr index b6b0c4d09..c91f0b9ae 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr @@ -1,5 +1,5 @@ error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:17:47 + --> $DIR/map_flatten_fixable.rs:18:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)` @@ -7,43 +7,43 @@ LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().coll = note: `-D clippy::map-flatten` implied by `-D warnings` error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:18:47 + --> $DIR/map_flatten_fixable.rs:19:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)` error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:19:47 + --> $DIR/map_flatten_fixable.rs:20:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)` error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:20:47 + --> $DIR/map_flatten_fixable.rs:21:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))` error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:23:47 + --> $DIR/map_flatten_fixable.rs:24:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)` error: called `map(..).flatten()` on `Option` - --> $DIR/map_flatten_fixable.rs:26:40 + --> $DIR/map_flatten_fixable.rs:27:40 | LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Result` - --> $DIR/map_flatten_fixable.rs:29:42 + --> $DIR/map_flatten_fixable.rs:30:42 | LL | let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Iterator` - --> $DIR/map_flatten_fixable.rs:38:10 + --> $DIR/map_flatten_fixable.rs:39:10 | LL | .map(|n| match n { | __________^ @@ -72,7 +72,7 @@ LL ~ }); | error: called `map(..).flatten()` on `Option` - --> $DIR/map_flatten_fixable.rs:58:10 + --> $DIR/map_flatten_fixable.rs:59:10 | LL | .map(|_| { | __________^ diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed index fc252cdd3..9fd3739b6 100644 --- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed +++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed @@ -123,7 +123,7 @@ fn main() { Enum::A => (), Enum::B => (), Enum::C => (), - _ => (), + Enum::__Private => (), } match Enum::A { Enum::A => (), diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr index 6fa313dc9..105b4c4b4 100644 --- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr +++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr @@ -48,11 +48,17 @@ error: wildcard matches only a single variant and will also match any future add LL | _ => (), | ^ help: try this: `Color::Blue` +error: wildcard matches only a single variant and will also match any future added variants + --> $DIR/match_wildcard_for_single_variants.rs:126:13 + | +LL | _ => (), + | ^ help: try this: `Enum::__Private` + error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:153:13 | LL | _ => 2, | ^ help: try this: `Foo::B` -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs index 6f22366ea..1519e4da9 100644 --- a/src/tools/clippy/tests/ui/methods.rs +++ b/src/tools/clippy/tests/ui/methods.rs @@ -4,6 +4,7 @@ #![allow( clippy::disallowed_names, clippy::default_trait_access, + clippy::let_underscore_untyped, clippy::missing_docs_in_private_items, clippy::missing_safety_doc, clippy::non_ascii_literal, diff --git a/src/tools/clippy/tests/ui/methods.stderr b/src/tools/clippy/tests/ui/methods.stderr index b63672dd6..4643e09e2 100644 --- a/src/tools/clippy/tests/ui/methods.stderr +++ b/src/tools/clippy/tests/ui/methods.stderr @@ -1,5 +1,5 @@ error: methods called `new` usually return `Self` - --> $DIR/methods.rs:104:5 + --> $DIR/methods.rs:105:5 | LL | / fn new() -> i32 { LL | | 0 @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::new-ret-no-self` implied by `-D warnings` error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> $DIR/methods.rs:125:13 + --> $DIR/methods.rs:126:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr index f22fa19db..b410f56e1 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr @@ -51,13 +51,13 @@ LL | | fn foo_with_impl(&self) {} LL | | } | |_^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:44:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:45:5 | LL | fn foo_with_impl(&self) {} diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.stderr b/src/tools/clippy/tests/ui/module_name_repetitions.stderr index 3f343a3e4..277801194 100644 --- a/src/tools/clippy/tests/ui/module_name_repetitions.stderr +++ b/src/tools/clippy/tests/ui/module_name_repetitions.stderr @@ -1,34 +1,34 @@ error: item name starts with its containing module's name - --> $DIR/module_name_repetitions.rs:8:5 + --> $DIR/module_name_repetitions.rs:8:12 | LL | pub fn foo_bar() {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ | = note: `-D clippy::module-name-repetitions` implied by `-D warnings` error: item name ends with its containing module's name - --> $DIR/module_name_repetitions.rs:9:5 + --> $DIR/module_name_repetitions.rs:9:12 | LL | pub fn bar_foo() {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: item name starts with its containing module's name - --> $DIR/module_name_repetitions.rs:10:5 + --> $DIR/module_name_repetitions.rs:10:16 | LL | pub struct FooCake; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: item name ends with its containing module's name - --> $DIR/module_name_repetitions.rs:11:5 + --> $DIR/module_name_repetitions.rs:11:14 | LL | pub enum CakeFoo {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: item name starts with its containing module's name - --> $DIR/module_name_repetitions.rs:12:5 + --> $DIR/module_name_repetitions.rs:12:16 | LL | pub struct Foo7Bar; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: aborting due to 5 previous errors 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 new file mode 100644 index 000000000..4511bc99c --- /dev/null +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -0,0 +1,119 @@ +// aux-build:macro_rules.rs +#![allow(unused)] +#![allow(deref_nullptr)] +#![allow(clippy::unnecessary_operation)] +#![allow(clippy::drop_copy)] +#![warn(clippy::multiple_unsafe_ops_per_block)] + +#[macro_use] +extern crate macro_rules; + +use core::arch::asm; + +fn raw_ptr() -> *const () { + core::ptr::null() +} + +unsafe fn not_very_safe() {} + +struct Sample; + +impl Sample { + unsafe fn not_very_safe(&self) {} +} + +#[allow(non_upper_case_globals)] +const sample: Sample = Sample; + +union U { + i: i32, + u: u32, +} + +static mut STATIC: i32 = 0; + +fn test1() { + unsafe { + STATIC += 1; + not_very_safe(); + } +} + +fn test2() { + let u = U { i: 0 }; + + unsafe { + drop(u.u); + *raw_ptr(); + } +} + +fn test3() { + unsafe { + asm!("nop"); + sample.not_very_safe(); + STATIC = 0; + } +} + +fn test_all() { + let u = U { i: 0 }; + unsafe { + drop(u.u); + drop(STATIC); + sample.not_very_safe(); + not_very_safe(); + *raw_ptr(); + asm!("nop"); + } +} + +// no lint +fn correct1() { + unsafe { + STATIC += 1; + } +} + +// no lint +fn correct2() { + unsafe { + STATIC += 1; + } + + unsafe { + *raw_ptr(); + } +} + +// no lint +fn correct3() { + let u = U { u: 0 }; + + unsafe { + not_very_safe(); + } + + unsafe { + drop(u.i); + } +} + +// tests from the issue (https://github.com/rust-lang/rust-clippy/issues/10064) + +unsafe fn read_char_bad(ptr: *const u8) -> char { + unsafe { char::from_u32_unchecked(*ptr.cast::()) } +} + +// no lint +unsafe fn read_char_good(ptr: *const u8) -> char { + let int_value = unsafe { *ptr.cast::() }; + unsafe { core::char::from_u32_unchecked(int_value) } +} + +// no lint +fn issue10259() { + unsafe_macro!(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr new file mode 100644 index 000000000..303aeb7ae --- /dev/null +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -0,0 +1,129 @@ +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:36:5 + | +LL | / unsafe { +LL | | STATIC += 1; +LL | | not_very_safe(); +LL | | } + | |_____^ + | +note: modification of a mutable static occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:37:9 + | +LL | STATIC += 1; + | ^^^^^^^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:38:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ + = note: `-D clippy::multiple-unsafe-ops-per-block` implied by `-D warnings` + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:45:5 + | +LL | / unsafe { +LL | | drop(u.u); +LL | | *raw_ptr(); +LL | | } + | |_____^ + | +note: union field access occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:46:14 + | +LL | drop(u.u); + | ^^^ +note: raw pointer dereference occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:47:9 + | +LL | *raw_ptr(); + | ^^^^^^^^^^ + +error: this `unsafe` block contains 3 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:52:5 + | +LL | / unsafe { +LL | | asm!("nop"); +LL | | sample.not_very_safe(); +LL | | STATIC = 0; +LL | | } + | |_____^ + | +note: inline assembly used here + --> $DIR/multiple_unsafe_ops_per_block.rs:53:9 + | +LL | asm!("nop"); + | ^^^^^^^^^^^ +note: unsafe method call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:54:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ +note: modification of a mutable static occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:55:9 + | +LL | STATIC = 0; + | ^^^^^^^^^^ + +error: this `unsafe` block contains 6 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:61:5 + | +LL | / unsafe { +LL | | drop(u.u); +LL | | drop(STATIC); +LL | | sample.not_very_safe(); +... | +LL | | asm!("nop"); +LL | | } + | |_____^ + | +note: union field access occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:62:14 + | +LL | drop(u.u); + | ^^^ +note: access of a mutable static occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:63:14 + | +LL | drop(STATIC); + | ^^^^^^ +note: unsafe method call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:64:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:65:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ +note: raw pointer dereference occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:66:9 + | +LL | *raw_ptr(); + | ^^^^^^^^^^ +note: inline assembly used here + --> $DIR/multiple_unsafe_ops_per_block.rs:67:9 + | +LL | asm!("nop"); + | ^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:105:5 + | +LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:105:14 + | +LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: raw pointer dereference occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:105:39 + | +LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed index 04a74a009..bbbb3cf62 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.fixed +++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed @@ -84,7 +84,7 @@ pub unsafe fn mutates_static() -> usize { } #[no_mangle] -pub fn unmangled(i: bool) -> bool { +pub extern "C" fn unmangled(i: bool) -> bool { !i } diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs index f04122f4e..94d3c83bd 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.rs +++ b/src/tools/clippy/tests/ui/must_use_candidates.rs @@ -84,7 +84,7 @@ pub unsafe fn mutates_static() -> usize { } #[no_mangle] -pub fn unmangled(i: bool) -> bool { +pub extern "C" fn unmangled(i: bool) -> bool { !i } diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed new file mode 100644 index 000000000..f0f1f9298 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed @@ -0,0 +1,548 @@ +// run-rustfix +// aux-build:macro_rules.rs + +#![warn(clippy::needless_lifetimes)] +#![allow( + unused, + clippy::boxed_local, + clippy::extra_unused_type_parameters, + clippy::needless_pass_by_value, + clippy::unnecessary_wraps, + dyn_drop, + clippy::get_first +)] + +#[macro_use] +extern crate macro_rules; + +fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} + +fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {} + +// No error; same lifetime on two params. +fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {} + +// No error; static involved. +fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} + +fn mut_and_static_input(_x: &mut u8, _y: &'static str) {} + +fn in_and_out(x: &u8, _y: u8) -> &u8 { + x +} + +// No error; multiple input refs. +fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { + x +} + +// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: +// fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 +// ^^^ +fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { + x +} + +// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: +// fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 +// ^^^ +fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { + y +} + +// No error; multiple input refs +async fn func<'a>(args: &[&'a str]) -> Option<&'a str> { + args.get(0).cloned() +} + +// No error; static involved. +fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 { + x +} + +// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: +// fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> +// ^^^ +fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { + Ok(x) +} + +// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: +// fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> +// ^^^ +fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { + Ok(y) +} + +// No error; two input refs. +fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { + x.unwrap() +} + +fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { + Ok(x) +} + +// Where-clause, but without lifetimes. +fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> +where + T: Copy, +{ + Ok(x) +} + +type Ref<'r> = &'r u8; + +// No error; same lifetime on two params. +fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} + +fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} + +// No error; bounded lifetime. +fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} + +// No error; bounded lifetime. +fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8) +where + 'b: 'a, +{ +} + +struct Lt<'a, I: 'static> { + x: &'a I, +} + +// No error; fn bound references `'a`. +fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +where + F: Fn(Lt<'a, I>) -> Lt<'a, I>, +{ + unreachable!() +} + +fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> +where + for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, +{ + unreachable!() +} + +// No error; see below. +fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) { + f(x); +} + +fn fn_bound_3_cannot_elide() { + let x = 42; + let p = &x; + let mut q = &x; + // This will fail if we elide lifetimes of `fn_bound_3`. + fn_bound_3(p, |y| q = y); +} + +// No error; multiple input refs. +fn fn_bound_4<'a, F: FnOnce() -> &'a ()>(cond: bool, x: &'a (), f: F) -> &'a () { + if cond { x } else { f() } +} + +struct X { + x: u8, +} + +impl X { + fn self_and_out(&self) -> &u8 { + &self.x + } + + // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: + // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 + // ^^^ + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { + &self.x + } + + // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid: + // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 + // ^^^^^ + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { + x + } + + fn distinct_self_and_in(&self, _x: &u8) {} + + // No error; same lifetimes on two params. + fn self_and_same_in<'s>(&'s self, _x: &'s u8) {} +} + +struct Foo<'a>(&'a u8); + +impl<'a> Foo<'a> { + // No error; lifetime `'a` not defined in method. + fn self_shared_lifetime(&self, _: &'a u8) {} + // No error; bounds exist. + fn self_bound_lifetime<'b: 'a>(&self, _: &'b u8) {} +} + +fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { + unimplemented!() +} + +fn struct_with_lt(_foo: Foo<'_>) -> &str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `Foo`). +fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `Foo`). +fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { + unimplemented!() +} + +// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is +// valid: +// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str +// ^^ +fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { + unimplemented!() +} + +// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is +// valid: +// fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str +// ^^^^ +fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { + unimplemented!() +} + +trait WithLifetime<'a> {} + +type WithLifetimeAlias<'a> = dyn WithLifetime<'a>; + +// Should not warn because it won't build without the lifetime. +fn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str { + unimplemented!() +} + +// Should warn because there is no lifetime on `Drop`, so this would be +// unambiguous if we elided the lifetime. +fn trait_obj_elided2(_arg: &dyn Drop) -> &str { + unimplemented!() +} + +type FooAlias<'a> = Foo<'a>; + +fn alias_with_lt(_foo: FooAlias<'_>) -> &str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`). +fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`). +fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { + unimplemented!() +} + +// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is +// valid: +// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str +// ^^ +fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { + unimplemented!() +} + +// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is +// valid: +// fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str +// ^^^^^^^^^ +fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { + unimplemented!() +} + +fn named_input_elided_output(_arg: &str) -> &str { + unimplemented!() +} + +fn elided_input_named_output<'a>(_arg: &str) -> &'a str { + unimplemented!() +} + +fn trait_bound_ok>(_: &u8, _: T) { + unimplemented!() +} +fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { + unimplemented!() +} + +// Don't warn on these; see issue #292. +fn trait_bound_bug<'a, T: WithLifetime<'a>>() { + unimplemented!() +} + +// See issue #740. +struct Test { + vec: Vec, +} + +impl Test { + fn iter<'a>(&'a self) -> Box + 'a> { + unimplemented!() + } +} + +trait LintContext<'a> {} + +fn f<'a, T: LintContext<'a>>(_: &T) {} + +fn test<'a>(x: &'a [u8]) -> u8 { + let y: &'a u8 = &x[5]; + *y +} + +// Issue #3284: give hint regarding lifetime in return type. +struct Cow<'a> { + x: &'a str, +} +fn out_return_type_lts(e: &str) -> Cow<'_> { + unimplemented!() +} + +// Make sure we still warn on implementations +mod issue4291 { + trait BadTrait { + fn needless_lt(x: &u8) {} + } + + impl BadTrait for () { + fn needless_lt(_x: &u8) {} + } +} + +mod issue2944 { + trait Foo {} + struct Bar; + struct Baz<'a> { + bar: &'a Bar, + } + + impl<'a> Foo for Baz<'a> {} + impl Bar { + fn baz(&self) -> impl Foo + '_ { + Baz { bar: self } + } + } +} + +mod nested_elision_sites { + // issue #issue2944 + + // closure trait bounds subject to nested elision + // don't lint because they refer to outer lifetimes + fn trait_fn<'a>(i: &'a i32) -> impl Fn() -> &'a i32 { + move || i + } + fn trait_fn_mut<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 { + move || i + } + fn trait_fn_once<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 { + move || i + } + + // don't lint + fn impl_trait_in_input_position<'a>(f: impl Fn() -> &'a i32) -> &'a i32 { + f() + } + fn impl_trait_in_output_position<'a>(i: &'a i32) -> impl Fn() -> &'a i32 { + move || i + } + // lint + fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 { + f(i) + } + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 { + f(i) + } + + // don't lint + fn generics_not_elidable<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 { + f() + } + // lint + fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { + f(i) + } + + // don't lint + fn where_clause_not_elidable<'a, T>(f: T) -> &'a i32 + where + T: Fn() -> &'a i32, + { + f() + } + // lint + fn where_clause_elidadable(i: &i32, f: T) -> &i32 + where + T: Fn(&i32) -> &i32, + { + f(i) + } + + // don't lint + fn pointer_fn_in_input_position<'a>(f: fn(&'a i32) -> &'a i32, i: &'a i32) -> &'a i32 { + f(i) + } + fn pointer_fn_in_output_position<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 { + |i| i + } + // lint + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { + f(i) + } + + // don't lint + fn nested_fn_pointer_1<'a>(_: &'a i32) -> fn(fn(&'a i32) -> &'a i32) -> i32 { + |f| 42 + } + fn nested_fn_pointer_2<'a>(_: &'a i32) -> impl Fn(fn(&'a i32)) { + |f| () + } + + // lint + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { + |f| 42 + } + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { + |f| () + } +} + +mod issue6159 { + use std::ops::Deref; + pub fn apply_deref<'a, T, F, R>(x: &'a T, f: F) -> R + where + T: Deref, + F: FnOnce(&'a T::Target) -> R, + { + f(x.deref()) + } +} + +mod issue7296 { + use std::rc::Rc; + use std::sync::Arc; + + struct Foo; + impl Foo { + fn implicit(&self) -> &() { + &() + } + fn implicit_mut(&mut self) -> &() { + &() + } + + fn explicit<'a>(self: &'a Arc) -> &'a () { + &() + } + fn explicit_mut<'a>(self: &'a mut Rc) -> &'a () { + &() + } + + fn lifetime_elsewhere(self: Box, here: &()) -> &() { + &() + } + } + + trait Bar { + fn implicit(&self) -> &(); + fn implicit_provided(&self) -> &() { + &() + } + + fn explicit<'a>(self: &'a Arc) -> &'a (); + fn explicit_provided<'a>(self: &'a Arc) -> &'a () { + &() + } + + fn lifetime_elsewhere(self: Box, here: &()) -> &(); + fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { + &() + } + } +} + +mod pr_9743_false_negative_fix { + #![allow(unused)] + + fn foo(x: &u8, y: &'_ u8) {} + + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} +} + +mod pr_9743_output_lifetime_checks { + #![allow(unused)] + + // lint: only one input + fn one_input(x: &u8) -> &u8 { + unimplemented!() + } + + // lint: multiple inputs, output would not be elided + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 { + unimplemented!() + } + + // don't lint: multiple inputs, output would be elided (which would create an ambiguity) + fn multiple_inputs_output_would_be_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'a u8 { + unimplemented!() + } +} + +mod in_macro { + macro_rules! local_one_input_macro { + () => { + fn one_input(x: &u8) -> &u8 { + unimplemented!() + } + }; + } + + // lint local macro expands to function with needless lifetimes + local_one_input_macro!(); + + // no lint on external macro + macro_rules::needless_lifetime!(); + + macro_rules! expanded_lifetime { + ($l:lifetime) => { + fn f<$l>(arg: &$l str) -> &$l str { + arg + } + } + } + + expanded_lifetime!('a); +} + +mod issue5787 { + use std::sync::MutexGuard; + + struct Foo; + + impl Foo { + // doesn't get linted without async + pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> { + guard + } + } + + async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str { + y + } +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs index 2efc93675..ddfd10430 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.rs +++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs @@ -1,13 +1,20 @@ +// run-rustfix +// aux-build:macro_rules.rs + #![warn(clippy::needless_lifetimes)] #![allow( - dead_code, + unused, clippy::boxed_local, + clippy::extra_unused_type_parameters, clippy::needless_pass_by_value, clippy::unnecessary_wraps, dyn_drop, clippy::get_first )] +#[macro_use] +extern crate macro_rules; + fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} @@ -495,4 +502,47 @@ mod pr_9743_output_lifetime_checks { } } +mod in_macro { + macro_rules! local_one_input_macro { + () => { + fn one_input<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + }; + } + + // lint local macro expands to function with needless lifetimes + local_one_input_macro!(); + + // no lint on external macro + macro_rules::needless_lifetime!(); + + macro_rules! expanded_lifetime { + ($l:lifetime) => { + fn f<$l>(arg: &$l str) -> &$l str { + arg + } + } + } + + expanded_lifetime!('a); +} + +mod issue5787 { + use std::sync::MutexGuard; + + struct Foo; + + impl Foo { + // doesn't get linted without async + pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> { + guard + } + } + + async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str { + y + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr index 5a7cf13c8..4e3c8f20d 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr +++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr @@ -1,316 +1,559 @@ error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:11:1 + --> $DIR/needless_lifetimes.rs:18:1 | LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::needless-lifetimes` implied by `-D warnings` +help: elide the lifetimes + | +LL - fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} +LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} + | error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:13:1 + --> $DIR/needless_lifetimes.rs:20:1 | LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} +LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:23:1 + --> $DIR/needless_lifetimes.rs:30:1 | LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { +LL + fn in_and_out(x: &u8, _y: u8) -> &u8 { + | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:35:1 + --> $DIR/needless_lifetimes.rs:42:1 | LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { +LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:42:1 + --> $DIR/needless_lifetimes.rs:49:1 | LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { +LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { + | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:59:1 + --> $DIR/needless_lifetimes.rs:66:1 | LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { +LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:66:1 + --> $DIR/needless_lifetimes.rs:73:1 | LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { +LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:75:1 + --> $DIR/needless_lifetimes.rs:82:1 | LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { +LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:80:1 + --> $DIR/needless_lifetimes.rs:87:1 | LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> +LL + fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> + | error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:92:1 + --> $DIR/needless_lifetimes.rs:99:1 | LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:92:37 +help: elide the lifetimes + | +LL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} +LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} | -LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} - | ^^ error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:116:1 + --> $DIR/needless_lifetimes.rs:123:1 | LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:116:32 +help: elide the lifetimes + | +LL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +LL + fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> | -LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> - | ^^ error: the following explicit lifetimes could be elided: 's - --> $DIR/needless_lifetimes.rs:146:5 + --> $DIR/needless_lifetimes.rs:153:5 | LL | fn self_and_out<'s>(&'s self) -> &'s u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn self_and_out<'s>(&'s self) -> &'s u8 { +LL + fn self_and_out(&self) -> &u8 { + | error: the following explicit lifetimes could be elided: 't - --> $DIR/needless_lifetimes.rs:153:5 + --> $DIR/needless_lifetimes.rs:160:5 | LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { +LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { + | error: the following explicit lifetimes could be elided: 's - --> $DIR/needless_lifetimes.rs:160:5 + --> $DIR/needless_lifetimes.rs:167:5 | LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { +LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { + | error: the following explicit lifetimes could be elided: 's, 't - --> $DIR/needless_lifetimes.rs:164:5 + --> $DIR/needless_lifetimes.rs:171:5 | LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} +LL + fn distinct_self_and_in(&self, _x: &u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:183:1 + --> $DIR/needless_lifetimes.rs:190:1 | LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:183:33 +help: elide the lifetimes + | +LL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { +LL + fn struct_with_lt(_foo: Foo<'_>) -> &str { | -LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { - | ^^ error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:201:1 + --> $DIR/needless_lifetimes.rs:208:1 | LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:201:43 +help: elide the lifetimes + | +LL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { +LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { | -LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { - | ^^ error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:209:1 + --> $DIR/needless_lifetimes.rs:216:1 | LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { +LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:224:1 + --> $DIR/needless_lifetimes.rs:231:1 | LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { +LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:230:1 + --> $DIR/needless_lifetimes.rs:237:1 | LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:230:37 +help: elide the lifetimes + | +LL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { +LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str { | -LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { - | ^^ error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:248:1 + --> $DIR/needless_lifetimes.rs:255:1 | LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:248:47 +help: elide the lifetimes + | +LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { +LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { | -LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { - | ^^ error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:256:1 + --> $DIR/needless_lifetimes.rs:263:1 | LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { +LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:260:1 + --> $DIR/needless_lifetimes.rs:267:1 | LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn named_input_elided_output<'a>(_arg: &'a str) -> &str { +LL + fn named_input_elided_output(_arg: &str) -> &str { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:268:1 + --> $DIR/needless_lifetimes.rs:275:1 | LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { +LL + fn trait_bound_ok>(_: &u8, _: T) { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:304:1 + --> $DIR/needless_lifetimes.rs:311:1 | LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace with `'_` in generic arguments such as here - --> $DIR/needless_lifetimes.rs:304:47 +help: elide the lifetimes + | +LL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { +LL + fn out_return_type_lts(e: &str) -> Cow<'_> { | -LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { - | ^^ error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:311:9 + --> $DIR/needless_lifetimes.rs:318:9 | LL | fn needless_lt<'a>(x: &'a u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn needless_lt<'a>(x: &'a u8) {} +LL + fn needless_lt(x: &u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:315:9 + --> $DIR/needless_lifetimes.rs:322:9 | LL | fn needless_lt<'a>(_x: &'a u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn needless_lt<'a>(_x: &'a u8) {} +LL + fn needless_lt(_x: &u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:328:9 + --> $DIR/needless_lifetimes.rs:335:9 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn baz<'a>(&'a self) -> impl Foo + 'a { +LL + fn baz(&self) -> impl Foo + '_ { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:360:5 + --> $DIR/needless_lifetimes.rs:367:5 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { +LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:369:5 + --> $DIR/needless_lifetimes.rs:376:5 | LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { +LL + fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:381:5 + --> $DIR/needless_lifetimes.rs:388:5 | LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32 +LL + fn where_clause_elidadable(i: &i32, f: T) -> &i32 + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:396:5 + --> $DIR/needless_lifetimes.rs:403:5 | LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { +LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:409:5 + --> $DIR/needless_lifetimes.rs:416:5 | LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { +LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:412:5 + --> $DIR/needless_lifetimes.rs:419:5 | LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { +LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:434:9 + --> $DIR/needless_lifetimes.rs:441:9 | LL | fn implicit<'a>(&'a self) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn implicit<'a>(&'a self) -> &'a () { +LL + fn implicit(&self) -> &() { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:437:9 + --> $DIR/needless_lifetimes.rs:444:9 | LL | fn implicit_mut<'a>(&'a mut self) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn implicit_mut<'a>(&'a mut self) -> &'a () { +LL + fn implicit_mut(&mut self) -> &() { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:448:9 + --> $DIR/needless_lifetimes.rs:455:9 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { +LL + fn lifetime_elsewhere(self: Box, here: &()) -> &() { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:454:9 + --> $DIR/needless_lifetimes.rs:461:9 | LL | fn implicit<'a>(&'a self) -> &'a (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn implicit<'a>(&'a self) -> &'a (); +LL + fn implicit(&self) -> &(); + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:455:9 + --> $DIR/needless_lifetimes.rs:462:9 | LL | fn implicit_provided<'a>(&'a self) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn implicit_provided<'a>(&'a self) -> &'a () { +LL + fn implicit_provided(&self) -> &() { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:464:9 + --> $DIR/needless_lifetimes.rs:471:9 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); +LL + fn lifetime_elsewhere(self: Box, here: &()) -> &(); + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:465:9 + --> $DIR/needless_lifetimes.rs:472:9 | LL | fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { +LL + fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:474:5 + --> $DIR/needless_lifetimes.rs:481:5 | LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn foo<'a>(x: &'a u8, y: &'_ u8) {} +LL + fn foo(x: &u8, y: &'_ u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:476:5 + --> $DIR/needless_lifetimes.rs:483:5 | LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} +LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:483:5 + --> $DIR/needless_lifetimes.rs:490:5 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { +LL + fn one_input(x: &u8) -> &u8 { + | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:488:5 + --> $DIR/needless_lifetimes.rs:495:5 | LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: elide the lifetimes + | +LL - fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { +LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 { + | + +error: the following explicit lifetimes could be elided: 'a + --> $DIR/needless_lifetimes.rs:508:13 + | +LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | local_one_input_macro!(); + | ------------------------ in this macro invocation + | + = note: this error originates in the macro `local_one_input_macro` (in Nightly builds, run with -Z macro-backtrace for more info) +help: elide the lifetimes + | +LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { +LL + fn one_input(x: &u8) -> &u8 { + | -error: aborting due to 45 previous errors +error: aborting due to 46 previous errors diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr index b31544ec3..cffa19bec 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop.stderr +++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr @@ -49,7 +49,7 @@ error: the loop variable `i` is used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator +help: consider using an iterator and enumerate() | LL | for (i, ) in vec.iter().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ @@ -126,7 +126,7 @@ error: the loop variable `i` is used to index `vec` LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator +help: consider using an iterator and enumerate() | LL | for (i, ) in vec.iter().enumerate().skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -137,7 +137,7 @@ error: the loop variable `i` is used to index `vec` LL | for i in 5..10 { | ^^^^^ | -help: consider using an iterator +help: consider using an iterator and enumerate() | LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -148,7 +148,7 @@ error: the loop variable `i` is used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator +help: consider using an iterator and enumerate() | LL | for (i, ) in vec.iter_mut().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index ab1c0e590..0f525dd29 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -31,6 +31,16 @@ fn test_no_semicolon() -> bool { true } +#[rustfmt::skip] +fn test_multiple_semicolon() -> bool { + true +} + +#[rustfmt::skip] +fn test_multiple_semicolon_with_spaces() -> bool { + true +} + fn test_if_block() -> bool { if true { true @@ -287,4 +297,14 @@ fn issue10051() -> Result { } } +mod issue10049 { + fn single() -> u32 { + if true { 1 } else { 2 } + } + + fn multiple(b1: bool, b2: bool, b3: bool) -> u32 { + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }) + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index abed338bb..a1db8375d 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -31,6 +31,16 @@ fn test_no_semicolon() -> bool { return true; } +#[rustfmt::skip] +fn test_multiple_semicolon() -> bool { + return true;;; +} + +#[rustfmt::skip] +fn test_multiple_semicolon_with_spaces() -> bool { + return true;; ; ; +} + fn test_if_block() -> bool { if true { return true; @@ -297,4 +307,14 @@ fn issue10051() -> Result { } } +mod issue10049 { + fn single() -> u32 { + return if true { 1 } else { 2 }; + } + + fn multiple(b1: bool, b2: bool, b3: bool) -> u32 { + return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr index 52eabf6e1..87d0cd3e1 100644 --- a/src/tools/clippy/tests/ui/needless_return.stderr +++ b/src/tools/clippy/tests/ui/needless_return.stderr @@ -16,7 +16,23 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:36:9 + --> $DIR/needless_return.rs:36:5 + | +LL | return true;;; + | ^^^^^^^^^^^ + | + = help: remove `return` + +error: unneeded `return` statement + --> $DIR/needless_return.rs:41:5 + | +LL | return true;; ; ; + | ^^^^^^^^^^^ + | + = help: remove `return` + +error: unneeded `return` statement + --> $DIR/needless_return.rs:46:9 | LL | return true; | ^^^^^^^^^^^ @@ -24,7 +40,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:38:9 + --> $DIR/needless_return.rs:48:9 | LL | return false; | ^^^^^^^^^^^^ @@ -32,7 +48,7 @@ LL | return false; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:44:17 + --> $DIR/needless_return.rs:54:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -40,7 +56,7 @@ LL | true => return false, = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:46:13 + --> $DIR/needless_return.rs:56:13 | LL | return true; | ^^^^^^^^^^^ @@ -48,7 +64,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:53:9 + --> $DIR/needless_return.rs:63:9 | LL | return true; | ^^^^^^^^^^^ @@ -56,7 +72,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:55:16 + --> $DIR/needless_return.rs:65:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -64,7 +80,7 @@ LL | let _ = || return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:59:5 + --> $DIR/needless_return.rs:69:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +88,7 @@ LL | return the_answer!(); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:62:21 + --> $DIR/needless_return.rs:72:21 | LL | fn test_void_fun() { | _____________________^ @@ -82,7 +98,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:67:11 + --> $DIR/needless_return.rs:77:11 | LL | if b { | ___________^ @@ -92,7 +108,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:69:13 + --> $DIR/needless_return.rs:79:13 | LL | } else { | _____________^ @@ -102,7 +118,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:77:14 + --> $DIR/needless_return.rs:87:14 | LL | _ => return, | ^^^^^^ @@ -110,7 +126,7 @@ LL | _ => return, = help: replace `return` with a unit value error: unneeded `return` statement - --> $DIR/needless_return.rs:85:24 + --> $DIR/needless_return.rs:95:24 | LL | let _ = 42; | ________________________^ @@ -120,7 +136,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:88:14 + --> $DIR/needless_return.rs:98:14 | LL | _ => return, | ^^^^^^ @@ -128,7 +144,7 @@ LL | _ => return, = help: replace `return` with a unit value error: unneeded `return` statement - --> $DIR/needless_return.rs:101:9 + --> $DIR/needless_return.rs:111:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +152,7 @@ LL | return String::from("test"); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:103:9 + --> $DIR/needless_return.rs:113:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +160,7 @@ LL | return String::new(); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:125:32 + --> $DIR/needless_return.rs:135:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ @@ -152,7 +168,7 @@ LL | bar.unwrap_or_else(|_| return) = help: replace `return` with an empty block error: unneeded `return` statement - --> $DIR/needless_return.rs:129:21 + --> $DIR/needless_return.rs:139:21 | LL | let _ = || { | _____________________^ @@ -162,7 +178,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:132:20 + --> $DIR/needless_return.rs:142:20 | LL | let _ = || return; | ^^^^^^ @@ -170,7 +186,7 @@ LL | let _ = || return; = help: replace `return` with an empty block error: unneeded `return` statement - --> $DIR/needless_return.rs:138:32 + --> $DIR/needless_return.rs:148:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ @@ -178,7 +194,7 @@ LL | res.unwrap_or_else(|_| return Foo) = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:147:5 + --> $DIR/needless_return.rs:157:5 | LL | return true; | ^^^^^^^^^^^ @@ -186,7 +202,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:151:5 + --> $DIR/needless_return.rs:161:5 | LL | return true; | ^^^^^^^^^^^ @@ -194,7 +210,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:156:9 + --> $DIR/needless_return.rs:166:9 | LL | return true; | ^^^^^^^^^^^ @@ -202,7 +218,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:158:9 + --> $DIR/needless_return.rs:168:9 | LL | return false; | ^^^^^^^^^^^^ @@ -210,7 +226,7 @@ LL | return false; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:164:17 + --> $DIR/needless_return.rs:174:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -218,7 +234,7 @@ LL | true => return false, = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:166:13 + --> $DIR/needless_return.rs:176:13 | LL | return true; | ^^^^^^^^^^^ @@ -226,7 +242,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:173:9 + --> $DIR/needless_return.rs:183:9 | LL | return true; | ^^^^^^^^^^^ @@ -234,7 +250,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:175:16 + --> $DIR/needless_return.rs:185:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -242,7 +258,7 @@ LL | let _ = || return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:179:5 + --> $DIR/needless_return.rs:189:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -250,7 +266,7 @@ LL | return the_answer!(); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:182:33 + --> $DIR/needless_return.rs:192:33 | LL | async fn async_test_void_fun() { | _________________________________^ @@ -260,7 +276,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:187:11 + --> $DIR/needless_return.rs:197:11 | LL | if b { | ___________^ @@ -270,7 +286,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:189:13 + --> $DIR/needless_return.rs:199:13 | LL | } else { | _____________^ @@ -280,7 +296,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:197:14 + --> $DIR/needless_return.rs:207:14 | LL | _ => return, | ^^^^^^ @@ -288,7 +304,7 @@ LL | _ => return, = help: replace `return` with a unit value error: unneeded `return` statement - --> $DIR/needless_return.rs:210:9 + --> $DIR/needless_return.rs:220:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -296,7 +312,7 @@ LL | return String::from("test"); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:212:9 + --> $DIR/needless_return.rs:222:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -304,7 +320,7 @@ LL | return String::new(); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:228:5 + --> $DIR/needless_return.rs:238:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -312,7 +328,7 @@ LL | return format!("Hello {}", "world!"); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:239:9 + --> $DIR/needless_return.rs:249:9 | LL | return true; | ^^^^^^^^^^^ @@ -320,7 +336,7 @@ LL | return true; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:241:9 + --> $DIR/needless_return.rs:251:9 | LL | return false; | ^^^^^^^^^^^^ @@ -328,7 +344,7 @@ LL | return false; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:248:13 + --> $DIR/needless_return.rs:258:13 | LL | return 10; | ^^^^^^^^^ @@ -336,7 +352,7 @@ LL | return 10; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:251:13 + --> $DIR/needless_return.rs:261:13 | LL | return 100; | ^^^^^^^^^^ @@ -344,7 +360,7 @@ LL | return 100; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:259:9 + --> $DIR/needless_return.rs:269:9 | LL | return 0; | ^^^^^^^^ @@ -352,7 +368,7 @@ LL | return 0; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:266:13 + --> $DIR/needless_return.rs:276:13 | LL | return *(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -360,7 +376,7 @@ LL | return *(x as *const isize); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:268:13 + --> $DIR/needless_return.rs:278:13 | LL | return !*(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,7 +384,7 @@ LL | return !*(x as *const isize); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:275:20 + --> $DIR/needless_return.rs:285:20 | LL | let _ = 42; | ____________________^ @@ -379,7 +395,7 @@ LL | | return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:282:20 + --> $DIR/needless_return.rs:292:20 | LL | let _ = 42; return; | ^^^^^^^ @@ -387,7 +403,7 @@ LL | let _ = 42; return; = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:294:9 + --> $DIR/needless_return.rs:304:9 | LL | return Ok(format!("ok!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -395,12 +411,28 @@ LL | return Ok(format!("ok!")); = help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:296:9 + --> $DIR/needless_return.rs:306:9 | LL | return Err(format!("err!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: remove `return` -error: aborting due to 48 previous errors +error: unneeded `return` statement + --> $DIR/needless_return.rs:312:9 + | +LL | return if true { 1 } else { 2 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: remove `return` + +error: unneeded `return` statement + --> $DIR/needless_return.rs:316:9 + | +LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: remove `return` and wrap the sequence with parentheses + +error: aborting due to 52 previous errors diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs index 28e8f459d..29821ff96 100644 --- a/src/tools/clippy/tests/ui/never_loop.rs +++ b/src/tools/clippy/tests/ui/never_loop.rs @@ -250,6 +250,51 @@ pub fn test20() { } } +pub fn test21() { + loop { + 'a: { + {} + break 'a; + } + } +} + +// Issue 10304: code after break from block was not considered +// unreachable code and was considered for further analysis of +// whether the loop would ever be executed or not. +pub fn test22() { + for _ in 0..10 { + 'block: { + break 'block; + return; + } + println!("looped"); + } +} + +pub fn test23() { + for _ in 0..10 { + 'block: { + for _ in 0..20 { + break 'block; + } + } + println!("looped"); + } +} + +pub fn test24() { + 'a: for _ in 0..10 { + 'b: { + let x = Some(1); + match x { + None => break 'a, + Some(_) => break 'b, + } + } + } +} + fn main() { test1(); test2(); diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr index b7029bf8b..704d44864 100644 --- a/src/tools/clippy/tests/ui/never_loop.stderr +++ b/src/tools/clippy/tests/ui/never_loop.stderr @@ -126,5 +126,18 @@ LL | | } LL | | } | |_____^ -error: aborting due to 11 previous errors +error: this loop never actually loops + --> $DIR/never_loop.rs:278:13 + | +LL | / for _ in 0..20 { +LL | | break 'block; +LL | | } + | |_____________^ + | +help: if you need the first element of the iterator, try writing + | +LL | if let Some(_) = (0..20).next() { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs index 65809023f..7803418cb 100644 --- a/src/tools/clippy/tests/ui/new_without_default.rs +++ b/src/tools/clippy/tests/ui/new_without_default.rs @@ -1,4 +1,9 @@ -#![allow(dead_code, clippy::missing_safety_doc, clippy::extra_unused_lifetimes)] +#![allow( + dead_code, + clippy::missing_safety_doc, + clippy::extra_unused_lifetimes, + clippy::extra_unused_type_parameters +)] #![warn(clippy::new_without_default)] pub struct Foo; diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr index 212a69ab9..583dd327d 100644 --- a/src/tools/clippy/tests/ui/new_without_default.stderr +++ b/src/tools/clippy/tests/ui/new_without_default.stderr @@ -1,5 +1,5 @@ error: you should consider adding a `Default` implementation for `Foo` - --> $DIR/new_without_default.rs:7:5 + --> $DIR/new_without_default.rs:12:5 | LL | / pub fn new() -> Foo { LL | | Foo @@ -17,7 +17,7 @@ LL + } | error: you should consider adding a `Default` implementation for `Bar` - --> $DIR/new_without_default.rs:15:5 + --> $DIR/new_without_default.rs:20:5 | LL | / pub fn new() -> Self { LL | | Bar @@ -34,7 +34,7 @@ LL + } | error: you should consider adding a `Default` implementation for `LtKo<'c>` - --> $DIR/new_without_default.rs:79:5 + --> $DIR/new_without_default.rs:84:5 | LL | / pub fn new() -> LtKo<'c> { LL | | unimplemented!() @@ -51,7 +51,7 @@ LL + } | error: you should consider adding a `Default` implementation for `NewNotEqualToDerive` - --> $DIR/new_without_default.rs:172:5 + --> $DIR/new_without_default.rs:177:5 | LL | / pub fn new() -> Self { LL | | NewNotEqualToDerive { foo: 1 } @@ -68,7 +68,7 @@ LL + } | error: you should consider adding a `Default` implementation for `FooGenerics` - --> $DIR/new_without_default.rs:180:5 + --> $DIR/new_without_default.rs:185:5 | LL | / pub fn new() -> Self { LL | | Self(Default::default()) @@ -85,7 +85,7 @@ LL + } | error: you should consider adding a `Default` implementation for `BarGenerics` - --> $DIR/new_without_default.rs:187:5 + --> $DIR/new_without_default.rs:192:5 | LL | / pub fn new() -> Self { LL | | Self(Default::default()) @@ -102,7 +102,7 @@ LL + } | error: you should consider adding a `Default` implementation for `Foo` - --> $DIR/new_without_default.rs:198:9 + --> $DIR/new_without_default.rs:203:9 | LL | / pub fn new() -> Self { LL | | todo!() diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed new file mode 100644 index 000000000..d18dec22a --- /dev/null +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed @@ -0,0 +1,48 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::no_mangle_with_rust_abi)] + +#[no_mangle] +extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + +/// # Safety +/// This function shouldn't be called unless the horsemen are ready +#[no_mangle] +pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + +/// # Safety +/// This function shouldn't be called unless the horsemen are ready +#[no_mangle] +unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + arg_one: u32, + arg_two: usize, +) -> u32 { + 0 +} + +// Must not run on functions that explicitly opt in to Rust ABI with `extern "Rust"` +#[no_mangle] +#[rustfmt::skip] +extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {} + +fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {} + +extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {} + +extern "C" { + fn c_abi_in_block(arg_one: u32, arg_two: usize); +} + +fn main() { + // test code goes here +} diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs new file mode 100644 index 000000000..481e1b6d9 --- /dev/null +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs @@ -0,0 +1,48 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::no_mangle_with_rust_abi)] + +#[no_mangle] +fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + +/// # Safety +/// This function shouldn't be called unless the horsemen are ready +#[no_mangle] +pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + +/// # Safety +/// This function shouldn't be called unless the horsemen are ready +#[no_mangle] +unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + arg_one: u32, + arg_two: usize, +) -> u32 { + 0 +} + +// Must not run on functions that explicitly opt in to Rust ABI with `extern "Rust"` +#[no_mangle] +#[rustfmt::skip] +extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {} + +fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {} + +#[no_mangle] +extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {} + +extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {} + +extern "C" { + fn c_abi_in_block(arg_one: u32, arg_two: usize); +} + +fn main() { + // test code goes here +} diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr new file mode 100644 index 000000000..71517d318 --- /dev/null +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr @@ -0,0 +1,45 @@ +error: attribute #[no_mangle] set on a Rust ABI function + --> $DIR/no_mangle_with_rust_abi.rs:7:1 + | +LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize)` + | + = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` + +error: attribute #[no_mangle] set on a Rust ABI function + --> $DIR/no_mangle_with_rust_abi.rs:10:1 + | +LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize)` + +error: attribute #[no_mangle] set on a Rust ABI function + --> $DIR/no_mangle_with_rust_abi.rs:15:1 + | +LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize)` + +error: attribute #[no_mangle] set on a Rust ABI function + --> $DIR/no_mangle_with_rust_abi.rs:20:1 + | +LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize)` + +error: attribute #[no_mangle] set on a Rust ABI function + --> $DIR/no_mangle_with_rust_abi.rs:23:1 + | +LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( +LL | | arg_one: u32, +LL | | arg_two: usize, +LL | | ) -> u32 { + | |________^ + | +help: try + | +LL + extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( +LL + arg_one: u32, +LL + arg_two: usize, +LL ~ ) -> u32 { + | + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/question_mark_used.rs b/src/tools/clippy/tests/ui/question_mark_used.rs new file mode 100644 index 000000000..8c3ef7896 --- /dev/null +++ b/src/tools/clippy/tests/ui/question_mark_used.rs @@ -0,0 +1,15 @@ +// non rustfixable +#![allow(unreachable_code)] +#![allow(dead_code)] +#![warn(clippy::question_mark_used)] + +fn other_function() -> Option { + Some(32) +} + +fn my_function() -> Option { + other_function()?; + None +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/question_mark_used.stderr b/src/tools/clippy/tests/ui/question_mark_used.stderr new file mode 100644 index 000000000..8b5fcbcdb --- /dev/null +++ b/src/tools/clippy/tests/ui/question_mark_used.stderr @@ -0,0 +1,11 @@ +error: question mark operator was used + --> $DIR/question_mark_used.rs:11:5 + | +LL | other_function()?; + | ^^^^^^^^^^^^^^^^^ + | + = help: consider using a custom macro or match expression + = note: `-D clippy::question-mark-used` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed index ec7f8ae92..276266a2d 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.fixed +++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed @@ -1,7 +1,7 @@ // run-rustfix #![warn(clippy::redundant_field_names)] -#![allow(clippy::no_effect, dead_code, unused_variables)] +#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] #[macro_use] extern crate derive_new; diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs index 73122016c..f674141c1 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.rs +++ b/src/tools/clippy/tests/ui/redundant_field_names.rs @@ -1,7 +1,7 @@ // run-rustfix #![warn(clippy::redundant_field_names)] -#![allow(clippy::no_effect, dead_code, unused_variables)] +#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] #[macro_use] extern crate derive_new; diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs index f0e1a8128..ab8ac97a0 100644 --- a/src/tools/clippy/tests/ui/regex.rs +++ b/src/tools/clippy/tests/ui/regex.rs @@ -36,6 +36,10 @@ fn syntax_error() { let raw_string_error = Regex::new(r"[...\/...]"); let raw_string_error = Regex::new(r#"[...\/...]"#); + + let escaped_string_span = Regex::new("\\b\\c"); + + let aux_span = Regex::new("(?ixi)"); } fn trivial_regex() { diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr index 2424644c6..c2440f39e 100644 --- a/src/tools/clippy/tests/ui/regex.stderr +++ b/src/tools/clippy/tests/ui/regex.stderr @@ -29,7 +29,10 @@ error: regex syntax error: invalid character class range, the start must be <= t LL | let some_unicode = Regex::new("[é-è]"); | ^^^ -error: regex syntax error on position 0: unclosed group +error: regex parse error: + ( + ^ + error: unclosed group --> $DIR/regex.rs:18:33 | LL | let some_regex = Regex::new(OPENING_PAREN); @@ -43,25 +46,37 @@ LL | let binary_pipe_in_wrong_position = BRegex::new("|"); | = help: the regex is unlikely to be useful as it is -error: regex syntax error on position 0: unclosed group +error: regex parse error: + ( + ^ + error: unclosed group --> $DIR/regex.rs:21:41 | LL | let some_binary_regex = BRegex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed group +error: regex parse error: + ( + ^ + error: unclosed group --> $DIR/regex.rs:22:56 | LL | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed group +error: regex parse error: + ( + ^ + error: unclosed group --> $DIR/regex.rs:34:37 | LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed group +error: regex parse error: + ( + ^ + error: unclosed group --> $DIR/regex.rs:35:39 | LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); @@ -79,8 +94,25 @@ error: regex syntax error: unrecognized escape sequence LL | let raw_string_error = Regex::new(r#"[...//...]"#); | ^^ +error: regex parse error: + /b/c + ^^ + error: unrecognized escape sequence + --> $DIR/regex.rs:40:42 + | +LL | let escaped_string_span = Regex::new("/b/c"); + | ^^^^^^^^ + | + = help: consider using a raw string literal: `r".."` + +error: regex syntax error: duplicate flag + --> $DIR/regex.rs:42:34 + | +LL | let aux_span = Regex::new("(?ixi)"); + | ^ ^ + error: trivial regex - --> $DIR/regex.rs:42:33 + --> $DIR/regex.rs:46:33 | LL | let trivial_eq = Regex::new("^foobar$"); | ^^^^^^^^^^ @@ -88,7 +120,7 @@ LL | let trivial_eq = Regex::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:44:48 + --> $DIR/regex.rs:48:48 | LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); | ^^^^^^^^^^ @@ -96,7 +128,7 @@ LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:46:42 + --> $DIR/regex.rs:50:42 | LL | let trivial_starts_with = Regex::new("^foobar"); | ^^^^^^^^^ @@ -104,7 +136,7 @@ LL | let trivial_starts_with = Regex::new("^foobar"); = help: consider using `str::starts_with` error: trivial regex - --> $DIR/regex.rs:48:40 + --> $DIR/regex.rs:52:40 | LL | let trivial_ends_with = Regex::new("foobar$"); | ^^^^^^^^^ @@ -112,7 +144,7 @@ LL | let trivial_ends_with = Regex::new("foobar$"); = help: consider using `str::ends_with` error: trivial regex - --> $DIR/regex.rs:50:39 + --> $DIR/regex.rs:54:39 | LL | let trivial_contains = Regex::new("foobar"); | ^^^^^^^^ @@ -120,7 +152,7 @@ LL | let trivial_contains = Regex::new("foobar"); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:52:39 + --> $DIR/regex.rs:56:39 | LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); | ^^^^^^^^^^^^^^^^ @@ -128,7 +160,7 @@ LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:54:40 + --> $DIR/regex.rs:58:40 | LL | let trivial_backslash = Regex::new("a/.b"); | ^^^^^^^ @@ -136,7 +168,7 @@ LL | let trivial_backslash = Regex::new("a/.b"); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:57:36 + --> $DIR/regex.rs:61:36 | LL | let trivial_empty = Regex::new(""); | ^^ @@ -144,7 +176,7 @@ LL | let trivial_empty = Regex::new(""); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:59:36 + --> $DIR/regex.rs:63:36 | LL | let trivial_empty = Regex::new("^"); | ^^^ @@ -152,7 +184,7 @@ LL | let trivial_empty = Regex::new("^"); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:61:36 + --> $DIR/regex.rs:65:36 | LL | let trivial_empty = Regex::new("^$"); | ^^^^ @@ -160,12 +192,12 @@ LL | let trivial_empty = Regex::new("^$"); = help: consider using `str::is_empty` error: trivial regex - --> $DIR/regex.rs:63:44 + --> $DIR/regex.rs:67:44 | LL | let binary_trivial_empty = BRegex::new("^$"); | ^^^^ | = help: consider using `str::is_empty` -error: aborting due to 23 previous errors +error: aborting due to 25 previous errors diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed index 713cff604..dc24d447c 100644 --- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed +++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed @@ -26,7 +26,7 @@ fn seek_to_start_false_method(t: &mut StructWithSeekMethod) { // This should NOT trigger clippy warning because // StructWithSeekMethod does not implement std::io::Seek; -fn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) { +fn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) { t.seek(SeekFrom::Start(0)); } @@ -38,7 +38,7 @@ fn seek_to_start_false_trait(t: &mut StructWithSeekTrait) { // This should NOT trigger clippy warning because // StructWithSeekMethod does not implement std::io::Seek; -fn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) { +fn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) { t.seek(SeekFrom::Start(0)); } diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs index 467003a1a..4adde2c40 100644 --- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs +++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs @@ -26,7 +26,7 @@ fn seek_to_start_false_method(t: &mut StructWithSeekMethod) { // This should NOT trigger clippy warning because // StructWithSeekMethod does not implement std::io::Seek; -fn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) { +fn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) { t.seek(SeekFrom::Start(0)); } @@ -38,7 +38,7 @@ fn seek_to_start_false_trait(t: &mut StructWithSeekTrait) { // This should NOT trigger clippy warning because // StructWithSeekMethod does not implement std::io::Seek; -fn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) { +fn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) { t.seek(SeekFrom::Start(0)); } diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.fixed b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed new file mode 100644 index 000000000..da998c610 --- /dev/null +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed @@ -0,0 +1,84 @@ +// run-rustfix + +#![warn(clippy::significant_drop_tightening)] + +use std::sync::Mutex; + +pub fn complex_return_triggers_the_lint() -> i32 { + fn foo() -> i32 { + 1 + } + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let _ = *lock; + let _ = *lock; + drop(lock); + foo() +} + +pub fn path_return_can_be_ignored() -> i32 { + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let rslt = *lock; + let _ = *lock; + rslt +} + +pub fn post_bindings_can_be_ignored() { + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let rslt = *lock; + let another = rslt; + let _ = another; +} + +pub fn unnecessary_contention_with_multiple_owned_results() { + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let _ = lock.abs(); + let _ = lock.is_positive(); + } + + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let rslt0 = lock.abs(); + let rslt1 = lock.is_positive(); + drop(lock); + do_heavy_computation_that_takes_time((rslt0, rslt1)); + } +} + +pub fn unnecessary_contention_with_single_owned_results() { + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let _ = lock.abs(); + } + { + let mutex = Mutex::new(vec![1i32]); + let mut lock = mutex.lock().unwrap(); + lock.clear(); + } + + { + let mutex = Mutex::new(1i32); + + let rslt0 = mutex.lock().unwrap().abs(); + + do_heavy_computation_that_takes_time(rslt0); + } + { + let mutex = Mutex::new(vec![1i32]); + + mutex.lock().unwrap().clear(); + + do_heavy_computation_that_takes_time(()); + } +} + +// Marker used for illustration purposes. +pub fn do_heavy_computation_that_takes_time(_: T) {} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.rs b/src/tools/clippy/tests/ui/significant_drop_tightening.rs new file mode 100644 index 000000000..83823f95f --- /dev/null +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.rs @@ -0,0 +1,80 @@ +// run-rustfix + +#![warn(clippy::significant_drop_tightening)] + +use std::sync::Mutex; + +pub fn complex_return_triggers_the_lint() -> i32 { + fn foo() -> i32 { + 1 + } + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let _ = *lock; + let _ = *lock; + foo() +} + +pub fn path_return_can_be_ignored() -> i32 { + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let rslt = *lock; + let _ = *lock; + rslt +} + +pub fn post_bindings_can_be_ignored() { + let mutex = Mutex::new(1); + let lock = mutex.lock().unwrap(); + let rslt = *lock; + let another = rslt; + let _ = another; +} + +pub fn unnecessary_contention_with_multiple_owned_results() { + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let _ = lock.abs(); + let _ = lock.is_positive(); + } + + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let rslt0 = lock.abs(); + let rslt1 = lock.is_positive(); + do_heavy_computation_that_takes_time((rslt0, rslt1)); + } +} + +pub fn unnecessary_contention_with_single_owned_results() { + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let _ = lock.abs(); + } + { + let mutex = Mutex::new(vec![1i32]); + let mut lock = mutex.lock().unwrap(); + lock.clear(); + } + + { + let mutex = Mutex::new(1i32); + let lock = mutex.lock().unwrap(); + let rslt0 = lock.abs(); + do_heavy_computation_that_takes_time(rslt0); + } + { + let mutex = Mutex::new(vec![1i32]); + let mut lock = mutex.lock().unwrap(); + lock.clear(); + do_heavy_computation_that_takes_time(()); + } +} + +// Marker used for illustration purposes. +pub fn do_heavy_computation_that_takes_time(_: T) {} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr new file mode 100644 index 000000000..ab8ce356e --- /dev/null +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr @@ -0,0 +1,94 @@ +error: temporary with significant `Drop` can be early dropped + --> $DIR/significant_drop_tightening.rs:12:9 + | +LL | pub fn complex_return_triggers_the_lint() -> i32 { + | __________________________________________________- +LL | | fn foo() -> i32 { +LL | | 1 +LL | | } +LL | | let mutex = Mutex::new(1); +LL | | let lock = mutex.lock().unwrap(); + | | ^^^^ +... | +LL | | foo() +LL | | } + | |_- temporary `lock` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention + = note: `-D clippy::significant-drop-tightening` implied by `-D warnings` +help: drop the temporary after the end of its last usage + | +LL ~ let _ = *lock; +LL + drop(lock); + | + +error: temporary with significant `Drop` can be early dropped + --> $DIR/significant_drop_tightening.rs:44:13 + | +LL | / { +LL | | let mutex = Mutex::new(1i32); +LL | | let lock = mutex.lock().unwrap(); + | | ^^^^ +LL | | let rslt0 = lock.abs(); +LL | | let rslt1 = lock.is_positive(); +LL | | do_heavy_computation_that_takes_time((rslt0, rslt1)); +LL | | } + | |_____- temporary `lock` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: drop the temporary after the end of its last usage + | +LL ~ let rslt1 = lock.is_positive(); +LL + drop(lock); + | + +error: temporary with significant `Drop` can be early dropped + --> $DIR/significant_drop_tightening.rs:65:13 + | +LL | / { +LL | | let mutex = Mutex::new(1i32); +LL | | let lock = mutex.lock().unwrap(); + | | ^^^^ +LL | | let rslt0 = lock.abs(); +LL | | do_heavy_computation_that_takes_time(rslt0); +LL | | } + | |_____- temporary `lock` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: merge the temporary construction with its single usage + | +LL ~ +LL + let rslt0 = mutex.lock().unwrap().abs(); + | +help: remove separated single usage + | +LL - let rslt0 = lock.abs(); +LL + + | + +error: temporary with significant `Drop` can be early dropped + --> $DIR/significant_drop_tightening.rs:71:17 + | +LL | / { +LL | | let mutex = Mutex::new(vec![1i32]); +LL | | let mut lock = mutex.lock().unwrap(); + | | ^^^^ +LL | | lock.clear(); +LL | | do_heavy_computation_that_takes_time(()); +LL | | } + | |_____- temporary `lock` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: merge the temporary construction with its single usage + | +LL ~ +LL + mutex.lock().unwrap().clear(); + | +help: remove separated single usage + | +LL - lock.clear(); +LL + + | + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs new file mode 100644 index 000000000..bdc6113a2 --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs @@ -0,0 +1,10 @@ +fn main() { + // Things it should warn about: + std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); + std::process::Command::new("cat").arg("--number file").spawn().unwrap(); + + // Things it should not warn about: + std::process::Command::new("echo").arg("hello world").spawn().unwrap(); + std::process::Command::new("a").arg("--fmt=%a %b %c").spawn().unwrap(); + std::process::Command::new("b").arg("-ldflags=-s -w").spawn().unwrap(); +} diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr new file mode 100644 index 000000000..9bc0ca93a --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr @@ -0,0 +1,25 @@ +error: single argument that looks like it should be multiple arguments + --> $DIR/suspicious_command_arg_space.rs:3:44 + | +LL | std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); + | ^^^^^^^^^^ + | + = note: `-D clippy::suspicious-command-arg-space` implied by `-D warnings` +help: consider splitting the argument + | +LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); + | ~~~~ ~~~~~~~~~~~~~~~ + +error: single argument that looks like it should be multiple arguments + --> $DIR/suspicious_command_arg_space.rs:4:43 + | +LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap(); + | ^^^^^^^^^^^^^^^ + | +help: consider splitting the argument + | +LL | std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); + | ~~~~ ~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr index dec3f50d6..c4ec7aa88 100644 --- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr @@ -2,27 +2,62 @@ error: this `to_owned` call clones the Cow<'_, str> itself and does not cause th --> $DIR/suspicious_to_owned.rs:16:13 | LL | let _ = cow.to_owned(); - | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + | ^^^^^^^^^^^^^^ | = note: `-D clippy::suspicious-to-owned` implied by `-D warnings` +help: depending on intent, either make the Cow an Owned variant + | +LL | let _ = cow.into_owned(); + | ~~~~~~~~~~~~~~~~ +help: or clone the Cow itself + | +LL | let _ = cow.clone(); + | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned --> $DIR/suspicious_to_owned.rs:26:13 | LL | let _ = cow.to_owned(); - | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + | ^^^^^^^^^^^^^^ + | +help: depending on intent, either make the Cow an Owned variant + | +LL | let _ = cow.into_owned(); + | ~~~~~~~~~~~~~~~~ +help: or clone the Cow itself + | +LL | let _ = cow.clone(); + | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned --> $DIR/suspicious_to_owned.rs:36:13 | LL | let _ = cow.to_owned(); - | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + | ^^^^^^^^^^^^^^ + | +help: depending on intent, either make the Cow an Owned variant + | +LL | let _ = cow.into_owned(); + | ~~~~~~~~~~~~~~~~ +help: or clone the Cow itself + | +LL | let _ = cow.clone(); + | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned --> $DIR/suspicious_to_owned.rs:46:13 | LL | let _ = cow.to_owned(); - | ^^^^^^^^^^^^^^ help: consider using, depending on intent: `cow.clone()` or `cow.into_owned()` + | ^^^^^^^^^^^^^^ + | +help: depending on intent, either make the Cow an Owned variant + | +LL | let _ = cow.into_owned(); + | ~~~~~~~~~~~~~~~~ +help: or clone the Cow itself + | +LL | let _ = cow.clone(); + | ~~~~~~~~~~~ error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type --> $DIR/suspicious_to_owned.rs:60:13 diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed index 805a2ba5a..fa89706a8 100644 --- a/src/tools/clippy/tests/ui/swap.fixed +++ b/src/tools/clippy/tests/ui/swap.fixed @@ -7,7 +7,8 @@ clippy::redundant_clone, redundant_semicolons, dead_code, - unused_assignments + unused_assignments, + unused_variables )] struct Foo(u32); @@ -121,6 +122,27 @@ fn main() { std::mem::swap(&mut c.0, &mut a); ; std::mem::swap(&mut c.0, &mut a); + + std::mem::swap(&mut a, &mut b); + + let mut c = 1; + let mut d = 2; + std::mem::swap(&mut d, &mut c); + + let mut b = 1; + std::mem::swap(&mut a, &mut b); + + let b = 1; + let a = 2; + + let t = b; + let b = a; + let a = t; + + let mut b = 1; + let mut a = 2; + + std::mem::swap(&mut b, &mut a); } fn issue_8154() { diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs index a8c878479..ef8a81c83 100644 --- a/src/tools/clippy/tests/ui/swap.rs +++ b/src/tools/clippy/tests/ui/swap.rs @@ -7,7 +7,8 @@ clippy::redundant_clone, redundant_semicolons, dead_code, - unused_assignments + unused_assignments, + unused_variables )] struct Foo(u32); @@ -143,6 +144,32 @@ fn main() { ; let t = c.0; c.0 = a; a = t; + + let a = b; + let b = a; + + let mut c = 1; + let mut d = 2; + d = c; + c = d; + + let mut b = 1; + let a = b; + b = a; + + let b = 1; + let a = 2; + + let t = b; + let b = a; + let a = t; + + let mut b = 1; + let mut a = 2; + + let t = b; + b = a; + a = t; } fn issue_8154() { diff --git a/src/tools/clippy/tests/ui/swap.stderr b/src/tools/clippy/tests/ui/swap.stderr index ee4b7a508..f0acbfe25 100644 --- a/src/tools/clippy/tests/ui/swap.stderr +++ b/src/tools/clippy/tests/ui/swap.stderr @@ -1,5 +1,5 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:24:5 + --> $DIR/swap.rs:25:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; @@ -10,7 +10,7 @@ LL | | bar.b = temp; = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:36:5 + --> $DIR/swap.rs:37:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -18,7 +18,7 @@ LL | | foo[1] = temp; | |_________________^ help: try: `foo.swap(0, 1)` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:45:5 + --> $DIR/swap.rs:46:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -26,7 +26,7 @@ LL | | foo[1] = temp; | |_________________^ help: try: `foo.swap(0, 1)` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:64:5 + --> $DIR/swap.rs:65:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -34,7 +34,7 @@ LL | | foo[1] = temp; | |_________________^ help: try: `foo.swap(0, 1)` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:75:5 + --> $DIR/swap.rs:76:5 | LL | / a ^= b; LL | | b ^= a; @@ -42,7 +42,7 @@ LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b)` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:83:5 + --> $DIR/swap.rs:84:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; @@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:91:5 + --> $DIR/swap.rs:92:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; @@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1)` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> $DIR/swap.rs:120:5 + --> $DIR/swap.rs:121:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; @@ -68,7 +68,7 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:134:7 + --> $DIR/swap.rs:135:7 | LL | ; let t = a; | _______^ @@ -79,7 +79,7 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> $DIR/swap.rs:143:7 + --> $DIR/swap.rs:144:7 | LL | ; let t = c.0; | _______^ @@ -89,8 +89,18 @@ LL | | a = t; | = note: or maybe you should use `std::mem::replace`? +error: this looks like you are swapping `b` and `a` manually + --> $DIR/swap.rs:170:5 + | +LL | / let t = b; +LL | | b = a; +LL | | a = t; + | |_________^ help: try: `std::mem::swap(&mut b, &mut a)` + | + = note: or maybe you should use `std::mem::replace`? + error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:131:5 + --> $DIR/swap.rs:132:5 | LL | / a = b; LL | | b = a; @@ -100,7 +110,7 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` - --> $DIR/swap.rs:140:5 + --> $DIR/swap.rs:141:5 | LL | / c.0 = a; LL | | a = c.0; @@ -108,8 +118,35 @@ LL | | a = c.0; | = note: or maybe you should use `std::mem::replace`? +error: this looks like you are trying to swap `a` and `b` + --> $DIR/swap.rs:148:5 + | +LL | / let a = b; +LL | | let b = a; + | |_____________^ help: try: `std::mem::swap(&mut a, &mut b)` + | + = note: or maybe you should use `std::mem::replace`? + +error: this looks like you are trying to swap `d` and `c` + --> $DIR/swap.rs:153:5 + | +LL | / d = c; +LL | | c = d; + | |_________^ help: try: `std::mem::swap(&mut d, &mut c)` + | + = note: or maybe you should use `std::mem::replace`? + +error: this looks like you are trying to swap `a` and `b` + --> $DIR/swap.rs:157:5 + | +LL | / let a = b; +LL | | b = a; + | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` + | + = note: or maybe you should use `std::mem::replace`? + error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> $DIR/swap.rs:178:5 + --> $DIR/swap.rs:205:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y; @@ -118,5 +155,5 @@ LL | | s.0.y = t; | = note: or maybe you should use `std::mem::replace`? -error: aborting due to 13 previous errors +error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr index ec3031862..39418d359 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/track-diagnostics.rs:LL:CC | LL | const S: A = B; - | ^ expected struct `A`, found struct `B` + | ^ expected `A`, found `B` -Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs new file mode 100644 index 000000000..a38406782 --- /dev/null +++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs @@ -0,0 +1,41 @@ +#![warn(clippy::transmute_int_to_non_zero)] + +use core::num::*; + +fn main() { + let int_u8: u8 = 1; + let int_u16: u16 = 1; + let int_u32: u32 = 1; + let int_u64: u64 = 1; + let int_u128: u128 = 1; + + let int_i8: i8 = 1; + let int_i16: i16 = 1; + let int_i32: i32 = 1; + let int_i64: i64 = 1; + let int_i128: i128 = 1; + + let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) }; + let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) }; + let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) }; + let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) }; + let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) }; + + let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) }; + let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) }; + let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) }; + let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) }; + let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) }; + + let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) }; + let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) }; + let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) }; + let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) }; + let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) }; + + let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) }; + let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) }; + let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) }; + let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) }; + let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) }; +} diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr new file mode 100644 index 000000000..33f8ce79e --- /dev/null +++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr @@ -0,0 +1,64 @@ +error: transmute from a `u8` to a `NonZeroU8` + --> $DIR/transmute_int_to_non_zero.rs:18:33 + | +LL | let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU8::new_unchecked(int_u8)` + | + = note: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` + +error: transmute from a `u16` to a `NonZeroU16` + --> $DIR/transmute_int_to_non_zero.rs:19:34 + | +LL | let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU16::new_unchecked(int_u16)` + +error: transmute from a `u32` to a `NonZeroU32` + --> $DIR/transmute_int_to_non_zero.rs:20:34 + | +LL | let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU32::new_unchecked(int_u32)` + +error: transmute from a `u64` to a `NonZeroU64` + --> $DIR/transmute_int_to_non_zero.rs:21:34 + | +LL | let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU64::new_unchecked(int_u64)` + +error: transmute from a `u128` to a `NonZeroU128` + --> $DIR/transmute_int_to_non_zero.rs:22:35 + | +LL | let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU128::new_unchecked(int_u128)` + +error: transmute from a `i8` to a `NonZeroI8` + --> $DIR/transmute_int_to_non_zero.rs:24:33 + | +LL | let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI8::new_unchecked(int_i8)` + +error: transmute from a `i16` to a `NonZeroI16` + --> $DIR/transmute_int_to_non_zero.rs:25:34 + | +LL | let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI16::new_unchecked(int_i16)` + +error: transmute from a `i32` to a `NonZeroI32` + --> $DIR/transmute_int_to_non_zero.rs:26:34 + | +LL | let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI32::new_unchecked(int_i32)` + +error: transmute from a `i64` to a `NonZeroI64` + --> $DIR/transmute_int_to_non_zero.rs:27:34 + | +LL | let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI64::new_unchecked(int_i64)` + +error: transmute from a `i128` to a `NonZeroI128` + --> $DIR/transmute_int_to_non_zero.rs:28:35 + | +LL | let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI128::new_unchecked(int_i128)` + +error: aborting due to 10 previous errors + diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed index 7263abac1..55307506e 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -51,6 +51,8 @@ fn main() { // e is a function pointer type and U is an integer; fptr-addr-cast let _usize_from_fn_ptr_transmute = unsafe { foo as usize }; let _usize_from_fn_ptr = foo as *const usize; + + let _usize_from_ref = unsafe { &1u32 as *const u32 as usize }; } // If a ref-to-ptr cast of this form where the pointer type points to a type other diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs index d8e4421d4..e7360f3f9 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -51,6 +51,8 @@ fn main() { // e is a function pointer type and U is an integer; fptr-addr-cast let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; let _usize_from_fn_ptr = foo as *const usize; + + let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; } // If a ref-to-ptr cast of this form where the pointer type points to a type other diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr index de9418c8d..e862fcb67 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -46,11 +46,17 @@ error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a LL | let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize` +error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead + --> $DIR/transmutes_expressible_as_ptr_casts.rs:55:36 + | +LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize` + error: transmute from a reference to a pointer - --> $DIR/transmutes_expressible_as_ptr_casts.rs:64:14 + --> $DIR/transmutes_expressible_as_ptr_casts.rs:66:14 | LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs index 2eca1f470..8b4613b3f 100644 --- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs +++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs @@ -1,4 +1,5 @@ #![deny(clippy::type_repetition_in_bounds)] +#![allow(clippy::extra_unused_type_parameters)] use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr index 70d700c1c..a90df03c0 100644 --- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr @@ -1,5 +1,5 @@ error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:8:5 + --> $DIR/type_repetition_in_bounds.rs:9:5 | LL | T: Clone, | ^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::type_repetition_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:25:5 + --> $DIR/type_repetition_in_bounds.rs:26:5 | LL | Self: Copy + Default + Ord, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | Self: Copy + Default + Ord, = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord` error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:85:5 + --> $DIR/type_repetition_in_bounds.rs:86:5 | LL | T: Clone, | ^^^^^^^^ @@ -28,7 +28,7 @@ LL | T: Clone, = help: consider combining the bounds: `T: ?Sized + Clone` error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:90:5 + --> $DIR/type_repetition_in_bounds.rs:91:5 | LL | T: ?Sized, | ^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed index 9d08e80cf..cbd5cc5fc 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed @@ -174,3 +174,7 @@ fn _meets_msrv() { let local_i32 = 1; println!("expand='{local_i32}'"); } + +fn _do_not_fire() { + println!("{:?}", None::<()>); +} diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs index 35b3677a8..cf0ea5be4 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.rs +++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs @@ -179,3 +179,7 @@ fn _meets_msrv() { let local_i32 = 1; println!("expand='{}'", local_i32); } + +fn _do_not_fire() { + println!("{:?}", None::<()>); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs index 7fefea705..89fedb145 100644 --- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs +++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs @@ -48,4 +48,21 @@ fn unnecessary_on_stmt_and_expr() -> u32 { 24 } +mod issue_10084 { + unsafe fn bar() -> i32 { + 42 + } + + macro_rules! foo { + () => { + // SAFETY: This is necessary + unsafe { bar() } + }; + } + + fn main() { + foo!(); + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/unreadable_literal.fixed b/src/tools/clippy/tests/ui/unreadable_literal.fixed index a67363b09..13e5feb19 100644 --- a/src/tools/clippy/tests/ui/unreadable_literal.fixed +++ b/src/tools/clippy/tests/ui/unreadable_literal.fixed @@ -23,7 +23,7 @@ fn main() { let _good = ( 0b1011_i64, 0o1_234_u32, - 0x0123_4567, + 0x1_234_567, 65536, 1_2345_6789, 1234_f32, diff --git a/src/tools/clippy/tests/ui/unreadable_literal.stderr b/src/tools/clippy/tests/ui/unreadable_literal.stderr index b51130c6a..450121b1c 100644 --- a/src/tools/clippy/tests/ui/unreadable_literal.stderr +++ b/src/tools/clippy/tests/ui/unreadable_literal.stderr @@ -1,11 +1,3 @@ -error: digits of hex or binary literal not grouped by four - --> $DIR/unreadable_literal.rs:26:9 - | -LL | 0x1_234_567, - | ^^^^^^^^^^^ help: consider: `0x0123_4567` - | - = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings` - error: long literal lacking separators --> $DIR/unreadable_literal.rs:34:17 | @@ -68,5 +60,5 @@ error: long literal lacking separators LL | let _fail5 = 1.100300400; | ^^^^^^^^^^^ help: consider: `1.100_300_400` -error: aborting due to 11 previous errors +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/unused_io_amount.rs b/src/tools/clippy/tests/ui/unused_io_amount.rs index 4b0595581..8d3e094b7 100644 --- a/src/tools/clippy/tests/ui/unused_io_amount.rs +++ b/src/tools/clippy/tests/ui/unused_io_amount.rs @@ -63,6 +63,14 @@ fn combine_or(file: &str) -> Result<(), Error> { Ok(()) } +fn is_ok_err(s: &mut T) { + s.write(b"ok").is_ok(); + s.write(b"err").is_err(); + let mut buf = [0u8; 0]; + s.read(&mut buf).is_ok(); + s.read(&mut buf).is_err(); +} + async fn bad_async_write(w: &mut W) { w.write(b"hello world").await.unwrap(); } diff --git a/src/tools/clippy/tests/ui/unused_io_amount.stderr b/src/tools/clippy/tests/ui/unused_io_amount.stderr index 7ba7e09c0..0865c5213 100644 --- a/src/tools/clippy/tests/ui/unused_io_amount.stderr +++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr @@ -82,13 +82,45 @@ LL | | .expect("error"); error: written amount is not handled --> $DIR/unused_io_amount.rs:67:5 | +LL | s.write(b"ok").is_ok(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `Write::write_all` instead, or handle partial writes + +error: written amount is not handled + --> $DIR/unused_io_amount.rs:68:5 + | +LL | s.write(b"err").is_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `Write::write_all` instead, or handle partial writes + +error: read amount is not handled + --> $DIR/unused_io_amount.rs:70:5 + | +LL | s.read(&mut buf).is_ok(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `Read::read_exact` instead, or handle partial reads + +error: read amount is not handled + --> $DIR/unused_io_amount.rs:71:5 + | +LL | s.read(&mut buf).is_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `Read::read_exact` instead, or handle partial reads + +error: written amount is not handled + --> $DIR/unused_io_amount.rs:75:5 + | LL | w.write(b"hello world").await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: read amount is not handled - --> $DIR/unused_io_amount.rs:72:5 + --> $DIR/unused_io_amount.rs:80:5 | LL | r.read(&mut buf[..]).await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +128,7 @@ LL | r.read(&mut buf[..]).await.unwrap(); = help: use `AsyncReadExt::read_exact` instead, or handle partial reads error: written amount is not handled - --> $DIR/unused_io_amount.rs:85:9 + --> $DIR/unused_io_amount.rs:93:9 | LL | w.write(b"hello world").await?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +136,7 @@ LL | w.write(b"hello world").await?; = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: read amount is not handled - --> $DIR/unused_io_amount.rs:93:9 + --> $DIR/unused_io_amount.rs:101:9 | LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +144,7 @@ LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?; = help: use `AsyncReadExt::read_exact` instead, or handle partial reads error: written amount is not handled - --> $DIR/unused_io_amount.rs:101:5 + --> $DIR/unused_io_amount.rs:109:5 | LL | w.write(b"hello world").await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,12 +152,12 @@ LL | w.write(b"hello world").await.unwrap(); = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: read amount is not handled - --> $DIR/unused_io_amount.rs:106:5 + --> $DIR/unused_io_amount.rs:114:5 | LL | r.read(&mut buf[..]).await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `AsyncReadExt::read_exact` instead, or handle partial reads -error: aborting due to 16 previous errors +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed index 236074978..293bf75a7 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed @@ -96,7 +96,7 @@ fn main() { } match Enum::A { Enum::A => (), - Enum::B | _ => (), + Enum::B | Enum::__Private => (), } } } diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr index efecc9576..30d29aa4e 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr @@ -34,11 +34,11 @@ error: wildcard matches known variants and will also match future added variants LL | _ => {}, | ^ help: try this: `ErrorKind::PermissionDenied | _` -error: wildcard matches known variants and will also match future added variants +error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:99:13 | LL | _ => (), - | ^ help: try this: `Enum::B | _` + | ^ help: try this: `Enum::B | Enum::__Private` error: aborting due to 6 previous errors -- cgit v1.2.3