From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- src/tools/clippy/tests/ui/allow_attributes.fixed | 25 ++ src/tools/clippy/tests/ui/allow_attributes.rs | 25 ++ src/tools/clippy/tests/ui/allow_attributes.stderr | 16 + .../clippy/tests/ui/almost_complete_range.fixed | 49 +-- src/tools/clippy/tests/ui/almost_complete_range.rs | 49 +-- .../clippy/tests/ui/almost_complete_range.stderr | 93 ++-- .../clippy/tests/ui/arithmetic_side_effects.rs | 32 ++ .../clippy/tests/ui/arithmetic_side_effects.stderr | 294 ++++++++----- src/tools/clippy/tests/ui/as_conversions.rs | 13 +- src/tools/clippy/tests/ui/as_conversions.stderr | 6 +- src/tools/clippy/tests/ui/async_yields_async.fixed | 1 + src/tools/clippy/tests/ui/async_yields_async.rs | 1 + .../clippy/tests/ui/async_yields_async.stderr | 12 +- src/tools/clippy/tests/ui/author/blocks.stdout | 6 +- .../clippy/tests/ui/auxiliary/doc_unsafe_macros.rs | 16 - .../tests/ui/auxiliary/implicit_hasher_macros.rs | 6 - src/tools/clippy/tests/ui/auxiliary/macro_rules.rs | 141 +----- .../clippy/tests/ui/auxiliary/macro_use_helper.rs | 2 +- .../tests/ui/auxiliary/proc_macro_with_span.rs | 32 -- src/tools/clippy/tests/ui/auxiliary/proc_macros.rs | 474 +++++++++++++++++++++ .../auxiliary/helper.rs | 2 +- src/tools/clippy/tests/ui/boxed_local.rs | 35 +- src/tools/clippy/tests/ui/boxed_local.stderr | 8 +- src/tools/clippy/tests/ui/cast.rs | 6 + src/tools/clippy/tests/ui/cast.stderr | 112 +++-- src/tools/clippy/tests/ui/clear_with_drain.fixed | 358 ++++++++++++++++ src/tools/clippy/tests/ui/clear_with_drain.rs | 358 ++++++++++++++++ src/tools/clippy/tests/ui/clear_with_drain.stderr | 130 ++++++ .../clippy/tests/ui/collection_is_never_read.rs | 190 +++++++++ .../tests/ui/collection_is_never_read.stderr | 76 ++++ src/tools/clippy/tests/ui/crashes/ice-10148.rs | 9 + src/tools/clippy/tests/ui/crashes/ice-10148.stderr | 12 + src/tools/clippy/tests/ui/crashes/ice-6179.rs | 2 +- src/tools/clippy/tests/ui/crashes/ice-6252.stderr | 6 +- src/tools/clippy/tests/ui/crashes/ice-6254.stderr | 2 + .../tests/ui/default_numeric_fallback_f64.fixed | 20 +- .../tests/ui/default_numeric_fallback_f64.rs | 20 +- .../tests/ui/default_numeric_fallback_f64.stderr | 57 ++- .../tests/ui/default_numeric_fallback_i32.fixed | 20 +- .../tests/ui/default_numeric_fallback_i32.rs | 20 +- .../tests/ui/default_numeric_fallback_i32.stderr | 61 ++- .../clippy/tests/ui/default_trait_access.fixed | 6 +- src/tools/clippy/tests/ui/default_trait_access.rs | 6 +- src/tools/clippy/tests/ui/deref_addrof.fixed | 24 +- src/tools/clippy/tests/ui/deref_addrof.rs | 24 +- src/tools/clippy/tests/ui/deref_addrof.stderr | 38 +- src/tools/clippy/tests/ui/deref_addrof_macro.rs | 15 +- src/tools/clippy/tests/ui/derivable_impls.fixed | 37 ++ src/tools/clippy/tests/ui/derivable_impls.rs | 37 ++ src/tools/clippy/tests/ui/derivable_impls.stderr | 24 +- src/tools/clippy/tests/ui/doc_unsafe.rs | 12 +- src/tools/clippy/tests/ui/double_must_use.rs | 11 + src/tools/clippy/tests/ui/double_must_use.stderr | 10 +- src/tools/clippy/tests/ui/empty_loop.rs | 15 +- src/tools/clippy/tests/ui/equatable_if_let.fixed | 16 +- src/tools/clippy/tests/ui/equatable_if_let.rs | 16 +- src/tools/clippy/tests/ui/equatable_if_let.stderr | 32 +- src/tools/clippy/tests/ui/erasing_op.rs | 8 +- src/tools/clippy/tests/ui/erasing_op.stderr | 10 +- .../tests/ui/extra_unused_type_parameters.fixed | 105 +++++ .../tests/ui/extra_unused_type_parameters.rs | 11 +- .../tests/ui/extra_unused_type_parameters.stderr | 79 ++-- .../ui/extra_unused_type_parameters_unfixable.rs | 24 ++ .../extra_unused_type_parameters_unfixable.stderr | 27 ++ .../clippy/tests/ui/field_reassign_with_default.rs | 36 +- .../tests/ui/field_reassign_with_default.stderr | 44 +- 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/format_args_unfixable.rs | 44 ++ .../clippy/tests/ui/format_args_unfixable.stderr | 36 +- src/tools/clippy/tests/ui/ifs_same_cond.rs | 26 ++ src/tools/clippy/tests/ui/ifs_same_cond.stderr | 14 +- .../clippy/tests/ui/impl_trait_in_params.stderr | 4 +- src/tools/clippy/tests/ui/implicit_clone.fixed | 2 +- src/tools/clippy/tests/ui/implicit_clone.rs | 2 +- src/tools/clippy/tests/ui/implicit_hasher.rs | 25 +- src/tools/clippy/tests/ui/implicit_hasher.stderr | 55 +-- .../tests/ui/inconsistent_struct_constructor.fixed | 21 +- .../tests/ui/inconsistent_struct_constructor.rs | 21 +- .../ui/inconsistent_struct_constructor.stderr | 4 +- src/tools/clippy/tests/ui/integer_arithmetic.rs | 2 +- src/tools/clippy/tests/ui/item_after_statement.rs | 53 --- .../clippy/tests/ui/item_after_statement.stderr | 33 -- src/tools/clippy/tests/ui/items_after_statement.rs | 70 +++ .../clippy/tests/ui/items_after_statement.stderr | 33 ++ src/tools/clippy/tests/ui/large_enum_variant.rs | 13 +- src/tools/clippy/tests/ui/large_futures.rs | 61 +++ src/tools/clippy/tests/ui/large_futures.stderr | 82 ++++ src/tools/clippy/tests/ui/len_without_is_empty.rs | 92 ++++ .../clippy/tests/ui/len_without_is_empty.stderr | 20 +- src/tools/clippy/tests/ui/let_unit.fixed | 4 + src/tools/clippy/tests/ui/let_unit.rs | 4 + .../clippy/tests/ui/let_with_type_underscore.rs | 19 + .../tests/ui/let_with_type_underscore.stderr | 39 ++ .../clippy/tests/ui/lines_filter_map_ok.fixed | 29 ++ src/tools/clippy/tests/ui/lines_filter_map_ok.rs | 29 ++ .../clippy/tests/ui/lines_filter_map_ok.stderr | 51 +++ src/tools/clippy/tests/ui/macro_use_imports.fixed | 6 +- src/tools/clippy/tests/ui/macro_use_imports.rs | 2 +- src/tools/clippy/tests/ui/macro_use_imports.stderr | 4 +- .../clippy/tests/ui/macro_use_imports_expect.rs | 2 +- src/tools/clippy/tests/ui/manual_async_fn.fixed | 6 + src/tools/clippy/tests/ui/manual_async_fn.rs | 12 + src/tools/clippy/tests/ui/manual_async_fn.stderr | 47 +- src/tools/clippy/tests/ui/manual_clamp.rs | 19 + .../tests/ui/manual_main_separator_str.fixed | 39 ++ .../clippy/tests/ui/manual_main_separator_str.rs | 39 ++ .../tests/ui/manual_main_separator_str.stderr | 28 ++ src/tools/clippy/tests/ui/manual_rem_euclid.fixed | 25 +- src/tools/clippy/tests/ui/manual_rem_euclid.rs | 25 +- src/tools/clippy/tests/ui/manual_rem_euclid.stderr | 25 +- .../tests/ui/manual_slice_size_calculation.rs | 36 ++ .../tests/ui/manual_slice_size_calculation.stderr | 51 +++ src/tools/clippy/tests/ui/match_result_ok.fixed | 2 +- src/tools/clippy/tests/ui/match_result_ok.stderr | 2 +- .../clippy/tests/ui/match_single_binding.fixed | 41 +- src/tools/clippy/tests/ui/match_single_binding.rs | 55 ++- .../clippy/tests/ui/match_single_binding.stderr | 111 ++++- .../clippy/tests/ui/match_single_binding2.fixed | 4 +- .../clippy/tests/ui/match_single_binding2.stderr | 4 +- src/tools/clippy/tests/ui/mem_replace.fixed | 34 ++ src/tools/clippy/tests/ui/mem_replace.rs | 34 ++ src/tools/clippy/tests/ui/mem_replace.stderr | 26 +- src/tools/clippy/tests/ui/mem_replace_macro.rs | 23 +- src/tools/clippy/tests/ui/mem_replace_macro.stderr | 11 +- .../clippy/tests/ui/missing_assert_message.rs | 84 ++++ .../clippy/tests/ui/missing_assert_message.stderr | 131 ++++++ .../tests/ui/missing_const_for_fn/cant_be_const.rs | 6 +- src/tools/clippy/tests/ui/missing_doc.rs | 6 +- src/tools/clippy/tests/ui/missing_doc.stderr | 70 +-- src/tools/clippy/tests/ui/missing_doc_impl.rs | 6 +- src/tools/clippy/tests/ui/missing_doc_impl.stderr | 56 +-- .../clippy/tests/ui/mistyped_literal_suffix.fixed | 6 +- .../clippy/tests/ui/mistyped_literal_suffix.rs | 6 +- .../tests/ui/multiple_unsafe_ops_per_block.rs | 39 +- .../tests/ui/multiple_unsafe_ops_per_block.stderr | 62 ++- src/tools/clippy/tests/ui/must_use_unit.fixed | 11 +- src/tools/clippy/tests/ui/must_use_unit.rs | 11 +- src/tools/clippy/tests/ui/mut_mut.rs | 11 +- src/tools/clippy/tests/ui/mut_mut.stderr | 25 +- src/tools/clippy/tests/ui/needless_late_init.fixed | 36 +- src/tools/clippy/tests/ui/needless_late_init.rs | 36 +- .../clippy/tests/ui/needless_late_init.stderr | 32 +- src/tools/clippy/tests/ui/needless_lifetimes.fixed | 37 +- src/tools/clippy/tests/ui/needless_lifetimes.rs | 37 +- .../clippy/tests/ui/needless_lifetimes.stderr | 15 +- src/tools/clippy/tests/ui/needless_return.fixed | 9 + src/tools/clippy/tests/ui/needless_return.rs | 9 + src/tools/clippy/tests/ui/needless_update.rs | 2 +- src/tools/clippy/tests/ui/new_ret_no_self.rs | 2 +- src/tools/clippy/tests/ui/no_effect.rs | 10 +- src/tools/clippy/tests/ui/no_effect.stderr | 66 ++- .../clippy/tests/ui/no_mangle_with_rust_abi.fixed | 48 --- .../clippy/tests/ui/no_mangle_with_rust_abi.rs | 2 - .../clippy/tests/ui/no_mangle_with_rust_abi.stderr | 74 +++- src/tools/clippy/tests/ui/nonminimal_bool.rs | 47 ++ src/tools/clippy/tests/ui/option_env_unwrap.rs | 24 +- src/tools/clippy/tests/ui/option_env_unwrap.stderr | 42 +- .../clippy/tests/ui/overflow_check_conditional.rs | 9 +- .../tests/ui/overflow_check_conditional.stderr | 16 +- src/tools/clippy/tests/ui/print_literal.rs | 4 + src/tools/clippy/tests/ui/ptr_as_ptr.fixed | 16 +- src/tools/clippy/tests/ui/ptr_as_ptr.rs | 16 +- src/tools/clippy/tests/ui/ptr_as_ptr.stderr | 25 +- .../clippy/tests/ui/redundant_async_block.fixed | 193 +++++++++ src/tools/clippy/tests/ui/redundant_async_block.rs | 193 +++++++++ .../clippy/tests/ui/redundant_async_block.stderr | 74 ++++ .../tests/ui/redundant_closure_call_fixable.fixed | 1 + .../tests/ui/redundant_closure_call_fixable.rs | 1 + .../tests/ui/redundant_closure_call_fixable.stderr | 12 +- .../ui/redundant_pattern_matching_result.fixed | 4 +- .../ui/redundant_pattern_matching_result.stderr | 4 +- .../tests/ui/single_component_path_imports.fixed | 6 + .../tests/ui/single_component_path_imports.rs | 6 + .../tests/ui/single_component_path_imports.stderr | 4 +- src/tools/clippy/tests/ui/single_match_else.rs | 6 +- src/tools/clippy/tests/ui/string_add.rs | 11 +- .../clippy/tests/ui/suspicious_doc_comments.fixed | 81 ++++ .../clippy/tests/ui/suspicious_doc_comments.rs | 81 ++++ .../clippy/tests/ui/suspicious_doc_comments.stderr | 114 +++++ .../tests/ui/suspicious_doc_comments_unfixable.rs | 16 + .../ui/suspicious_doc_comments_unfixable.stderr | 37 ++ src/tools/clippy/tests/ui/swap.fixed | 21 +- src/tools/clippy/tests/ui/swap.rs | 15 +- src/tools/clippy/tests/ui/swap.stderr | 58 +-- .../clippy/tests/ui/tests_outside_test_module.rs | 18 + .../tests/ui/tests_outside_test_module.stderr | 11 + src/tools/clippy/tests/ui/toplevel_ref_arg.fixed | 24 +- src/tools/clippy/tests/ui/toplevel_ref_arg.rs | 24 +- src/tools/clippy/tests/ui/toplevel_ref_arg.stderr | 21 +- .../tests/ui/toplevel_ref_arg_non_rustfix.rs | 22 +- .../tests/ui/toplevel_ref_arg_non_rustfix.stderr | 7 +- src/tools/clippy/tests/ui/trailing_empty_array.rs | 2 - .../ui/transmutes_expressible_as_ptr_casts.fixed | 8 +- .../ui/transmutes_expressible_as_ptr_casts.rs | 8 +- .../ui/transmutes_expressible_as_ptr_casts.stderr | 8 +- src/tools/clippy/tests/ui/try_err.fixed | 65 +-- src/tools/clippy/tests/ui/try_err.rs | 65 +-- src/tools/clippy/tests/ui/try_err.stderr | 32 +- src/tools/clippy/tests/ui/uninit.rs | 39 +- src/tools/clippy/tests/ui/uninit.stderr | 14 +- src/tools/clippy/tests/ui/uninit_vec.rs | 35 ++ src/tools/clippy/tests/ui/uninit_vec.stderr | 33 +- .../clippy/tests/ui/uninlined_format_args.fixed | 94 +++- src/tools/clippy/tests/ui/uninlined_format_args.rs | 92 +++- .../clippy/tests/ui/uninlined_format_args.stderr | 14 +- src/tools/clippy/tests/ui/unit_arg.rs | 6 +- .../clippy/tests/ui/unnecessary_box_returns.rs | 60 +++ .../clippy/tests/ui/unnecessary_box_returns.stderr | 35 ++ .../clippy/tests/ui/unnecessary_lazy_eval.fixed | 6 +- src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs | 6 +- .../clippy/tests/ui/unnecessary_operation.fixed | 10 +- src/tools/clippy/tests/ui/unnecessary_operation.rs | 10 +- .../clippy/tests/ui/unnecessary_operation.stderr | 46 +- .../ui/unnecessary_struct_initialization.fixed | 73 ++++ .../tests/ui/unnecessary_struct_initialization.rs | 77 ++++ .../ui/unnecessary_struct_initialization.stderr | 46 ++ .../clippy/tests/ui/unnecessary_unsafety_doc.rs | 12 +- .../tests/ui/unnecessary_unsafety_doc.stderr | 2 +- .../clippy/tests/ui/unused_format_specs.fixed | 18 - src/tools/clippy/tests/ui/unused_format_specs.rs | 18 - .../clippy/tests/ui/unused_format_specs.stderr | 54 --- .../tests/ui/unused_format_specs_unfixable.stderr | 12 +- src/tools/clippy/tests/ui/use_self.fixed | 10 + src/tools/clippy/tests/ui/use_self.rs | 10 + 226 files changed, 6279 insertions(+), 2057 deletions(-) create mode 100644 src/tools/clippy/tests/ui/allow_attributes.fixed create mode 100644 src/tools/clippy/tests/ui/allow_attributes.rs create mode 100644 src/tools/clippy/tests/ui/allow_attributes.stderr delete mode 100644 src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs delete mode 100644 src/tools/clippy/tests/ui/auxiliary/implicit_hasher_macros.rs delete mode 100644 src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs create mode 100644 src/tools/clippy/tests/ui/auxiliary/proc_macros.rs create mode 100644 src/tools/clippy/tests/ui/clear_with_drain.fixed create mode 100644 src/tools/clippy/tests/ui/clear_with_drain.rs create mode 100644 src/tools/clippy/tests/ui/clear_with_drain.stderr create mode 100644 src/tools/clippy/tests/ui/collection_is_never_read.rs create mode 100644 src/tools/clippy/tests/ui/collection_is_never_read.stderr create mode 100644 src/tools/clippy/tests/ui/crashes/ice-10148.rs create mode 100644 src/tools/clippy/tests/ui/crashes/ice-10148.stderr create mode 100644 src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed create mode 100644 src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs create mode 100644 src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr delete mode 100644 src/tools/clippy/tests/ui/item_after_statement.rs delete mode 100644 src/tools/clippy/tests/ui/item_after_statement.stderr create mode 100644 src/tools/clippy/tests/ui/items_after_statement.rs create mode 100644 src/tools/clippy/tests/ui/items_after_statement.stderr create mode 100644 src/tools/clippy/tests/ui/large_futures.rs create mode 100644 src/tools/clippy/tests/ui/large_futures.stderr create mode 100644 src/tools/clippy/tests/ui/let_with_type_underscore.rs create mode 100644 src/tools/clippy/tests/ui/let_with_type_underscore.stderr create mode 100644 src/tools/clippy/tests/ui/lines_filter_map_ok.fixed create mode 100644 src/tools/clippy/tests/ui/lines_filter_map_ok.rs create mode 100644 src/tools/clippy/tests/ui/lines_filter_map_ok.stderr create mode 100644 src/tools/clippy/tests/ui/manual_main_separator_str.fixed create mode 100644 src/tools/clippy/tests/ui/manual_main_separator_str.rs create mode 100644 src/tools/clippy/tests/ui/manual_main_separator_str.stderr create mode 100644 src/tools/clippy/tests/ui/manual_slice_size_calculation.rs create mode 100644 src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr create mode 100644 src/tools/clippy/tests/ui/missing_assert_message.rs create mode 100644 src/tools/clippy/tests/ui/missing_assert_message.stderr delete mode 100644 src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed create mode 100644 src/tools/clippy/tests/ui/redundant_async_block.fixed create mode 100644 src/tools/clippy/tests/ui/redundant_async_block.rs create mode 100644 src/tools/clippy/tests/ui/redundant_async_block.stderr create mode 100644 src/tools/clippy/tests/ui/suspicious_doc_comments.fixed create mode 100644 src/tools/clippy/tests/ui/suspicious_doc_comments.rs create mode 100644 src/tools/clippy/tests/ui/suspicious_doc_comments.stderr create mode 100644 src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs create mode 100644 src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr create mode 100644 src/tools/clippy/tests/ui/tests_outside_test_module.rs create mode 100644 src/tools/clippy/tests/ui/tests_outside_test_module.stderr create mode 100644 src/tools/clippy/tests/ui/unnecessary_box_returns.rs create mode 100644 src/tools/clippy/tests/ui/unnecessary_box_returns.stderr create mode 100644 src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed create mode 100644 src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs create mode 100644 src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr delete mode 100644 src/tools/clippy/tests/ui/unused_format_specs.fixed delete mode 100644 src/tools/clippy/tests/ui/unused_format_specs.rs delete mode 100644 src/tools/clippy/tests/ui/unused_format_specs.stderr (limited to 'src/tools/clippy/tests/ui') diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed new file mode 100644 index 000000000..b8dd0619e --- /dev/null +++ b/src/tools/clippy/tests/ui/allow_attributes.fixed @@ -0,0 +1,25 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::allow_attributes)] +#![feature(lint_reasons)] + +fn main() {} + +// Using clippy::needless_borrow just as a placeholder, it isn't relevant. + +// Should lint +#[expect(dead_code)] +struct T1; + +struct T2; // Should not lint +#[deny(clippy::needless_borrow)] // Should not lint +struct T3; +#[warn(clippy::needless_borrow)] // Should not lint +struct T4; +// `panic = "unwind"` should always be true +#[cfg_attr(panic = "unwind", expect(dead_code))] +struct CfgT; + +fn ignore_inner_attr() { + #![allow(unused)] // Should not lint +} diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs new file mode 100644 index 000000000..295f56090 --- /dev/null +++ b/src/tools/clippy/tests/ui/allow_attributes.rs @@ -0,0 +1,25 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::allow_attributes)] +#![feature(lint_reasons)] + +fn main() {} + +// Using clippy::needless_borrow just as a placeholder, it isn't relevant. + +// Should lint +#[allow(dead_code)] +struct T1; + +struct T2; // Should not lint +#[deny(clippy::needless_borrow)] // Should not lint +struct T3; +#[warn(clippy::needless_borrow)] // Should not lint +struct T4; +// `panic = "unwind"` should always be true +#[cfg_attr(panic = "unwind", allow(dead_code))] +struct CfgT; + +fn ignore_inner_attr() { + #![allow(unused)] // Should not lint +} diff --git a/src/tools/clippy/tests/ui/allow_attributes.stderr b/src/tools/clippy/tests/ui/allow_attributes.stderr new file mode 100644 index 000000000..681837e9e --- /dev/null +++ b/src/tools/clippy/tests/ui/allow_attributes.stderr @@ -0,0 +1,16 @@ +error: #[allow] attribute found + --> $DIR/allow_attributes.rs:11:3 + | +LL | #[allow(dead_code)] + | ^^^^^ help: replace it with: `expect` + | + = note: `-D clippy::allow-attributes` implied by `-D warnings` + +error: #[allow] attribute found + --> $DIR/allow_attributes.rs:20:30 + | +LL | #[cfg_attr(panic = "unwind", allow(dead_code))] + | ^^^^^ help: replace it with: `expect` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/almost_complete_range.fixed b/src/tools/clippy/tests/ui/almost_complete_range.fixed index 6046addf7..a4bf7fe18 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.fixed +++ b/src/tools/clippy/tests/ui/almost_complete_range.fixed @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] @@ -9,33 +9,10 @@ #![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::double_parens)] -#[macro_use] -extern crate macro_rules; - -macro_rules! a { - () => { - 'a' - }; -} -macro_rules! A { - () => { - 'A' - }; -} -macro_rules! zero { - () => { - '0' - }; -} - -macro_rules! b { - () => { - let _ = 'a'..='z'; - let _ = 'A'..='Z'; - let _ = '0'..='9'; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { #[rustfmt::skip] { @@ -56,9 +33,9 @@ fn main() { let _ = b'B'..b'Z'; let _ = b'1'..b'9'; - let _ = a!()..='z'; - let _ = A!()..='Z'; - let _ = zero!()..='9'; + let _ = inline!('a')..='z'; + let _ = inline!('A')..='Z'; + let _ = inline!('0')..='9'; let _ = match 0u8 { b'a'..=b'z' if true => 1, @@ -80,8 +57,16 @@ fn main() { _ => 7, }; - almost_complete_range!(); - b!(); + external!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); + inline!( + let _ = 'a'..='z'; + let _ = 'A'..='Z'; + let _ = '0'..='9'; + ); } #[clippy::msrv = "1.25"] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.rs b/src/tools/clippy/tests/ui/almost_complete_range.rs index ae7e07ab8..8237c3a13 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.rs +++ b/src/tools/clippy/tests/ui/almost_complete_range.rs @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] @@ -9,33 +9,10 @@ #![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::double_parens)] -#[macro_use] -extern crate macro_rules; - -macro_rules! a { - () => { - 'a' - }; -} -macro_rules! A { - () => { - 'A' - }; -} -macro_rules! zero { - () => { - '0' - }; -} - -macro_rules! b { - () => { - let _ = 'a'..'z'; - let _ = 'A'..'Z'; - let _ = '0'..'9'; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { #[rustfmt::skip] { @@ -56,9 +33,9 @@ fn main() { let _ = b'B'..b'Z'; let _ = b'1'..b'9'; - let _ = a!()..'z'; - let _ = A!()..'Z'; - let _ = zero!()..'9'; + let _ = inline!('a')..'z'; + let _ = inline!('A')..'Z'; + let _ = inline!('0')..'9'; let _ = match 0u8 { b'a'..b'z' if true => 1, @@ -80,8 +57,16 @@ fn main() { _ => 7, }; - almost_complete_range!(); - b!(); + external!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); + inline!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); } #[clippy::msrv = "1.25"] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.stderr b/src/tools/clippy/tests/ui/almost_complete_range.stderr index a7a532878..34521c13a 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.stderr +++ b/src/tools/clippy/tests/ui/almost_complete_range.stderr @@ -1,5 +1,5 @@ error: almost complete ascii range - --> $DIR/almost_complete_range.rs:42:17 + --> $DIR/almost_complete_range.rs:19:17 | LL | let _ = ('a') ..'z'; | ^^^^^^--^^^ @@ -9,7 +9,7 @@ LL | let _ = ('a') ..'z'; = note: `-D clippy::almost-complete-range` implied by `-D warnings` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:43:17 + --> $DIR/almost_complete_range.rs:20:17 | LL | let _ = 'A' .. ('Z'); | ^^^^--^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = 'A' .. ('Z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:44:17 + --> $DIR/almost_complete_range.rs:21:17 | LL | let _ = ((('0'))) .. ('9'); | ^^^^^^^^^^--^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = ((('0'))) .. ('9'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:51:13 + --> $DIR/almost_complete_range.rs:28:13 | LL | let _ = (b'a')..(b'z'); | ^^^^^^--^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = (b'a')..(b'z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:52:13 + --> $DIR/almost_complete_range.rs:29:13 | LL | let _ = b'A'..b'Z'; | ^^^^--^^^^ @@ -41,7 +41,7 @@ LL | let _ = b'A'..b'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:53:13 + --> $DIR/almost_complete_range.rs:30:13 | LL | let _ = b'0'..b'9'; | ^^^^--^^^^ @@ -49,31 +49,31 @@ LL | let _ = b'0'..b'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:59:13 + --> $DIR/almost_complete_range.rs:36:13 | -LL | let _ = a!()..'z'; - | ^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('a')..'z'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:60:13 + --> $DIR/almost_complete_range.rs:37:13 | -LL | let _ = A!()..'Z'; - | ^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('A')..'Z'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:61:13 + --> $DIR/almost_complete_range.rs:38:13 | -LL | let _ = zero!()..'9'; - | ^^^^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('0')..'9'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:64:9 + --> $DIR/almost_complete_range.rs:41:9 | LL | b'a'..b'z' if true => 1, | ^^^^--^^^^ @@ -81,7 +81,7 @@ LL | b'a'..b'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:65:9 + --> $DIR/almost_complete_range.rs:42:9 | LL | b'A'..b'Z' if true => 2, | ^^^^--^^^^ @@ -89,7 +89,7 @@ LL | b'A'..b'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:66:9 + --> $DIR/almost_complete_range.rs:43:9 | LL | b'0'..b'9' if true => 3, | ^^^^--^^^^ @@ -97,7 +97,7 @@ LL | b'0'..b'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:74:9 + --> $DIR/almost_complete_range.rs:51:9 | LL | 'a'..'z' if true => 1, | ^^^--^^^ @@ -105,7 +105,7 @@ LL | 'a'..'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:75:9 + --> $DIR/almost_complete_range.rs:52:9 | LL | 'A'..'Z' if true => 2, | ^^^--^^^ @@ -113,7 +113,7 @@ LL | 'A'..'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:76:9 + --> $DIR/almost_complete_range.rs:53:9 | LL | '0'..'9' if true => 3, | ^^^--^^^ @@ -121,46 +121,37 @@ LL | '0'..'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:33:17 + --> $DIR/almost_complete_range.rs:66:17 | LL | let _ = 'a'..'z'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:34:17 + --> $DIR/almost_complete_range.rs:67:17 | LL | let _ = 'A'..'Z'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:35:17 + --> $DIR/almost_complete_range.rs:68:17 | LL | let _ = '0'..'9'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:90:9 + --> $DIR/almost_complete_range.rs:75:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -168,7 +159,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:91:9 + --> $DIR/almost_complete_range.rs:76:9 | LL | 'A'..'Z' => 2, | ^^^--^^^ @@ -176,7 +167,7 @@ LL | 'A'..'Z' => 2, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:92:9 + --> $DIR/almost_complete_range.rs:77:9 | LL | '0'..'9' => 3, | ^^^--^^^ @@ -184,7 +175,7 @@ LL | '0'..'9' => 3, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:99:13 + --> $DIR/almost_complete_range.rs:84:13 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -192,7 +183,7 @@ LL | let _ = 'a'..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:100:13 + --> $DIR/almost_complete_range.rs:85:13 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -200,7 +191,7 @@ LL | let _ = 'A'..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:101:13 + --> $DIR/almost_complete_range.rs:86:13 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -208,7 +199,7 @@ LL | let _ = '0'..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:103:9 + --> $DIR/almost_complete_range.rs:88:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -216,7 +207,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:104:9 + --> $DIR/almost_complete_range.rs:89:9 | LL | 'A'..'Z' => 1, | ^^^--^^^ @@ -224,7 +215,7 @@ LL | 'A'..'Z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:105:9 + --> $DIR/almost_complete_range.rs:90:9 | LL | '0'..'9' => 3, | ^^^--^^^ diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index 2611e3a78..3c06676d7 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -45,24 +45,32 @@ impl_arith!( Div, Custom, Custom, div; Mul, Custom, Custom, mul; Rem, Custom, Custom, rem; + Shl, Custom, Custom, shl; + Shr, Custom, Custom, shr; Sub, Custom, Custom, sub; Add, Custom, &Custom, add; Div, Custom, &Custom, div; Mul, Custom, &Custom, mul; Rem, Custom, &Custom, rem; + Shl, Custom, &Custom, shl; + Shr, Custom, &Custom, shr; Sub, Custom, &Custom, sub; Add, &Custom, Custom, add; Div, &Custom, Custom, div; Mul, &Custom, Custom, mul; Rem, &Custom, Custom, rem; + Shl, &Custom, Custom, shl; + Shr, &Custom, Custom, shr; Sub, &Custom, Custom, sub; Add, &Custom, &Custom, add; Div, &Custom, &Custom, div; Mul, &Custom, &Custom, mul; Rem, &Custom, &Custom, rem; + Shl, &Custom, &Custom, shl; + Shr, &Custom, &Custom, shr; Sub, &Custom, &Custom, sub; ); @@ -71,24 +79,32 @@ impl_assign_arith!( DivAssign, Custom, Custom, div_assign; MulAssign, Custom, Custom, mul_assign; RemAssign, Custom, Custom, rem_assign; + ShlAssign, Custom, Custom, shl_assign; + ShrAssign, Custom, Custom, shr_assign; SubAssign, Custom, Custom, sub_assign; AddAssign, Custom, &Custom, add_assign; DivAssign, Custom, &Custom, div_assign; MulAssign, Custom, &Custom, mul_assign; RemAssign, Custom, &Custom, rem_assign; + ShlAssign, Custom, &Custom, shl_assign; + ShrAssign, Custom, &Custom, shr_assign; SubAssign, Custom, &Custom, sub_assign; AddAssign, &Custom, Custom, add_assign; DivAssign, &Custom, Custom, div_assign; MulAssign, &Custom, Custom, mul_assign; RemAssign, &Custom, Custom, rem_assign; + ShlAssign, &Custom, Custom, shl_assign; + ShrAssign, &Custom, Custom, shr_assign; SubAssign, &Custom, Custom, sub_assign; AddAssign, &Custom, &Custom, add_assign; DivAssign, &Custom, &Custom, div_assign; MulAssign, &Custom, &Custom, mul_assign; RemAssign, &Custom, &Custom, rem_assign; + ShlAssign, &Custom, &Custom, shl_assign; + ShrAssign, &Custom, &Custom, shr_assign; SubAssign, &Custom, &Custom, sub_assign; ); @@ -297,6 +313,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom %= &Custom; _custom *= Custom; _custom *= &Custom; + _custom >>= Custom; + _custom >>= &Custom; + _custom <<= Custom; + _custom <<= &Custom; _custom += -Custom; _custom += &-Custom; _custom -= -Custom; @@ -307,6 +327,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom %= &-Custom; _custom *= -Custom; _custom *= &-Custom; + _custom >>= -Custom; + _custom >>= &-Custom; + _custom <<= -Custom; + _custom <<= &-Custom; // Binary _n = _n + 1; @@ -347,6 +371,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom = Custom + &Custom; _custom = &Custom + Custom; _custom = &Custom + &Custom; + _custom = _custom >> _custom; + _custom = _custom >> &_custom; + _custom = Custom << _custom; + _custom = &Custom << _custom; // Unary _n = -_n; @@ -397,4 +425,8 @@ pub fn integer_arithmetic() { i ^= i; } +pub fn issue_10583(a: u16) -> u16 { + 10 / a +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr index 17a2448fb..2c8ee2884 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:270:5 + --> $DIR/arithmetic_side_effects.rs:286:5 | LL | _n += 1; | ^^^^^^^ @@ -7,592 +7,652 @@ 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:271:5 + --> $DIR/arithmetic_side_effects.rs:287:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:272:5 + --> $DIR/arithmetic_side_effects.rs:288:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:273:5 + --> $DIR/arithmetic_side_effects.rs:289:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:274:5 + --> $DIR/arithmetic_side_effects.rs:290:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:275:5 + --> $DIR/arithmetic_side_effects.rs:291:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:276:5 + --> $DIR/arithmetic_side_effects.rs:292:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:277:5 + --> $DIR/arithmetic_side_effects.rs:293:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:278:5 + --> $DIR/arithmetic_side_effects.rs:294:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:279:5 + --> $DIR/arithmetic_side_effects.rs:295:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:280:5 + --> $DIR/arithmetic_side_effects.rs:296:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:281:5 + --> $DIR/arithmetic_side_effects.rs:297:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:282:5 + --> $DIR/arithmetic_side_effects.rs:298:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:283:5 + --> $DIR/arithmetic_side_effects.rs:299:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:284:5 + --> $DIR/arithmetic_side_effects.rs:300:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:285:5 + --> $DIR/arithmetic_side_effects.rs:301:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:286:5 + --> $DIR/arithmetic_side_effects.rs:302:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:287:5 + --> $DIR/arithmetic_side_effects.rs:303:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:288:5 + --> $DIR/arithmetic_side_effects.rs:304:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:289:5 + --> $DIR/arithmetic_side_effects.rs:305:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:290: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:291: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:292: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:293: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:294:5 + --> $DIR/arithmetic_side_effects.rs:310:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:295:5 + --> $DIR/arithmetic_side_effects.rs:311:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:296:5 + --> $DIR/arithmetic_side_effects.rs:312:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:297:5 + --> $DIR/arithmetic_side_effects.rs:313:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:298:5 + --> $DIR/arithmetic_side_effects.rs:314:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:299:5 + --> $DIR/arithmetic_side_effects.rs:315:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:300:5 + --> $DIR/arithmetic_side_effects.rs:316:5 + | +LL | _custom >>= Custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:317:5 + | +LL | _custom >>= &Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:318:5 + | +LL | _custom <<= Custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:319:5 + | +LL | _custom <<= &Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:320:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:301:5 + --> $DIR/arithmetic_side_effects.rs:321:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:302:5 + --> $DIR/arithmetic_side_effects.rs:322:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:303:5 + --> $DIR/arithmetic_side_effects.rs:323:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:304:5 + --> $DIR/arithmetic_side_effects.rs:324:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:305:5 + --> $DIR/arithmetic_side_effects.rs:325:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:306:5 + --> $DIR/arithmetic_side_effects.rs:326:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:307:5 + --> $DIR/arithmetic_side_effects.rs:327:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:308:5 + --> $DIR/arithmetic_side_effects.rs:328:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:309:5 + --> $DIR/arithmetic_side_effects.rs:329:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:312:10 + --> $DIR/arithmetic_side_effects.rs:330:5 + | +LL | _custom >>= -Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:331:5 + | +LL | _custom >>= &-Custom; + | ^^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:332:5 + | +LL | _custom <<= -Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:333:5 + | +LL | _custom <<= &-Custom; + | ^^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:336:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:313:10 + --> $DIR/arithmetic_side_effects.rs:337:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:314:10 + --> $DIR/arithmetic_side_effects.rs:338:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:315:10 + --> $DIR/arithmetic_side_effects.rs:339:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:316:10 + --> $DIR/arithmetic_side_effects.rs:340:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:317:10 + --> $DIR/arithmetic_side_effects.rs:341:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:318:10 + --> $DIR/arithmetic_side_effects.rs:342:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:319:10 + --> $DIR/arithmetic_side_effects.rs:343:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:320:10 + --> $DIR/arithmetic_side_effects.rs:344:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:321:10 + --> $DIR/arithmetic_side_effects.rs:345:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:322:10 + --> $DIR/arithmetic_side_effects.rs:346:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:323:10 + --> $DIR/arithmetic_side_effects.rs:347:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:324:10 + --> $DIR/arithmetic_side_effects.rs:348:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:325:10 + --> $DIR/arithmetic_side_effects.rs:349:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:326:10 + --> $DIR/arithmetic_side_effects.rs:350:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:327:10 + --> $DIR/arithmetic_side_effects.rs:351:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:328:10 + --> $DIR/arithmetic_side_effects.rs:352:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:329:10 + --> $DIR/arithmetic_side_effects.rs:353:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:330:10 + --> $DIR/arithmetic_side_effects.rs:354:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:331:15 + --> $DIR/arithmetic_side_effects.rs:355:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:332:15 + --> $DIR/arithmetic_side_effects.rs:356:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:333:15 + --> $DIR/arithmetic_side_effects.rs:357:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:334:15 + --> $DIR/arithmetic_side_effects.rs:358:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:335:15 + --> $DIR/arithmetic_side_effects.rs:359:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:336:15 + --> $DIR/arithmetic_side_effects.rs:360:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:337:15 + --> $DIR/arithmetic_side_effects.rs:361:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:338:15 + --> $DIR/arithmetic_side_effects.rs:362:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:339:15 + --> $DIR/arithmetic_side_effects.rs:363:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:340:15 + --> $DIR/arithmetic_side_effects.rs:364:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:341:15 + --> $DIR/arithmetic_side_effects.rs:365:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:342:15 + --> $DIR/arithmetic_side_effects.rs:366:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:343:15 + --> $DIR/arithmetic_side_effects.rs:367:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:344:15 + --> $DIR/arithmetic_side_effects.rs:368:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:345:15 + --> $DIR/arithmetic_side_effects.rs:369:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:346:15 + --> $DIR/arithmetic_side_effects.rs:370:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:347:15 + --> $DIR/arithmetic_side_effects.rs:371:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:348:15 + --> $DIR/arithmetic_side_effects.rs:372:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:349:15 + --> $DIR/arithmetic_side_effects.rs:373:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:352:10 + --> $DIR/arithmetic_side_effects.rs:374:15 + | +LL | _custom = _custom >> _custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:375:15 + | +LL | _custom = _custom >> &_custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:376:15 + | +LL | _custom = Custom << _custom; + | ^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:377:15 + | +LL | _custom = &Custom << _custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:380:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:353:10 + --> $DIR/arithmetic_side_effects.rs:381:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:354:15 + --> $DIR/arithmetic_side_effects.rs:382:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:355:15 + --> $DIR/arithmetic_side_effects.rs:383:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:364:5 + --> $DIR/arithmetic_side_effects.rs:392:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:365:5 + --> $DIR/arithmetic_side_effects.rs:393:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:367:5 + --> $DIR/arithmetic_side_effects.rs:394:5 + | +LL | 1 % i / 2; + | ^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:395:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:368:5 + --> $DIR/arithmetic_side_effects.rs:396:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $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:370:5 - | -LL | i << 1; - | ^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:379:5 + --> $DIR/arithmetic_side_effects.rs:407:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:380:5 + --> $DIR/arithmetic_side_effects.rs:408:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:381:5 + --> $DIR/arithmetic_side_effects.rs:409:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:383:5 + --> $DIR/arithmetic_side_effects.rs:411:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:385:5 + --> $DIR/arithmetic_side_effects.rs:413:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:386:5 + --> $DIR/arithmetic_side_effects.rs:414:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:388:5 + --> $DIR/arithmetic_side_effects.rs:416:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:390:5 + --> $DIR/arithmetic_side_effects.rs:418:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:391:5 + --> $DIR/arithmetic_side_effects.rs:419:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:392:5 + --> $DIR/arithmetic_side_effects.rs:429:5 | -LL | i <<= 3; - | ^^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:393:5 - | -LL | i >>= 2; - | ^^^^^^^ +LL | 10 / a + | ^^^^^^ -error: aborting due to 99 previous errors +error: aborting due to 109 previous errors diff --git a/src/tools/clippy/tests/ui/as_conversions.rs b/src/tools/clippy/tests/ui/as_conversions.rs index ba4394def..c50d4088b 100644 --- a/src/tools/clippy/tests/ui/as_conversions.rs +++ b/src/tools/clippy/tests/ui/as_conversions.rs @@ -1,20 +1,15 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::as_conversions)] #![allow(clippy::borrow_as_ptr)] -#[macro_use] -extern crate macro_rules; - -fn with_external_macro() { - as_conv_with_arg!(0u32 as u64); - as_conv!(); -} +extern crate proc_macros; +use proc_macros::external; fn main() { let i = 0u32 as u64; let j = &i as *const u64 as *mut u64; - with_external_macro(); + external!(0u32 as u64); } diff --git a/src/tools/clippy/tests/ui/as_conversions.stderr b/src/tools/clippy/tests/ui/as_conversions.stderr index f5d59e1e5..54037a649 100644 --- a/src/tools/clippy/tests/ui/as_conversions.stderr +++ b/src/tools/clippy/tests/ui/as_conversions.stderr @@ -1,5 +1,5 @@ error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:15:13 + --> $DIR/as_conversions.rs:10:13 | LL | let i = 0u32 as u64; | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let i = 0u32 as u64; = note: `-D clippy::as-conversions` implied by `-D warnings` error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:17:13 + --> $DIR/as_conversions.rs:12:13 | LL | let j = &i as *const u64 as *mut u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let j = &i as *const u64 as *mut u64; = help: consider using a safe wrapper for this conversion error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:17:13 + --> $DIR/as_conversions.rs:12:13 | LL | let j = &i as *const u64 as *mut u64; | ^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed index 3cf380d2b..579a63ea4 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.fixed +++ b/src/tools/clippy/tests/ui/async_yields_async.fixed @@ -2,6 +2,7 @@ #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] +#![allow(clippy::redundant_async_block)] use core::future::Future; use core::pin::Pin; diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs index dd4131b60..5aec2fb50 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.rs +++ b/src/tools/clippy/tests/ui/async_yields_async.rs @@ -2,6 +2,7 @@ #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] +#![allow(clippy::redundant_async_block)] use core::future::Future; use core::pin::Pin; diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr index 22ce1c6f6..7f7253483 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.stderr +++ b/src/tools/clippy/tests/ui/async_yields_async.stderr @@ -1,5 +1,5 @@ error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:39:9 + --> $DIR/async_yields_async.rs:40:9 | LL | let _h = async { | _____________________- @@ -19,7 +19,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:44:9 + --> $DIR/async_yields_async.rs:45:9 | LL | let _i = async { | ____________________- @@ -32,7 +32,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:50:9 + --> $DIR/async_yields_async.rs:51:9 | LL | let _j = async || { | ________________________- @@ -51,7 +51,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:55:9 + --> $DIR/async_yields_async.rs:56:9 | LL | let _k = async || { | _______________________- @@ -64,7 +64,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:57:23 + --> $DIR/async_yields_async.rs:58:23 | LL | let _l = async || CustomFutureType; | ^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | let _l = async || CustomFutureType; | help: consider awaiting this value: `CustomFutureType.await` error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:63:9 + --> $DIR/async_yields_async.rs:64:9 | LL | let _m = async || { | _______________________- diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout index c6acf24c2..eb3e5189c 100644 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ b/src/tools/clippy/tests/ui/author/blocks.stdout @@ -43,11 +43,7 @@ if let ExprKind::Block(block, None) = expr.kind if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output && expr1 = &cx.tcx.hir().body(body_id).value - && let ExprKind::Call(func, args) = expr1.kind - && let ExprKind::Path(ref qpath) = func.kind - && matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _)) - && args.len() == 1 - && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind + && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output && expr2 = &cx.tcx.hir().body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind diff --git a/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs b/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs deleted file mode 100644 index 3d917e3dc..000000000 --- a/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[macro_export] -macro_rules! undocd_unsafe { - () => { - pub unsafe fn oy_vey() { - unimplemented!(); - } - }; -} -#[macro_export] -macro_rules! undocd_safe { - () => { - pub fn vey_oy() { - unimplemented!(); - } - }; -} diff --git a/src/tools/clippy/tests/ui/auxiliary/implicit_hasher_macros.rs b/src/tools/clippy/tests/ui/auxiliary/implicit_hasher_macros.rs deleted file mode 100644 index 1eb77c531..000000000 --- a/src/tools/clippy/tests/ui/auxiliary/implicit_hasher_macros.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_export] -macro_rules! implicit_hasher_fn { - () => { - pub fn f(input: &HashMap) {} - }; -} diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs index a13af5652..a9bb61451 100644 --- a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs +++ b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs @@ -2,21 +2,6 @@ //! Used to test that certain lints don't trigger in imported external macros -#[macro_export] -macro_rules! foofoo { - () => { - loop {} - }; -} - -#[macro_export] -macro_rules! must_use_unit { - () => { - #[must_use] - fn foo() {} - }; -} - #[macro_export] macro_rules! try_err { () => { @@ -36,84 +21,6 @@ macro_rules! string_add { }; } -#[macro_export] -macro_rules! take_external { - ($s:expr) => { - std::mem::replace($s, Default::default()) - }; -} - -#[macro_export] -macro_rules! option_env_unwrap_external { - ($env: expr) => { - option_env!($env).unwrap() - }; - ($env: expr, $message: expr) => { - option_env!($env).expect($message) - }; -} - -#[macro_export] -macro_rules! ref_arg_binding { - () => { - let ref _y = 42; - }; -} - -#[macro_export] -macro_rules! ref_arg_function { - () => { - fn fun_example(ref _x: usize) {} - }; -} - -#[macro_export] -macro_rules! as_conv_with_arg { - (0u32 as u64) => { - () - }; -} - -#[macro_export] -macro_rules! as_conv { - () => { - 0u32 as u64 - }; -} - -#[macro_export] -macro_rules! large_enum_variant { - () => { - enum LargeEnumInMacro { - A(i32), - B([i32; 8000]), - } - }; -} - -#[macro_export] -macro_rules! field_reassign_with_default { - () => { - #[derive(Default)] - struct A { - pub i: i32, - pub j: i64, - } - fn lint() { - let mut a: A = Default::default(); - a.i = 42; - a; - } - }; -} - -#[macro_export] -macro_rules! default_numeric_fallback { - () => { - let x = 22; - }; -} - #[macro_export] macro_rules! mut_mut { () => { @@ -122,49 +29,11 @@ macro_rules! mut_mut { } #[macro_export] -macro_rules! ptr_as_ptr_cast { - ($ptr: ident) => { - $ptr as *const i32 - }; -} - -#[macro_export] -macro_rules! manual_rem_euclid { +macro_rules! issue_10421 { () => { - let value: i32 = 5; - let _: i32 = ((value % 4) + 4) % 4; - }; -} - -#[macro_export] -macro_rules! equatable_if_let { - ($a:ident) => {{ if let 2 = $a {} }}; -} - -#[macro_export] -macro_rules! almost_complete_range { - () => { - let _ = 'a'..'z'; - let _ = 'A'..'Z'; - 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!() - } + let mut a = 1; + let mut b = 2; + a = b; + b = a; }; } diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_use_helper.rs b/src/tools/clippy/tests/ui/auxiliary/macro_use_helper.rs index ecb55d8cb..7ed8a28db 100644 --- a/src/tools/clippy/tests/ui/auxiliary/macro_use_helper.rs +++ b/src/tools/clippy/tests/ui/auxiliary/macro_use_helper.rs @@ -13,7 +13,7 @@ pub mod inner { // RE-EXPORT // this will stick in `inner` module - pub use macro_rules::foofoo; + pub use macro_rules::mut_mut; pub use macro_rules::try_err; pub mod nested { diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs deleted file mode 100644 index 8ea631f2b..000000000 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs +++ /dev/null @@ -1,32 +0,0 @@ -// compile-flags: --emit=link -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::{token_stream::IntoIter, Group, Span, TokenStream, TokenTree}; - -#[proc_macro] -pub fn with_span(input: TokenStream) -> TokenStream { - let mut iter = input.into_iter(); - let span = iter.next().unwrap().span(); - let mut res = TokenStream::new(); - write_with_span(span, iter, &mut res); - res -} - -fn write_with_span(s: Span, input: IntoIter, out: &mut TokenStream) { - for mut tt in input { - if let TokenTree::Group(g) = tt { - let mut stream = TokenStream::new(); - write_with_span(s, g.stream().into_iter(), &mut stream); - let mut group = Group::new(g.delimiter(), stream); - group.set_span(s); - out.extend([TokenTree::Group(group)]); - } else { - tt.set_span(s); - out.extend([tt]); - } - } -} diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs new file mode 100644 index 000000000..3d5beab1e --- /dev/null +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs @@ -0,0 +1,474 @@ +// compile-flags: --emit=link +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(let_chains)] +#![feature(proc_macro_span)] +#![allow(dead_code)] + +extern crate proc_macro; + +use core::mem; +use proc_macro::{ + token_stream::IntoIter, + Delimiter::{self, Brace, Parenthesis}, + Group, Ident, Literal, Punct, + Spacing::{self, Alone, Joint}, + Span, TokenStream, TokenTree as TT, +}; + +type Result = core::result::Result; + +/// Make a `compile_error!` pointing to the given span. +fn make_error(msg: &str, span: Span) -> TokenStream { + TokenStream::from_iter([ + TT::Ident(Ident::new("compile_error", span)), + TT::Punct(punct_with_span('!', Alone, span)), + TT::Group({ + let mut msg = Literal::string(msg); + msg.set_span(span); + group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span) + }), + ]) +} + +fn expect_tt(tt: Option, f: impl FnOnce(TT) -> Option, expected: &str, span: Span) -> Result { + match tt { + None => Err(make_error( + &format!("unexpected end of input, expected {expected}"), + span, + )), + Some(tt) => { + let span = tt.span(); + match f(tt) { + Some(x) => Ok(x), + None => Err(make_error(&format!("unexpected token, expected {expected}"), span)), + } + }, + } +} + +fn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct { + let mut p = Punct::new(c, spacing); + p.set_span(span); + p +} + +fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group { + let mut g = Group::new(delimiter, stream); + g.set_span(span); + g +} + +/// Token used to escape the following token from the macro's span rules. +const ESCAPE_CHAR: char = '$'; + +/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their +/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn with_span(input: TokenStream) -> TokenStream { + let mut iter = input.into_iter(); + let span = iter.next().unwrap().span(); + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(span, iter, &mut res) { + e + } else { + res + } +} + +/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be +/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn external(input: TokenStream) -> TokenStream { + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) { + e + } else { + res + } +} + +/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped +/// either by `#ident` or `#(tokens)`. +fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> { + while let Some(tt) = input.next() { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => { + expect_tt( + input.next(), + |tt| match tt { + tt @ (TT::Ident(_) | TT::Literal(_)) => { + out.extend([tt]); + Some(()) + }, + TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => { + p.set_span(s); + out.extend([TT::Punct(p)]); + Some(()) + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]); + Some(()) + }, + _ => None, + }, + "an ident, a literal, or parenthesized tokens", + p.span(), + )?; + }, + TT::Group(g) => { + let mut stream = TokenStream::new(); + write_with_span(s, g.stream().into_iter(), &mut stream)?; + out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]); + }, + mut tt => { + tt.set_span(s); + out.extend([tt]); + }, + } + } + Ok(()) +} + +/// Within the item this attribute is attached to, an `inline!` macro is available which expands the +/// contained tokens as though they came from a macro expansion. +/// +/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument +/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or +/// `$"literal"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will +/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another +/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will +/// expand the remaining tokens as a single argument. +/// +/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro +/// calls. However, any arguments will be passed as though they came from the outermost context. +#[proc_macro_attribute] +pub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream { + let mut args = args.into_iter(); + let mac_name = match args.next() { + Some(TT::Ident(name)) => Some(name), + Some(tt) => { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }, + None => None, + }; + if let Some(tt) = args.next() { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }; + + let mac_name = if let Some(mac_name) = mac_name { + Ident::new(&format!("__inline_mac_{mac_name}"), Span::call_site()) + } else { + let mut input = match LookaheadIter::new(input.clone().into_iter()) { + Some(x) => x, + None => return input, + }; + loop { + match input.next() { + None => break Ident::new("__inline_mac", Span::call_site()), + Some(TT::Ident(kind)) => match &*kind.to_string() { + "impl" => break Ident::new("__inline_mac_impl", Span::call_site()), + kind @ ("struct" | "enum" | "union" | "fn" | "mod" | "trait" | "type" | "const" | "static") => { + if let TT::Ident(name) = &input.tt { + break Ident::new(&format!("__inline_mac_{kind}_{name}"), Span::call_site()); + } else { + break Ident::new(&format!("__inline_mac_{kind}"), Span::call_site()); + } + }, + _ => {}, + }, + _ => {}, + } + } + }; + + let mut expander = Expander::default(); + let mut mac = MacWriter::new(mac_name); + if let Err(e) = expander.expand(input.into_iter(), &mut mac) { + return e; + } + let mut out = TokenStream::new(); + mac.finish(&mut out); + out.extend(expander.expn); + out +} + +/// Wraps a `TokenStream` iterator with a single token lookahead. +struct LookaheadIter { + tt: TT, + iter: IntoIter, +} +impl LookaheadIter { + fn new(mut iter: IntoIter) -> Option { + iter.next().map(|tt| Self { tt, iter }) + } + + /// Get's the lookahead token, replacing it with the next token in the stream. + /// Note: If there isn't a next token, this will not return the lookahead token. + fn next(&mut self) -> Option { + self.iter.next().map(|tt| mem::replace(&mut self.tt, tt)) + } +} + +/// Builds the macro used to implement all the `inline!` macro calls. +struct MacWriter { + name: Ident, + macros: TokenStream, + next_idx: usize, +} +impl MacWriter { + fn new(name: Ident) -> Self { + Self { + name, + macros: TokenStream::new(), + next_idx: 0, + } + } + + /// Inserts a new `inline!` call. + fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> { + let idx = self.next_idx; + self.next_idx += 1; + + let mut inner = Expander::for_arm(idx); + inner.expand(body.stream().into_iter(), self)?; + let new_arm = inner.arm.unwrap(); + + self.macros.extend([ + TT::Group(Group::new(Parenthesis, new_arm.args_def)), + TT::Punct(Punct::new('=', Joint)), + TT::Punct(Punct::new('>', Alone)), + TT::Group(Group::new(Parenthesis, inner.expn)), + TT::Punct(Punct::new(';', Alone)), + ]); + + expander.expn.extend([ + TT::Ident({ + let mut name = self.name.clone(); + name.set_span(name_span); + name + }), + TT::Punct(punct_with_span('!', Alone, bang_span)), + ]); + let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]); + if let Some(arm) = expander.arm.as_mut() { + if !new_arm.args.is_empty() { + arm.add_sub_args(new_arm.args, &mut call_body); + } + } else { + call_body.extend(new_arm.args); + } + let mut g = Group::new(body.delimiter(), call_body); + g.set_span(body.span()); + expander.expn.extend([TT::Group(g)]); + Ok(()) + } + + /// Creates the macro definition. + fn finish(self, out: &mut TokenStream) { + if self.next_idx != 0 { + out.extend([ + TT::Ident(Ident::new("macro_rules", Span::call_site())), + TT::Punct(Punct::new('!', Alone)), + TT::Ident(self.name), + TT::Group(Group::new(Brace, self.macros)), + ]) + } + } +} + +struct MacroArm { + args_def: TokenStream, + args: Vec, +} +impl MacroArm { + fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new(kind, Span::call_site())), + ]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(kind), + ]), + ))]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new("tt", Span::call_site())), + ]), + )), + TT::Punct(Punct::new('*', Alone)), + ]), + ))]); + name.set_span(arg_span); + out.extend([ + TT::Punct(punct_with_span('$', Alone, dollar_span)), + TT::Group(group_with_span( + Parenthesis, + TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]), + dollar_span, + )), + TT::Punct(punct_with_span('*', Alone, dollar_span)), + ]); + } + + fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]), + TT::Punct(p) if p.as_char() == '\'' && p.spacing() == Joint => { + let lt_name = expect_tt( + input.next(), + |tt| match tt { + TT::Ident(x) => Some(x), + _ => None, + }, + "lifetime name", + p.span(), + )?; + let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span()); + self.add_single_arg_def("lifetime", dollar_span, arg_span, out); + self.args.extend([TT::Punct(p), TT::Ident(lt_name)]); + }, + TT::Ident(x) => { + self.add_single_arg_def("ident", dollar_span, x.span(), out); + self.args.push(TT::Ident(x)); + }, + TT::Literal(x) => { + self.add_single_arg_def("literal", dollar_span, x.span(), out); + self.args.push(TT::Literal(x)); + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + let mut inner = g.stream().into_iter(); + if let Some(TT::Punct(p)) = inner.next() + && p.as_char() == '@' + { + let kind = expect_tt( + inner.next(), + |tt| match tt { + TT::Ident(kind) => Some(kind), + _ => None, + }, + "a macro fragment specifier", + p.span(), + )?; + self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out); + self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) + } else { + self.add_multi_arg_def(dollar_span, g.span(), out); + self.args.push(TT::Group(g)); + } + }, + tt => return Err(make_error("unsupported escape", tt.span())), + }; + Ok(()) + } + + fn add_sub_args(&mut self, args: Vec, out: &mut TokenStream) { + self.add_multi_arg_def(Span::call_site(), Span::call_site(), out); + self.args + .extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]); + } +} + +#[derive(Default)] +struct Expander { + arm: Option, + expn: TokenStream, +} +impl Expander { + fn for_arm(idx: usize) -> Self { + Self { + arm: Some(MacroArm { + args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]), + args: Vec::new(), + }), + expn: TokenStream::new(), + } + } + + fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> { + match tt { + TT::Group(g) => { + let outer = mem::take(&mut self.expn); + self.expand(g.stream().into_iter(), mac)?; + let inner = mem::replace(&mut self.expn, outer); + self.expn + .extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]); + }, + tt => self.expn.extend([tt]), + } + Ok(()) + } + + fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> { + let Some(mut input) = LookaheadIter::new(input) else { + return Ok(()); + }; + while let Some(tt) = input.next() { + if let TT::Punct(p) = &tt + && p.as_char() == ESCAPE_CHAR + && let Some(arm) = self.arm.as_mut() + { + arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?; + if input.next().is_none() { + return Ok(()); + } + } else if let TT::Punct(p) = &input.tt + && p.as_char() == '!' + && let TT::Ident(name) = &tt + && name.to_string() == "inline" + { + let g = expect_tt( + input.iter.next(), + |tt| match tt { + TT::Group(g) => Some(g), + _ => None, + }, + "macro arguments", + p.span(), + )?; + mac.insert(name.span(), p.span(), g, self)?; + if input.next().is_none() { + return Ok(()); + } + } else { + self.write_tt(tt, mac)?; + } + } + self.write_tt(input.tt, mac) + } +} diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs index f13733af3..b03c21262 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs @@ -1,5 +1,5 @@ // this file solely exists to test constants defined in foreign crates. -// As the most common case is the `http` crate, it replicates `http::HeadewrName`'s structure. +// As the most common case is the `http` crate, it replicates `http::HeaderName`'s structure. #![allow(clippy::declare_interior_mutable_const)] #![allow(unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/boxed_local.rs b/src/tools/clippy/tests/ui/boxed_local.rs index 4639f00a8..79b6d33fc 100644 --- a/src/tools/clippy/tests/ui/boxed_local.rs +++ b/src/tools/clippy/tests/ui/boxed_local.rs @@ -1,4 +1,3 @@ -#![feature(box_syntax)] #![feature(lint_reasons)] #![allow( clippy::borrowed_box, @@ -34,7 +33,7 @@ fn ok_box_trait(boxed_trait: &Box) { } fn warn_call() { - let x = box A; + let x = Box::new(A); x.foo(); } @@ -43,41 +42,41 @@ fn warn_arg(x: Box) { } fn nowarn_closure_arg() { - let x = Some(box A); + let x = Some(Box::new(A)); x.map_or((), |x| take_ref(&x)); } fn warn_rename_call() { - let x = box A; + let x = Box::new(A); let y = x; y.foo(); // via autoderef } fn warn_notuse() { - let bz = box A; + let bz = Box::new(A); } fn warn_pass() { - let bz = box A; + let bz = Box::new(A); take_ref(&bz); // via deref coercion } fn nowarn_return() -> Box { - box A // moved out, "escapes" + Box::new(A) // moved out, "escapes" } fn nowarn_move() { - let bx = box A; + let bx = Box::new(A); drop(bx) // moved in, "escapes" } fn nowarn_call() { - let bx = box A; + let bx = Box::new(A); bx.clone(); // method only available to Box, not via autoderef } fn nowarn_pass() { - let bx = box A; + let bx = Box::new(A); take_box(&bx); // fn needs &Box } @@ -86,30 +85,20 @@ fn take_ref(x: &A) {} fn nowarn_ref_take() { // false positive, should actually warn - let x = box A; + let x = Box::new(A); let y = &x; take_box(y); } fn nowarn_match() { - let x = box A; // moved into a match + let x = Box::new(A); // moved into a match match x { y => drop(y), } } fn warn_match() { - let x = box A; - match &x { - // not moved - y => (), - } -} - -fn nowarn_large_array() { - // should not warn, is large array - // and should not be on stack - let x = box [1; 10000]; + let x = Box::new(A); match &x { // not moved y => (), diff --git a/src/tools/clippy/tests/ui/boxed_local.stderr b/src/tools/clippy/tests/ui/boxed_local.stderr index 9036529f3..10d78fbc0 100644 --- a/src/tools/clippy/tests/ui/boxed_local.stderr +++ b/src/tools/clippy/tests/ui/boxed_local.stderr @@ -1,5 +1,5 @@ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:41:13 + --> $DIR/boxed_local.rs:40:13 | LL | fn warn_arg(x: Box) { | ^ @@ -7,19 +7,19 @@ LL | fn warn_arg(x: Box) { = note: `-D clippy::boxed-local` implied by `-D warnings` error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:132:12 + --> $DIR/boxed_local.rs:121:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:196:44 + --> $DIR/boxed_local.rs:185:44 | LL | fn default_impl_x(self: Box, x: Box) -> u32 { | ^ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:203:16 + --> $DIR/boxed_local.rs:192:16 | LL | fn foo(x: Box) {} | ^ diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs index 8b2673c2a..a86b85706 100644 --- a/src/tools/clippy/tests/ui/cast.rs +++ b/src/tools/clippy/tests/ui/cast.rs @@ -29,6 +29,12 @@ fn main() { 1f64 as isize; 1f64 as usize; 1f32 as u32 as u16; + { + let _x: i8 = 1i32 as _; + 1f32 as i32; + 1f64 as i32; + 1f32 as u8; + } // 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 451078de2..65ecf1aa3 100644 --- a/src/tools/clippy/tests/ui/cast.stderr +++ b/src/tools/clippy/tests/ui/cast.stderr @@ -44,10 +44,6 @@ 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 @@ -56,10 +52,6 @@ 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 @@ -76,10 +68,6 @@ 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 @@ -112,10 +100,6 @@ 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 @@ -124,10 +108,6 @@ 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 @@ -154,10 +134,6 @@ 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 @@ -165,8 +141,50 @@ error: casting `f32` to `u32` may lose the sign of the value LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ +error: casting `i32` to `i8` may truncate the value + --> $DIR/cast.rs:33:22 + | +LL | let _x: i8 = 1i32 as _; + | ^^^^^^^^^ + | + = 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 _x: i8 = 1i32.try_into(); + | ~~~~~~~~~~~~~~~ + +error: casting `f32` to `i32` may truncate the value + --> $DIR/cast.rs:34:9 + | +LL | 1f32 as i32; + | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + +error: casting `f64` to `i32` may truncate the value + --> $DIR/cast.rs:35:9 + | +LL | 1f64 as i32; + | ^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + +error: casting `f32` to `u8` may truncate the value + --> $DIR/cast.rs:36:9 + | +LL | 1f32 as u8; + | ^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + +error: casting `f32` to `u8` may lose the sign of the value + --> $DIR/cast.rs:36:9 + | +LL | 1f32 as u8; + | ^^^^^^^^^^ + error: casting `u8` to `i8` may wrap around the value - --> $DIR/cast.rs:33:5 + --> $DIR/cast.rs:39:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -174,43 +192,43 @@ 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:34:5 + --> $DIR/cast.rs:40:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> $DIR/cast.rs:35:5 + --> $DIR/cast.rs:41:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> $DIR/cast.rs:36:5 + --> $DIR/cast.rs:42:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> $DIR/cast.rs:37:5 + --> $DIR/cast.rs:43:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> $DIR/cast.rs:40:5 + --> $DIR/cast.rs:46:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> $DIR/cast.rs:42:5 + --> $DIR/cast.rs:48:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> $DIR/cast.rs:109:5 + --> $DIR/cast.rs:115:5 | LL | (-99999999999i64).min(1) as i8; // should be linted because signed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +240,7 @@ LL | i8::try_from((-99999999999i64).min(1)); // should be linted because sig | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> $DIR/cast.rs:121:5 + --> $DIR/cast.rs:127:5 | LL | 999999u64.clamp(0, 256) as u8; // should still be linted | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +252,7 @@ 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:142:21 + --> $DIR/cast.rs:148:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -246,7 +264,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> $DIR/cast.rs:143:21 + --> $DIR/cast.rs:149:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -254,7 +272,7 @@ 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:179:21 + --> $DIR/cast.rs:185:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -266,13 +284,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> $DIR/cast.rs:180:21 + --> $DIR/cast.rs:186:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> $DIR/cast.rs:194:21 + --> $DIR/cast.rs:200:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -284,7 +302,7 @@ 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:209:21 + --> $DIR/cast.rs:215:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -296,7 +314,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> $DIR/cast.rs:250:21 + --> $DIR/cast.rs:256:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -308,7 +326,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:258:13 + --> $DIR/cast.rs:264:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -316,11 +334,11 @@ 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)); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL | let c = u8::try_from(q >> 16); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:261:13 + --> $DIR/cast.rs:267:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -328,8 +346,8 @@ 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)); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL | let c = u8::try_from(q / 1000); + | ~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 36 previous errors +error: aborting due to 41 previous errors diff --git a/src/tools/clippy/tests/ui/clear_with_drain.fixed b/src/tools/clippy/tests/ui/clear_with_drain.fixed new file mode 100644 index 000000000..2d9545eee --- /dev/null +++ b/src/tools/clippy/tests/ui/clear_with_drain.fixed @@ -0,0 +1,358 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::clear_with_drain)] + +use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; + +fn vec_range() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(0..v.len()); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + let n = v.drain(0..v.len()).count(); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let iter = v.drain(usize::MIN..v.len()); + let n = iter.count(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); +} + +fn vec_range_from() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(0..); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let mut iter = v.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + let next = v.drain(usize::MIN..).next(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); +} + +fn vec_range_full() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(..); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + for x in v.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); +} + +fn vec_range_to() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(..v.len()); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let iter = v.drain(..v.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut v = vec![1, 2, 3]; + v.clear(); +} + +fn vec_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut v = vec![1, 2, 3]; + v.drain(1..); + let mut v = vec![1, 2, 3]; + v.drain(1..).max(); + + let mut v = vec![1, 2, 3]; + v.drain(..v.len() - 1); + let mut v = vec![1, 2, 3]; + v.drain(..v.len() - 1).min(); + + let mut v = vec![1, 2, 3]; + v.drain(1..v.len() - 1); + let mut v = vec![1, 2, 3]; + let w: Vec = v.drain(1..v.len() - 1).collect(); +} + +fn vec_deque_range() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(0..deque.len()); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + let n = deque.drain(0..deque.len()).count(); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(usize::MIN..deque.len()); + let n = iter.count(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); +} + +fn vec_deque_range_from() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(0..); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let mut iter = deque.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + let next = deque.drain(usize::MIN..).next(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); +} + +fn vec_deque_range_full() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + for x in deque.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); +} + +fn vec_deque_range_to() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..deque.len()); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..deque.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.clear(); +} + +fn vec_deque_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..); + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..).max(); + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..deque.len() - 1); + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..deque.len() - 1).min(); + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..deque.len() - 1); + let mut deque = VecDeque::from([1, 2, 3]); + let w: Vec = deque.drain(1..deque.len() - 1).collect(); +} + +fn string_range() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(0..s.len()); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + let n = s.drain(0..s.len()).count(); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let iter = s.drain(usize::MIN..s.len()); + let n = iter.count(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); +} + +fn string_range_from() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(0..); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let mut iter = s.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + let next = s.drain(usize::MIN..).next(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); +} + +fn string_range_full() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(..); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + for x in s.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); +} + +fn string_range_to() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(..s.len()); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let iter = s.drain(..s.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut s = String::from("Hello, world!"); + s.clear(); +} + +fn string_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut s = String::from("Hello, world!"); + s.drain(1..); + let mut s = String::from("Hello, world!"); + s.drain(1..).max(); + + let mut s = String::from("Hello, world!"); + s.drain(..s.len() - 1); + let mut s = String::from("Hello, world!"); + s.drain(..s.len() - 1).min(); + + let mut s = String::from("Hello, world!"); + s.drain(1..s.len() - 1); + let mut s = String::from("Hello, world!"); + let w: String = s.drain(1..s.len() - 1).collect(); +} + +fn hash_set() { + // Do not lint because iterator is assigned + let mut set = HashSet::from([1, 2, 3]); + let iter = set.drain(); + + // Do not lint because iterator is assigned and used + let mut set = HashSet::from([1, 2, 3]); + let mut iter = set.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut set = HashSet::from([1, 2, 3]); + let next = set.drain().next(); + + // Do lint + let mut set = HashSet::from([1, 2, 3]); + set.clear(); +} + +fn hash_map() { + // Do not lint because iterator is assigned + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let iter = map.drain(); + + // Do not lint because iterator is assigned and used + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let mut iter = map.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let next = map.drain().next(); + + // Do lint + let mut map = HashMap::from([(1, "a"), (2, "b")]); + map.clear(); +} + +fn binary_heap() { + // Do not lint because iterator is assigned + let mut heap = BinaryHeap::from([1, 2]); + let iter = heap.drain(); + + // Do not lint because iterator is assigned and used + let mut heap = BinaryHeap::from([1, 2]); + let mut iter = heap.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut heap = BinaryHeap::from([1, 2]); + let next = heap.drain().next(); + + // Do lint + let mut heap = BinaryHeap::from([1, 2]); + heap.clear(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/clear_with_drain.rs b/src/tools/clippy/tests/ui/clear_with_drain.rs new file mode 100644 index 000000000..4d60ee46e --- /dev/null +++ b/src/tools/clippy/tests/ui/clear_with_drain.rs @@ -0,0 +1,358 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::clear_with_drain)] + +use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; + +fn vec_range() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(0..v.len()); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + let n = v.drain(0..v.len()).count(); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let iter = v.drain(usize::MIN..v.len()); + let n = iter.count(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(0..v.len()); + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(usize::MIN..v.len()); +} + +fn vec_range_from() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(0..); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let mut iter = v.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + let next = v.drain(usize::MIN..).next(); + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(0..); + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(usize::MIN..); +} + +fn vec_range_full() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(..); + + // Do not lint because iterator is used + let mut v = vec![1, 2, 3]; + for x in v.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(..); +} + +fn vec_range_to() { + // Do not lint because iterator is assigned + let mut v = vec![1, 2, 3]; + let iter = v.drain(..v.len()); + + // Do not lint because iterator is assigned and used + let mut v = vec![1, 2, 3]; + let iter = v.drain(..v.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut v = vec![1, 2, 3]; + v.drain(..v.len()); +} + +fn vec_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut v = vec![1, 2, 3]; + v.drain(1..); + let mut v = vec![1, 2, 3]; + v.drain(1..).max(); + + let mut v = vec![1, 2, 3]; + v.drain(..v.len() - 1); + let mut v = vec![1, 2, 3]; + v.drain(..v.len() - 1).min(); + + let mut v = vec![1, 2, 3]; + v.drain(1..v.len() - 1); + let mut v = vec![1, 2, 3]; + let w: Vec = v.drain(1..v.len() - 1).collect(); +} + +fn vec_deque_range() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(0..deque.len()); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + let n = deque.drain(0..deque.len()).count(); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(usize::MIN..deque.len()); + let n = iter.count(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(0..deque.len()); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(usize::MIN..deque.len()); +} + +fn vec_deque_range_from() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(0..); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let mut iter = deque.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + let next = deque.drain(usize::MIN..).next(); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(0..); + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(usize::MIN..); +} + +fn vec_deque_range_full() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..); + + // Do not lint because iterator is used + let mut deque = VecDeque::from([1, 2, 3]); + for x in deque.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..); +} + +fn vec_deque_range_to() { + // Do not lint because iterator is assigned + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..deque.len()); + + // Do not lint because iterator is assigned and used + let mut deque = VecDeque::from([1, 2, 3]); + let iter = deque.drain(..deque.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..deque.len()); +} + +fn vec_deque_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..); + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..).max(); + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..deque.len() - 1); + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(..deque.len() - 1).min(); + + let mut deque = VecDeque::from([1, 2, 3]); + deque.drain(1..deque.len() - 1); + let mut deque = VecDeque::from([1, 2, 3]); + let w: Vec = deque.drain(1..deque.len() - 1).collect(); +} + +fn string_range() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(0..s.len()); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + let n = s.drain(0..s.len()).count(); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let iter = s.drain(usize::MIN..s.len()); + let n = iter.count(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(0..s.len()); + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(usize::MIN..s.len()); +} + +fn string_range_from() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(0..); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let mut iter = s.drain(0..); + let next = iter.next(); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + let next = s.drain(usize::MIN..).next(); + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(0..); + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(usize::MIN..); +} + +fn string_range_full() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(..); + + // Do not lint because iterator is used + let mut s = String::from("Hello, world!"); + for x in s.drain(..) { + let y = format!("x = {x}"); + } + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(..); +} + +fn string_range_to() { + // Do not lint because iterator is assigned + let mut s = String::from("Hello, world!"); + let iter = s.drain(..s.len()); + + // Do not lint because iterator is assigned and used + let mut s = String::from("Hello, world!"); + let iter = s.drain(..s.len()); + for x in iter { + let y = format!("x = {x}"); + } + + // Do lint + let mut s = String::from("Hello, world!"); + s.drain(..s.len()); +} + +fn string_partial_drains() { + // Do not lint any of these because the ranges are not full + + let mut s = String::from("Hello, world!"); + s.drain(1..); + let mut s = String::from("Hello, world!"); + s.drain(1..).max(); + + let mut s = String::from("Hello, world!"); + s.drain(..s.len() - 1); + let mut s = String::from("Hello, world!"); + s.drain(..s.len() - 1).min(); + + let mut s = String::from("Hello, world!"); + s.drain(1..s.len() - 1); + let mut s = String::from("Hello, world!"); + let w: String = s.drain(1..s.len() - 1).collect(); +} + +fn hash_set() { + // Do not lint because iterator is assigned + let mut set = HashSet::from([1, 2, 3]); + let iter = set.drain(); + + // Do not lint because iterator is assigned and used + let mut set = HashSet::from([1, 2, 3]); + let mut iter = set.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut set = HashSet::from([1, 2, 3]); + let next = set.drain().next(); + + // Do lint + let mut set = HashSet::from([1, 2, 3]); + set.drain(); +} + +fn hash_map() { + // Do not lint because iterator is assigned + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let iter = map.drain(); + + // Do not lint because iterator is assigned and used + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let mut iter = map.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut map = HashMap::from([(1, "a"), (2, "b")]); + let next = map.drain().next(); + + // Do lint + let mut map = HashMap::from([(1, "a"), (2, "b")]); + map.drain(); +} + +fn binary_heap() { + // Do not lint because iterator is assigned + let mut heap = BinaryHeap::from([1, 2]); + let iter = heap.drain(); + + // Do not lint because iterator is assigned and used + let mut heap = BinaryHeap::from([1, 2]); + let mut iter = heap.drain(); + let next = iter.next(); + + // Do not lint because iterator is used + let mut heap = BinaryHeap::from([1, 2]); + let next = heap.drain().next(); + + // Do lint + let mut heap = BinaryHeap::from([1, 2]); + heap.drain(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/clear_with_drain.stderr b/src/tools/clippy/tests/ui/clear_with_drain.stderr new file mode 100644 index 000000000..20158da11 --- /dev/null +++ b/src/tools/clippy/tests/ui/clear_with_drain.stderr @@ -0,0 +1,130 @@ +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:23:7 + | +LL | v.drain(0..v.len()); + | ^^^^^^^^^^^^^^^^^ help: try: `clear()` + | + = note: `-D clippy::clear-with-drain` implied by `-D warnings` + +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:27:7 + | +LL | v.drain(usize::MIN..v.len()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:46:7 + | +LL | v.drain(0..); + | ^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:50:7 + | +LL | v.drain(usize::MIN..); + | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:66:7 + | +LL | v.drain(..); + | ^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `Vec` + --> $DIR/clear_with_drain.rs:83:7 + | +LL | v.drain(..v.len()); + | ^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:121:11 + | +LL | deque.drain(0..deque.len()); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:125:11 + | +LL | deque.drain(usize::MIN..deque.len()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:144:11 + | +LL | deque.drain(0..); + | ^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:148:11 + | +LL | deque.drain(usize::MIN..); + | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:164:11 + | +LL | deque.drain(..); + | ^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `VecDeque` + --> $DIR/clear_with_drain.rs:181:11 + | +LL | deque.drain(..deque.len()); + | ^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:219:7 + | +LL | s.drain(0..s.len()); + | ^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:223:7 + | +LL | s.drain(usize::MIN..s.len()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:242:7 + | +LL | s.drain(0..); + | ^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:246:7 + | +LL | s.drain(usize::MIN..); + | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:262:7 + | +LL | s.drain(..); + | ^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `String` + --> $DIR/clear_with_drain.rs:279:7 + | +LL | s.drain(..s.len()); + | ^^^^^^^^^^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `HashSet` + --> $DIR/clear_with_drain.rs:317:9 + | +LL | set.drain(); + | ^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `HashMap` + --> $DIR/clear_with_drain.rs:336:9 + | +LL | map.drain(); + | ^^^^^^^ help: try: `clear()` + +error: `drain` used to clear a `BinaryHeap` + --> $DIR/clear_with_drain.rs:355:10 + | +LL | heap.drain(); + | ^^^^^^^ help: try: `clear()` + +error: aborting due to 21 previous errors + diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.rs b/src/tools/clippy/tests/ui/collection_is_never_read.rs new file mode 100644 index 000000000..01259a983 --- /dev/null +++ b/src/tools/clippy/tests/ui/collection_is_never_read.rs @@ -0,0 +1,190 @@ +#![allow(unused)] +#![warn(clippy::collection_is_never_read)] + +use std::collections::{HashMap, HashSet}; + +fn main() {} + +fn not_a_collection() { + // TODO: Expand `collection_is_never_read` beyond collections? + let mut x = 10; // Ok + x += 1; +} + +fn no_access_at_all() { + // Other lints should catch this. + let x = vec![1, 2, 3]; // Ok +} + +fn write_without_read() { + // The main use case for `collection_is_never_read`. + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); +} + +fn read_without_write() { + let mut x = vec![1, 2, 3]; // Ok + let _ = x.len(); +} + +fn write_and_read() { + let mut x = vec![1, 2, 3]; // Ok + x.push(4); + let _ = x.len(); +} + +fn write_after_read() { + // TODO: Warn here, but this requires more extensive data flow analysis. + let mut x = vec![1, 2, 3]; // Ok + let _ = x.len(); + x.push(4); // Pointless +} + +fn write_before_reassign() { + // TODO: Warn here, but this requires more extensive data flow analysis. + let mut x = HashMap::new(); // Ok + x.insert(1, 2); // Pointless + x = HashMap::new(); + let _ = x.len(); +} + +fn read_in_closure() { + let mut x = HashMap::new(); // Ok + x.insert(1, 2); + let _ = || { + let _ = x.len(); + }; +} + +fn write_in_closure() { + let mut x = vec![1, 2, 3]; // WARNING + let _ = || { + x.push(4); + }; +} + +fn read_in_format() { + let mut x = HashMap::new(); // Ok + x.insert(1, 2); + format!("{x:?}"); +} + +fn shadowing_1() { + let x = HashMap::::new(); // Ok + let _ = x.len(); + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); +} + +fn shadowing_2() { + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); + let x = HashMap::::new(); // Ok + let _ = x.len(); +} + +#[allow(clippy::let_unit_value)] +fn fake_read_1() { + let mut x = vec![1, 2, 3]; // WARNING + x.reverse(); + let _: () = x.clear(); +} + +fn fake_read_2() { + let mut x = vec![1, 2, 3]; // WARNING + x.reverse(); + println!("{:?}", x.push(5)); +} + +fn assignment() { + let mut x = vec![1, 2, 3]; // WARNING + let y = vec![4, 5, 6]; // Ok + x = y; +} + +#[allow(clippy::self_assignment)] +fn self_assignment() { + let mut x = vec![1, 2, 3]; // WARNING + x = x; +} + +fn method_argument_but_not_target() { + struct MyStruct; + impl MyStruct { + fn my_method(&self, _argument: &[usize]) {} + } + let my_struct = MyStruct; + + let mut x = vec![1, 2, 3]; // Ok + x.reverse(); + my_struct.my_method(&x); +} + +fn insert_is_not_a_read() { + let mut x = HashSet::new(); // WARNING + x.insert(5); +} + +fn insert_is_a_read() { + let mut x = HashSet::new(); // Ok + if x.insert(5) { + println!("5 was inserted"); + } +} + +fn not_read_if_return_value_not_used() { + // `is_empty` does not modify the set, so it's a query. But since the return value is not used, the + // lint does not consider it a read here. + let x = vec![1, 2, 3]; // WARNING + x.is_empty(); +} + +fn extension_traits() { + trait VecExt { + fn method_with_side_effect(&self); + fn method_without_side_effect(&self); + } + + impl VecExt for Vec { + fn method_with_side_effect(&self) { + println!("my length: {}", self.len()); + } + fn method_without_side_effect(&self) {} + } + + let x = vec![1, 2, 3]; // Ok + x.method_with_side_effect(); + + let y = vec![1, 2, 3]; // Ok (false negative) + y.method_without_side_effect(); +} + +fn function_argument() { + #[allow(clippy::ptr_arg)] + fn foo(v: &Vec) -> usize { + v.len() + } + + let x = vec![1, 2, 3]; // Ok + foo(&x); +} + +fn string() { + // Do lint (write without read) + let mut s = String::new(); + s.push_str("Hello, World!"); + + // Do not lint (read without write) + let mut s = String::from("Hello, World!"); + let _ = s.len(); + + // Do not lint (write and read) + let mut s = String::from("Hello, World!"); + s.push_str("foo, bar"); + let _ = s.len(); + + // Do lint the first line, but not the second + let mut s = String::from("Hello, World!"); + let t = String::from("foo, bar"); + s = t; +} diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.stderr b/src/tools/clippy/tests/ui/collection_is_never_read.stderr new file mode 100644 index 000000000..cf51a5368 --- /dev/null +++ b/src/tools/clippy/tests/ui/collection_is_never_read.stderr @@ -0,0 +1,76 @@ +error: collection is never read + --> $DIR/collection_is_never_read.rs:21:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::collection-is-never-read` implied by `-D warnings` + +error: collection is never read + --> $DIR/collection_is_never_read.rs:60:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:75:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:80:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:88:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:94:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:100:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:107:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:124:5 + | +LL | let mut x = HashSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:138:5 + | +LL | let x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:174:5 + | +LL | let mut s = String::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:187:5 + | +LL | let mut s = String::from("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.rs b/src/tools/clippy/tests/ui/crashes/ice-10148.rs new file mode 100644 index 000000000..1ab3570c9 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-10148.rs @@ -0,0 +1,9 @@ +// aux-build:../../auxiliary/proc_macros.rs + +extern crate proc_macros; + +use proc_macros::with_span; + +fn main() { + println!(with_span!(""something "")); +} diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.stderr b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr new file mode 100644 index 000000000..f23e4433f --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr @@ -0,0 +1,12 @@ +error: empty string literal in `println!` + --> $DIR/ice-10148.rs:8:5 + | +LL | println!(with_span!(""something "")); + | ^^^^^^^^^^^^^^^^^^^^-----------^^^^^ + | | + | help: remove the empty string + | + = note: `-D clippy::println-empty-string` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/crashes/ice-6179.rs b/src/tools/clippy/tests/ui/crashes/ice-6179.rs index 4fe92d356..ce1895851 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6179.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-6179.rs @@ -2,7 +2,7 @@ //! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details. #![warn(clippy::use_self)] -#![allow(dead_code)] +#![allow(dead_code, clippy::let_with_type_underscore)] struct Foo; diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index efdd56dd4..4787282f5 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -6,11 +6,11 @@ LL | _n: PhantomData, | help: consider importing one of these items | -LL | use core::marker::PhantomData; +LL + use core::marker::PhantomData; | -LL | use serde::__private::PhantomData; +LL + use serde::__private::PhantomData; | -LL | use std::marker::PhantomData; +LL + use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr index 22d82a30c..263c27d3d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr @@ -6,6 +6,8 @@ LL | FOO_REF_REF => {}, | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `-D indirect-structural-match` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed index a370ccc76..42c15d6a7 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( @@ -9,11 +9,12 @@ clippy::unnecessary_operation, clippy::branches_sharing_code, clippy::match_single_binding, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -166,20 +167,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22.0_f64; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22.0_f64;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22.;); } } diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs index 2476fe951..7da7ea254 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( @@ -9,11 +9,12 @@ clippy::unnecessary_operation, clippy::branches_sharing_code, clippy::match_single_binding, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -166,20 +167,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22.; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22.;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22.;); } } diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr index 5df2f6423..b949cd1d5 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:21:17 + --> $DIR/default_numeric_fallback_f64.rs:22:17 | LL | let x = 0.12; | ^^^^ help: consider adding suffix: `0.12_f64` @@ -7,147 +7,144 @@ LL | let x = 0.12; = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:18 + --> $DIR/default_numeric_fallback_f64.rs:23:18 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:22 + --> $DIR/default_numeric_fallback_f64.rs:23:22 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:26 + --> $DIR/default_numeric_fallback_f64.rs:23:26 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:28 + --> $DIR/default_numeric_fallback_f64.rs:24:28 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:32 + --> $DIR/default_numeric_fallback_f64.rs:24:32 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:46 + --> $DIR/default_numeric_fallback_f64.rs:24:46 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:50 + --> $DIR/default_numeric_fallback_f64.rs:24:50 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `4.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:24:23 + --> $DIR/default_numeric_fallback_f64.rs:25:23 | LL | let x = match 1. { | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:25:18 + --> $DIR/default_numeric_fallback_f64.rs:26:18 | LL | _ => 1., | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:44:21 + --> $DIR/default_numeric_fallback_f64.rs:45:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:52:21 + --> $DIR/default_numeric_fallback_f64.rs:53:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:58:21 + --> $DIR/default_numeric_fallback_f64.rs:59:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:66:21 + --> $DIR/default_numeric_fallback_f64.rs:67:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:78:9 + --> $DIR/default_numeric_fallback_f64.rs:79:9 | LL | 1. | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:84:27 + --> $DIR/default_numeric_fallback_f64.rs:85:27 | LL | let f = || -> _ { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:88:29 + --> $DIR/default_numeric_fallback_f64.rs:89:29 | LL | let f = || -> f64 { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:102:21 + --> $DIR/default_numeric_fallback_f64.rs:103:21 | LL | generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:105:32 + --> $DIR/default_numeric_fallback_f64.rs:106:32 | LL | let x: _ = generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:123:28 + --> $DIR/default_numeric_fallback_f64.rs:124:28 | LL | GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:126:36 + --> $DIR/default_numeric_fallback_f64.rs:127:36 | LL | let _ = GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:144:24 + --> $DIR/default_numeric_fallback_f64.rs:145:24 | LL | GenericEnum::X(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:164:23 + --> $DIR/default_numeric_fallback_f64.rs:165:23 | LL | s.generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:171:21 + --> $DIR/default_numeric_fallback_f64.rs:175:25 | -LL | let x = 22.; - | ^^^ help: consider adding suffix: `22.0_f64` -... -LL | internal_macro!(); - | ----------------- in this macro invocation +LL | inline!(let x = 22.;); + | ^^^ help: consider adding suffix: `22.0_f64` | - = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed index 3f4994f04..b7485b73d 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] @@ -9,11 +9,12 @@ clippy::no_effect, clippy::unnecessary_operation, clippy::branches_sharing_code, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -167,20 +168,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22_i32; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22_i32;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22;); } } diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs index 2df0e0978..7307d3135 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] @@ -9,11 +9,12 @@ clippy::no_effect, clippy::unnecessary_operation, clippy::branches_sharing_code, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -167,20 +168,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22;); } } diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr index 6f219c3fc..48cd28102 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:21:17 + --> $DIR/default_numeric_fallback_i32.rs:22:17 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32` @@ -7,159 +7,156 @@ LL | let x = 22; = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:18 + --> $DIR/default_numeric_fallback_i32.rs:23:18 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:21 + --> $DIR/default_numeric_fallback_i32.rs:23:21 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:24 + --> $DIR/default_numeric_fallback_i32.rs:23:24 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:28 + --> $DIR/default_numeric_fallback_i32.rs:24:28 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:31 + --> $DIR/default_numeric_fallback_i32.rs:24:31 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:44 + --> $DIR/default_numeric_fallback_i32.rs:24:44 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:47 + --> $DIR/default_numeric_fallback_i32.rs:24:47 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `4_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:24:23 + --> $DIR/default_numeric_fallback_i32.rs:25:23 | LL | let x = match 1 { | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:25:13 + --> $DIR/default_numeric_fallback_i32.rs:26:13 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:25:18 + --> $DIR/default_numeric_fallback_i32.rs:26:18 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:26:18 + --> $DIR/default_numeric_fallback_i32.rs:27:18 | LL | _ => 2, | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:45:21 + --> $DIR/default_numeric_fallback_i32.rs:46:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:53:21 + --> $DIR/default_numeric_fallback_i32.rs:54:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:59:21 + --> $DIR/default_numeric_fallback_i32.rs:60:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:67:21 + --> $DIR/default_numeric_fallback_i32.rs:68:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:79:9 + --> $DIR/default_numeric_fallback_i32.rs:80:9 | LL | 1 | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:85:27 + --> $DIR/default_numeric_fallback_i32.rs:86:27 | LL | let f = || -> _ { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:89:29 + --> $DIR/default_numeric_fallback_i32.rs:90:29 | LL | let f = || -> i32 { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:103:21 + --> $DIR/default_numeric_fallback_i32.rs:104:21 | LL | generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:106:32 + --> $DIR/default_numeric_fallback_i32.rs:107:32 | LL | let x: _ = generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:124:28 + --> $DIR/default_numeric_fallback_i32.rs:125:28 | LL | GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:127:36 + --> $DIR/default_numeric_fallback_i32.rs:128:36 | LL | let _ = GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:145:24 + --> $DIR/default_numeric_fallback_i32.rs:146:24 | LL | GenericEnum::X(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:165:23 + --> $DIR/default_numeric_fallback_i32.rs:166:23 | LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:172:21 + --> $DIR/default_numeric_fallback_i32.rs:176:25 | -LL | let x = 22; - | ^^ help: consider adding suffix: `22_i32` -... -LL | internal_macro!(); - | ----------------- in this macro invocation +LL | inline!(let x = 22;); + | ^^ help: consider adding suffix: `22_i32` | - = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 26 previous errors diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed index 5640599d4..7842ef3ec 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.fixed +++ b/src/tools/clippy/tests/ui/default_trait_access.fixed @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::default; use std::default::Default as D2; use std::string; diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs index 11d4bc5c5..cbb3e59c9 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.rs +++ b/src/tools/clippy/tests/ui/default_trait_access.rs @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::default; use std::default::Default as D2; use std::string; diff --git a/src/tools/clippy/tests/ui/deref_addrof.fixed b/src/tools/clippy/tests/ui/deref_addrof.fixed index 2f489deb1..ca5c03304 100644 --- a/src/tools/clippy/tests/ui/deref_addrof.fixed +++ b/src/tools/clippy/tests/ui/deref_addrof.fixed @@ -1,7 +1,12 @@ // run-rustfix +// aux-build:proc_macros.rs + #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] +extern crate proc_macros; +use proc_macros::inline_macros; + fn get_number() -> usize { 10 } @@ -41,28 +46,15 @@ fn main() { let _ = unsafe { *core::ptr::addr_of!(a) }; } -#[rustfmt::skip] -macro_rules! m { - ($visitor: expr) => { - $visitor - }; -} - -#[rustfmt::skip] -macro_rules! m_mut { - ($visitor: expr) => { - $visitor - }; -} - #[derive(Copy, Clone)] pub struct S; +#[inline_macros] impl S { pub fn f(&self) -> &Self { - m!(self) + inline!($(@expr self)) } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { - m_mut!(self) + inline!($(@expr self)) } } diff --git a/src/tools/clippy/tests/ui/deref_addrof.rs b/src/tools/clippy/tests/ui/deref_addrof.rs index 49f360b9a..3db5fafe9 100644 --- a/src/tools/clippy/tests/ui/deref_addrof.rs +++ b/src/tools/clippy/tests/ui/deref_addrof.rs @@ -1,7 +1,12 @@ // run-rustfix +// aux-build:proc_macros.rs + #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] +extern crate proc_macros; +use proc_macros::inline_macros; + fn get_number() -> usize { 10 } @@ -41,28 +46,15 @@ fn main() { let _ = unsafe { *core::ptr::addr_of!(a) }; } -#[rustfmt::skip] -macro_rules! m { - ($visitor: expr) => { - *& $visitor - }; -} - -#[rustfmt::skip] -macro_rules! m_mut { - ($visitor: expr) => { - *& mut $visitor - }; -} - #[derive(Copy, Clone)] pub struct S; +#[inline_macros] impl S { pub fn f(&self) -> &Self { - m!(self) + inline!(*& $(@expr self)) } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { - m_mut!(self) + inline!(*&mut $(@expr self)) } } diff --git a/src/tools/clippy/tests/ui/deref_addrof.stderr b/src/tools/clippy/tests/ui/deref_addrof.stderr index 75371fcdb..e0287522f 100644 --- a/src/tools/clippy/tests/ui/deref_addrof.stderr +++ b/src/tools/clippy/tests/ui/deref_addrof.stderr @@ -1,5 +1,5 @@ error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:19:13 + --> $DIR/deref_addrof.rs:24:13 | LL | let b = *&a; | ^^^ help: try this: `a` @@ -7,68 +7,62 @@ LL | let b = *&a; = note: `-D clippy::deref-addrof` implied by `-D warnings` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:21:13 + --> $DIR/deref_addrof.rs:26:13 | LL | let b = *&get_number(); | ^^^^^^^^^^^^^^ help: try this: `get_number()` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:26:13 + --> $DIR/deref_addrof.rs:31:13 | LL | let b = *&bytes[1..2][0]; | ^^^^^^^^^^^^^^^^ help: try this: `bytes[1..2][0]` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:30:13 + --> $DIR/deref_addrof.rs:35:13 | LL | let b = *&(a); | ^^^^^ help: try this: `(a)` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:32:13 + --> $DIR/deref_addrof.rs:37:13 | LL | let b = *(&a); | ^^^^^ help: try this: `a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:35:13 + --> $DIR/deref_addrof.rs:40:13 | LL | let b = *((&a)); | ^^^^^^^ help: try this: `a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:37:13 + --> $DIR/deref_addrof.rs:42:13 | LL | let b = *&&a; | ^^^^ help: try this: `&a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:39:14 + --> $DIR/deref_addrof.rs:44:14 | LL | let b = **&aref; | ^^^^^^ help: try this: `aref` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:47:9 + --> $DIR/deref_addrof.rs:54:17 | -LL | *& $visitor - | ^^^^^^^^^^^ help: try this: `$visitor` -... -LL | m!(self) - | -------- in this macro invocation +LL | inline!(*& $(@expr self)) + | ^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` | - = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:54:9 + --> $DIR/deref_addrof.rs:58:17 | -LL | *& mut $visitor - | ^^^^^^^^^^^^^^^ help: try this: `$visitor` -... -LL | m_mut!(self) - | ------------ in this macro invocation +LL | inline!(*&mut $(@expr self)) + | ^^^^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` | - = note: this error originates in the macro `m_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/deref_addrof_macro.rs b/src/tools/clippy/tests/ui/deref_addrof_macro.rs index dcebd6c6e..57c0be3f5 100644 --- a/src/tools/clippy/tests/ui/deref_addrof_macro.rs +++ b/src/tools/clippy/tests/ui/deref_addrof_macro.rs @@ -1,10 +1,13 @@ -macro_rules! m { - ($($x:tt),*) => { &[$(($x, stringify!(x)),)*] }; -} +// aux-build:proc_macros.rs + +#![warn(clippy::deref_addrof)] + +extern crate proc_macros; -#[warn(clippy::deref_addrof)] -fn f() -> [(i32, &'static str); 3] { - *m![1, 2, 3] // should be fine +#[proc_macros::inline_macros] +fn f() -> i32 { + // should be fine + *inline!(&$1) } fn main() {} diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed index ee8456f5d..89ec33a0d 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.fixed +++ b/src/tools/clippy/tests/ui/derivable_impls.fixed @@ -231,4 +231,41 @@ impl Default for NonExhaustiveEnum { } } +// https://github.com/rust-lang/rust-clippy/issues/10396 + +#[derive(Default)] +struct DefaultType; + +struct GenericType { + t: T, +} + +impl Default for GenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct InnerGenericType { + t: T, +} + +impl Default for InnerGenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct OtherGenericType { + inner: InnerGenericType, +} + +impl Default for OtherGenericType { + fn default() -> Self { + Self { + inner: Default::default(), + } + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs index 14af419bc..def6e4116 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.rs +++ b/src/tools/clippy/tests/ui/derivable_impls.rs @@ -267,4 +267,41 @@ impl Default for NonExhaustiveEnum { } } +// https://github.com/rust-lang/rust-clippy/issues/10396 + +#[derive(Default)] +struct DefaultType; + +struct GenericType { + t: T, +} + +impl Default for GenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct InnerGenericType { + t: T, +} + +impl Default for InnerGenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct OtherGenericType { + inner: InnerGenericType, +} + +impl Default for OtherGenericType { + fn default() -> Self { + Self { + inner: Default::default(), + } + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr index 81963c3be..8089f5ea0 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.stderr +++ b/src/tools/clippy/tests/ui/derivable_impls.stderr @@ -14,7 +14,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct FooDefault<'a> { | error: this `impl` can be derived @@ -30,7 +31,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct TupleDefault(bool, i32, u64); | error: this `impl` can be derived @@ -46,7 +48,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct StrDefault<'a>(&'a str); | error: this `impl` can be derived @@ -62,7 +65,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct Y(u32); | error: this `impl` can be derived @@ -78,7 +82,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfCurly { | error: this `impl` can be derived @@ -94,7 +99,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfParan(bool); | error: this `impl` can be derived @@ -110,7 +116,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub struct RepeatDefault1 { | error: this `impl` can be derived @@ -126,7 +133,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it... | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub enum SimpleEnum { | help: ...and mark the default variant | diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs index b91f7aa0d..30674ce37 100644 --- a/src/tools/clippy/tests/ui/doc_unsafe.rs +++ b/src/tools/clippy/tests/ui/doc_unsafe.rs @@ -1,9 +1,9 @@ -// aux-build:doc_unsafe_macros.rs +// aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] -#[macro_use] -extern crate doc_unsafe_macros; +extern crate proc_macros; +use proc_macros::external; /// This is not sufficiently documented pub unsafe fn destroy_the_planet() { @@ -105,7 +105,11 @@ macro_rules! very_unsafe { very_unsafe!(); // we don't lint code from external macros -undocd_unsafe!(); +external! { + pub unsafe fn oy_vey() { + unimplemented!(); + } +} fn main() { unsafe { diff --git a/src/tools/clippy/tests/ui/double_must_use.rs b/src/tools/clippy/tests/ui/double_must_use.rs index 05e087b08..26a387b3c 100644 --- a/src/tools/clippy/tests/ui/double_must_use.rs +++ b/src/tools/clippy/tests/ui/double_must_use.rs @@ -21,6 +21,17 @@ pub fn must_use_with_note() -> Result<(), ()> { unimplemented!(); } +// vvvv Should not lint (#10486) +#[must_use] +async fn async_must_use() -> usize { + unimplemented!(); +} + +#[must_use] +async fn async_must_use_result() -> Result<(), ()> { + Ok(()) +} + fn main() { must_use_result(); must_use_tuple(); diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr index 3d34557a8..49ab2ea3e 100644 --- a/src/tools/clippy/tests/ui/double_must_use.stderr +++ b/src/tools/clippy/tests/ui/double_must_use.stderr @@ -23,5 +23,13 @@ LL | pub fn must_use_array() -> [Result<(), ()>; 1] { | = help: either add some descriptive text or remove the attribute -error: aborting due to 3 previous errors +error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` + --> $DIR/double_must_use.rs:31:1 + | +LL | async fn async_must_use_result() -> Result<(), ()> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: either add some descriptive text or remove the attribute + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/empty_loop.rs b/src/tools/clippy/tests/ui/empty_loop.rs index 8fd7697eb..6a8e6b550 100644 --- a/src/tools/clippy/tests/ui/empty_loop.rs +++ b/src/tools/clippy/tests/ui/empty_loop.rs @@ -1,9 +1,9 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::empty_loop)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn should_trigger() { loop {} @@ -16,6 +16,7 @@ fn should_trigger() { } } +#[inline_macros] fn should_not_trigger() { loop { panic!("This is fine") @@ -38,14 +39,10 @@ fn should_not_trigger() { loop {} // We don't lint loops inside macros - macro_rules! foo { - () => { - loop {} - }; - } + inline!(loop {}); // We don't lint external macros - foofoo!() + external!(loop {}); } fn main() {} diff --git a/src/tools/clippy/tests/ui/equatable_if_let.fixed b/src/tools/clippy/tests/ui/equatable_if_let.fixed index 9af2ba962..007702ab5 100644 --- a/src/tools/clippy/tests/ui/equatable_if_let.fixed +++ b/src/tools/clippy/tests/ui/equatable_if_let.fixed @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq { } } +#[inline_macros] fn main() { let a = 2; let b = 3; @@ -78,14 +79,9 @@ fn main() { if Some(g) == Some(NotStructuralEq::A) {} if matches!(h, NoPartialEqStruct { a: 2, b: false }) {} - macro_rules! m1 { - (x) => { - "abc" - }; - } - if "abc" == m1!(x) { + if "abc" == inline!("abc") { println!("OK"); } - equatable_if_let!(a); + external!({ if let 2 = $a {} }); } diff --git a/src/tools/clippy/tests/ui/equatable_if_let.rs b/src/tools/clippy/tests/ui/equatable_if_let.rs index c3626c081..3bda79776 100644 --- a/src/tools/clippy/tests/ui/equatable_if_let.rs +++ b/src/tools/clippy/tests/ui/equatable_if_let.rs @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq { } } +#[inline_macros] fn main() { let a = 2; let b = 3; @@ -78,14 +79,9 @@ fn main() { if let Some(NotStructuralEq::A) = Some(g) {} if let NoPartialEqStruct { a: 2, b: false } = h {} - macro_rules! m1 { - (x) => { - "abc" - }; - } - if let m1!(x) = "abc" { + if let inline!("abc") = "abc" { println!("OK"); } - equatable_if_let!(a); + external!({ if let 2 = $a {} }); } diff --git a/src/tools/clippy/tests/ui/equatable_if_let.stderr b/src/tools/clippy/tests/ui/equatable_if_let.stderr index 40ca75b8d..a72d87bb7 100644 --- a/src/tools/clippy/tests/ui/equatable_if_let.stderr +++ b/src/tools/clippy/tests/ui/equatable_if_let.stderr @@ -1,5 +1,5 @@ error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:59:8 + --> $DIR/equatable_if_let.rs:60:8 | LL | if let 2 = a {} | ^^^^^^^^^ help: try: `a == 2` @@ -7,82 +7,82 @@ LL | if let 2 = a {} = note: `-D clippy::equatable-if-let` implied by `-D warnings` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:60:8 + --> $DIR/equatable_if_let.rs:61:8 | LL | if let Ordering::Greater = a.cmp(&b) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:61:8 + --> $DIR/equatable_if_let.rs:62:8 | LL | if let Some(2) = c {} | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:62:8 + --> $DIR/equatable_if_let.rs:63:8 | LL | if let Struct { a: 2, b: false } = d {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:63:8 + --> $DIR/equatable_if_let.rs:64:8 | LL | if let Enum::TupleVariant(32, 64) = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:64:8 + --> $DIR/equatable_if_let.rs:65:8 | LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:65:8 + --> $DIR/equatable_if_let.rs:66:8 | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:66:8 + --> $DIR/equatable_if_let.rs:67:8 | LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:75:8 + --> $DIR/equatable_if_let.rs:76:8 | LL | if let NotPartialEq::A = f {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:76:8 + --> $DIR/equatable_if_let.rs:77:8 | LL | if let NotStructuralEq::A = g {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:77:8 + --> $DIR/equatable_if_let.rs:78:8 | LL | if let Some(NotPartialEq::A) = Some(f) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:78:8 + --> $DIR/equatable_if_let.rs:79:8 | LL | if let Some(NotStructuralEq::A) = Some(g) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:79:8 + --> $DIR/equatable_if_let.rs:80:8 | LL | if let NoPartialEqStruct { a: 2, b: false } = h {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:86:8 + --> $DIR/equatable_if_let.rs:82:8 | -LL | if let m1!(x) = "abc" { - | ^^^^^^^^^^^^^^^^^^ help: try: `"abc" == m1!(x)` +LL | if let inline!("abc") = "abc" { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")` error: aborting due to 14 previous errors diff --git a/src/tools/clippy/tests/ui/erasing_op.rs b/src/tools/clippy/tests/ui/erasing_op.rs index ae2fad008..74985029e 100644 --- a/src/tools/clippy/tests/ui/erasing_op.rs +++ b/src/tools/clippy/tests/ui/erasing_op.rs @@ -31,9 +31,7 @@ impl core::ops::Mul for Vec1 { #[allow(clippy::no_effect)] #[warn(clippy::erasing_op)] -fn main() { - let x: u8 = 0; - +fn test(x: u8) { x * 0; 0 & x; 0 / x; @@ -41,3 +39,7 @@ fn main() { 0 * Vec1 { x: 5 }; Vec1 { x: 5 } * 0; } + +fn main() { + test(0) +} diff --git a/src/tools/clippy/tests/ui/erasing_op.stderr b/src/tools/clippy/tests/ui/erasing_op.stderr index 165ed9bfe..979412523 100644 --- a/src/tools/clippy/tests/ui/erasing_op.stderr +++ b/src/tools/clippy/tests/ui/erasing_op.stderr @@ -1,5 +1,5 @@ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:37:5 + --> $DIR/erasing_op.rs:35:5 | LL | x * 0; | ^^^^^ @@ -7,25 +7,25 @@ LL | x * 0; = note: `-D clippy::erasing-op` implied by `-D warnings` error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:38:5 + --> $DIR/erasing_op.rs:36:5 | LL | 0 & x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:39:5 + --> $DIR/erasing_op.rs:37:5 | LL | 0 / x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:41:5 + --> $DIR/erasing_op.rs:39:5 | LL | 0 * Vec1 { x: 5 }; | ^^^^^^^^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:42:5 + --> $DIR/erasing_op.rs:40:5 | LL | Vec1 { x: 5 } * 0; | ^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed new file mode 100644 index 000000000..19e718625 --- /dev/null +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed @@ -0,0 +1,105 @@ +// run-rustfix + +#![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>(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 some_unused(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.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs index 480174342..e53bb587e 100644 --- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs @@ -1,3 +1,5 @@ +// run-rustfix + #![allow(unused, clippy::needless_lifetimes)] #![warn(clippy::extra_unused_type_parameters)] @@ -21,14 +23,7 @@ fn used_ret(x: u8) -> T { T::default() } -fn unused_bounded(x: U) { - unimplemented!(); -} - -fn unused_where_clause(x: U) -where - T: Default, -{ +fn unused_bounded(x: U) { unimplemented!(); } diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr index 86c88fc9b..c042a5a22 100644 --- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr @@ -1,75 +1,64 @@ -error: type parameter goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:4:13 +error: type parameter `T` goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:6:13 | LL | fn unused_ty(x: u8) { - | ^^^ + | ^^^ help: consider removing the parameter | - = 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 +error: type parameters go unused in function definition: T, U + --> $DIR/extra_unused_type_parameters.rs:10:16 | LL | fn unused_multi(x: u8) { - | ^^^^^^ - | - = help: consider removing the parameters + | ^^^^^^ help: consider removing the parameters -error: type parameter goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:12:23 +error: type parameter `T` goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:14:21 | LL | fn unused_with_lt<'a, T>(x: &'a u8) { - | ^ - | - = help: consider removing the parameter + | ^^^ help: consider removing the parameter -error: type parameter goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:24:19 +error: type parameters go unused in function definition: T, V + --> $DIR/extra_unused_type_parameters.rs:26:19 | -LL | fn unused_bounded(x: U) { - | ^^^^^^^^^^^ +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 +help: consider removing the parameters | -LL | fn unused_where_clause(x: U) - | ^^ +LL - fn unused_bounded(x: U) { +LL + fn unused_bounded(x: U) { | - = help: consider removing the parameter -error: type parameters go unused in function definition - --> $DIR/extra_unused_type_parameters.rs:35:16 +error: type parameters go unused in function definition: A, D, E + --> $DIR/extra_unused_type_parameters.rs:30:16 | LL | fn some_unused, E>(b: B, c: C) { - | ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing the parameters + | +LL - fn some_unused, E>(b: B, c: C) { +LL + fn some_unused(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 +error: type parameter `T` goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:55:22 | LL | fn unused_ty_impl(&self) { - | ^^^ - | - = help: consider removing the parameter + | ^^^ help: consider removing the parameter -error: type parameters go unused in function definition - --> $DIR/extra_unused_type_parameters.rs:82:17 +error: type parameters go unused in function definition: A, B + --> $DIR/extra_unused_type_parameters.rs:77:17 | LL | fn unused_opaque(dummy: impl Default) { - | ^^^^^^ - | - = help: consider removing the parameters + | ^^^^^^ help: consider removing the parameters -error: type parameter goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:95:58 +error: type parameter `U` goes unused in function definition + --> $DIR/extra_unused_type_parameters.rs:90:56 | LL | fn unused_with_priv_trait_bound() { - | ^ - | - = help: consider removing the parameter + | ^^^ help: consider removing the parameter -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs new file mode 100644 index 000000000..10b39aa8f --- /dev/null +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs @@ -0,0 +1,24 @@ +#![warn(clippy::extra_unused_type_parameters)] + +fn unused_where_clause(x: U) +where + T: Default, +{ + unimplemented!(); +} + +fn unused_multi_where_clause(x: U) +where + T: Default, +{ + unimplemented!(); +} + +fn unused_all_where_clause() +where + T: Default, +{ + unimplemented!(); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr new file mode 100644 index 000000000..a9580cc89 --- /dev/null +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr @@ -0,0 +1,27 @@ +error: type parameter `T` goes unused in function definition + --> $DIR/extra_unused_type_parameters_unfixable.rs:3:24 + | +LL | fn unused_where_clause(x: U) + | ^ + | + = help: consider removing the parameter + = note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings` + +error: type parameters go unused in function definition: T, V + --> $DIR/extra_unused_type_parameters_unfixable.rs:10:30 + | +LL | fn unused_multi_where_clause(x: U) + | ^ ^^^^^^^^^^ + | + = help: consider removing the parameters + +error: type parameters go unused in function definition: T, U, V + --> $DIR/extra_unused_type_parameters_unfixable.rs:17:28 + | +LL | fn unused_all_where_clause() + | ^ ^^^^^^^^^^ ^^^^^^^^^^ + | + = help: consider removing the parameters + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs index 1f989bb12..0e208b3ed 100644 --- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs +++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs @@ -1,12 +1,12 @@ // aux-build:proc_macro_derive.rs -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::field_reassign_with_default)] #[macro_use] extern crate proc_macro_derive; -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; // Don't lint on derives that derive `Default` // See https://github.com/rust-lang/rust-clippy/issues/6545 @@ -36,14 +36,6 @@ struct D { b: Option, } -macro_rules! m { - ($key:ident: $value:tt) => {{ - let mut data = $crate::D::default(); - data.$key = Some($value); - data - }}; -} - /// Implements .next() that returns a different number each time. struct SideEffect(i32); @@ -57,6 +49,7 @@ impl SideEffect { } } +#[inline_macros] fn main() { // wrong, produces first error in stderr let mut a: A = Default::default(); @@ -150,7 +143,18 @@ fn main() { a.i = vec![1]; // Don't lint in external macros - field_reassign_with_default!(); + external! { + #[derive(Default)] + struct A { + pub i: i32, + pub j: i64, + } + fn lint() { + let mut a: A = Default::default(); + a.i = 42; + a; + } + } // be sure suggestion is correct with generics let mut a: Wrapper = Default::default(); @@ -160,9 +164,11 @@ fn main() { a.i = 42; // Don't lint in macros - m! { - a: 42 - }; + inline!( + let mut data = $crate::D::default(); + data.$a = Some($42); + data + ); } mod m { diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr index 710bb66a4..da74f9ef9 100644 --- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr +++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr @@ -1,132 +1,132 @@ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:63:5 + --> $DIR/field_reassign_with_default.rs:56:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:62:5 + --> $DIR/field_reassign_with_default.rs:55:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: `-D clippy::field-reassign-with-default` implied by `-D warnings` error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:103:5 + --> $DIR/field_reassign_with_default.rs:96:5 | LL | a.j = 43; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:102:5 + --> $DIR/field_reassign_with_default.rs:95:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:108:5 + --> $DIR/field_reassign_with_default.rs:101:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:107:5 + --> $DIR/field_reassign_with_default.rs:100:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:114:5 + --> $DIR/field_reassign_with_default.rs:107:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:113:5 + --> $DIR/field_reassign_with_default.rs:106:5 | LL | let mut a = A::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:124:5 + --> $DIR/field_reassign_with_default.rs:117:5 | LL | a.i = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:123:5 + --> $DIR/field_reassign_with_default.rs:116:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:128:5 + --> $DIR/field_reassign_with_default.rs:121:5 | LL | a.i = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:127:5 + --> $DIR/field_reassign_with_default.rs:120:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:150:5 + --> $DIR/field_reassign_with_default.rs:143:5 | LL | a.i = vec![1]; | ^^^^^^^^^^^^^^ | note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:149:5 + --> $DIR/field_reassign_with_default.rs:142:5 | LL | let mut a: C = C::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:157:5 + --> $DIR/field_reassign_with_default.rs:161:5 | LL | a.i = true; | ^^^^^^^^^^^ | note: consider initializing the variable with `Wrapper:: { i: true }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:156:5 + --> $DIR/field_reassign_with_default.rs:160:5 | LL | let mut a: Wrapper = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:160:5 + --> $DIR/field_reassign_with_default.rs:164:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `WrapperMulti:: { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:159:5 + --> $DIR/field_reassign_with_default.rs:163:5 | LL | let mut a: WrapperMulti = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:229:13 + --> $DIR/field_reassign_with_default.rs:235:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:228:13 + --> $DIR/field_reassign_with_default.rs:234:13 | LL | let mut f = ImplDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:245:13 + --> $DIR/field_reassign_with_default.rs:251:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:244:13 + --> $DIR/field_reassign_with_default.rs:250:13 | LL | let mut f = NoDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed index cd2f70ee8..beedf2c1d 100644 --- a/src/tools/clippy/tests/ui/format.fixed +++ b/src/tools/clippy/tests/ui/format.fixed @@ -1,5 +1,4 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -10,8 +9,6 @@ clippy::uninlined_format_args )] -extern crate proc_macro_with_span; - struct Foo(pub String); macro_rules! foo { @@ -90,7 +87,4 @@ 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 c22345a79..e805f1818 100644 --- a/src/tools/clippy/tests/ui/format.rs +++ b/src/tools/clippy/tests/ui/format.rs @@ -1,5 +1,4 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -10,8 +9,6 @@ clippy::uninlined_format_args )] -extern crate proc_macro_with_span; - struct Foo(pub String); macro_rules! foo { @@ -92,7 +89,4 @@ 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 a0e5d5c8a..0ef0ac655 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:22:5 + --> $DIR/format.rs:19: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:23:5 + --> $DIR/format.rs:20:5 | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:24:5 + --> $DIR/format.rs:21:5 | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:25:5 + --> $DIR/format.rs:22:5 | LL | / format!( LL | | r##"foo {{}} @@ -34,67 +34,67 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> $DIR/format.rs:30:13 + --> $DIR/format.rs:27:13 | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> $DIR/format.rs:32:5 + --> $DIR/format.rs:29:5 | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> $DIR/format.rs:40:5 + --> $DIR/format.rs:37:5 | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> $DIR/format.rs:70:5 + --> $DIR/format.rs:67:5 | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> $DIR/format.rs:72:5 + --> $DIR/format.rs:69:5 | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> $DIR/format.rs:76:18 + --> $DIR/format.rs:73:18 | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> $DIR/format.rs:80:22 + --> $DIR/format.rs:77: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:86:13 + --> $DIR/format.rs:83:13 | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:88:13 + --> $DIR/format.rs:85:13 | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:92:13 + --> $DIR/format.rs:89:13 | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> $DIR/format.rs:94:13 + --> $DIR/format.rs:91:13 | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.rs b/src/tools/clippy/tests/ui/format_args_unfixable.rs index eb0ac15bf..423bfaf97 100644 --- a/src/tools/clippy/tests/ui/format_args_unfixable.rs +++ b/src/tools/clippy/tests/ui/format_args_unfixable.rs @@ -1,4 +1,5 @@ #![warn(clippy::format_in_format_args, clippy::to_string_in_format_args)] +#![allow(unused)] #![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::uninlined_format_args)] use std::io::{stdout, Error, ErrorKind, Write}; @@ -57,3 +58,46 @@ fn main() { my_macro!(); println!("error: {}", my_other_macro!()); } + +macro_rules! _internal { + ($($args:tt)*) => { + println!("{}", format_args!($($args)*)) + }; +} + +macro_rules! my_println2 { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!($($args)+) + } + }}; +} + +macro_rules! my_println2_args { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!("foo: {}", format_args!($($args)+)) + } + }}; +} + +fn test2() { + let error = Error::new(ErrorKind::Other, "bad thing"); + + // None of these should be linted without the config change + my_println2!(true, "error: {}", format!("something failed at {}", Location::caller())); + my_println2!( + true, + "{}: {}", + error, + format!("something failed at {}", Location::caller()) + ); + + my_println2_args!(true, "error: {}", format!("something failed at {}", Location::caller())); + my_println2_args!( + true, + "{}: {}", + error, + format!("something failed at {}", Location::caller()) + ); +} diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr index b291d475a..c1be48c3b 100644 --- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr +++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr @@ -1,5 +1,5 @@ error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:25:5 + --> $DIR/format_args_unfixable.rs:26:5 | LL | println!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | println!("error: {}", format!("something failed at {}", Location::calle = note: `-D clippy::format-in-format-args` implied by `-D warnings` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:26:5 + --> $DIR/format_args_unfixable.rs:27:5 | LL | println!("{}: {}", error, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | println!("{}: {}", error, format!("something failed at {}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:27:5 + --> $DIR/format_args_unfixable.rs:28:5 | LL | println!("{:?}: {}", error, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | println!("{:?}: {}", error, format!("something failed at {}", Location: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:28:5 + --> $DIR/format_args_unfixable.rs:29:5 | LL | println!("{{}}: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | println!("{{}}: {}", format!("something failed at {}", Location::caller = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:29:5 + --> $DIR/format_args_unfixable.rs:30:5 | LL | println!(r#"error: "{}""#, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | println!(r#"error: "{}""#, format!("something failed at {}", Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:30:5 + --> $DIR/format_args_unfixable.rs:31:5 | LL | println!("error: {}", format!(r#"something failed at "{}""#, Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | println!("error: {}", format!(r#"something failed at "{}""#, Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> $DIR/format_args_unfixable.rs:31:5 + --> $DIR/format_args_unfixable.rs:32:5 | LL | println!("error: {}", format!("something failed at {} {0}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | println!("error: {}", format!("something failed at {} {0}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `format!` args - --> $DIR/format_args_unfixable.rs:32:13 + --> $DIR/format_args_unfixable.rs:33:13 | LL | let _ = format!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | let _ = format!("error: {}", format!("something failed at {}", Location = help: or consider changing `format!` to `format_args!` error: `format!` in `write!` args - --> $DIR/format_args_unfixable.rs:33:13 + --> $DIR/format_args_unfixable.rs:34:13 | LL | let _ = write!( | _____________^ @@ -86,7 +86,7 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `writeln!` args - --> $DIR/format_args_unfixable.rs:38:13 + --> $DIR/format_args_unfixable.rs:39:13 | LL | let _ = writeln!( | _____________^ @@ -100,7 +100,7 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `print!` args - --> $DIR/format_args_unfixable.rs:43:5 + --> $DIR/format_args_unfixable.rs:44:5 | LL | print!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | print!("error: {}", format!("something failed at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `eprint!` args - --> $DIR/format_args_unfixable.rs:44:5 + --> $DIR/format_args_unfixable.rs:45:5 | LL | eprint!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | eprint!("error: {}", format!("something failed at {}", Location::caller = help: or consider changing `format!` to `format_args!` error: `format!` in `eprintln!` args - --> $DIR/format_args_unfixable.rs:45:5 + --> $DIR/format_args_unfixable.rs:46:5 | LL | eprintln!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | eprintln!("error: {}", format!("something failed at {}", Location::call = help: or consider changing `format!` to `format_args!` error: `format!` in `format_args!` args - --> $DIR/format_args_unfixable.rs:46:13 + --> $DIR/format_args_unfixable.rs:47:13 | LL | let _ = format_args!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | let _ = format_args!("error: {}", format!("something failed at {}", Loc = help: or consider changing `format!` to `format_args!` error: `format!` in `assert!` args - --> $DIR/format_args_unfixable.rs:47:5 + --> $DIR/format_args_unfixable.rs:48:5 | LL | assert!(true, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | assert!(true, "error: {}", format!("something failed at {}", Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_eq!` args - --> $DIR/format_args_unfixable.rs:48:5 + --> $DIR/format_args_unfixable.rs:49:5 | LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_ne!` args - --> $DIR/format_args_unfixable.rs:49:5 + --> $DIR/format_args_unfixable.rs:50:5 | LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `panic!` args - --> $DIR/format_args_unfixable.rs:50:5 + --> $DIR/format_args_unfixable.rs:51:5 | LL | panic!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.rs b/src/tools/clippy/tests/ui/ifs_same_cond.rs index 9850fc091..9ce9a8762 100644 --- a/src/tools/clippy/tests/ui/ifs_same_cond.rs +++ b/src/tools/clippy/tests/ui/ifs_same_cond.rs @@ -43,4 +43,30 @@ fn ifs_same_cond() { } } +fn issue10272() { + let a = String::from("ha"); + if a.contains("ah") { + } else if a.contains("ah") { + // Trigger this lint + } else if a.contains("ha") { + } else if a == "wow" { + } + + let p: *mut i8 = std::ptr::null_mut(); + if p.is_null() { + } else if p.align_offset(0) == 0 { + } else if p.is_null() { + // ok, p is mutable pointer + } else { + } + + let x = std::cell::Cell::new(true); + if x.get() { + } else if !x.take() { + } else if x.get() { + // ok, x is interior mutable type + } else { + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr index 411308732..9519f6904 100644 --- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr +++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr @@ -35,5 +35,17 @@ note: same as this LL | if 2 * a == 1 { | ^^^^^^^^^^ -error: aborting due to 3 previous errors +error: this `if` has the same condition as a previous `if` + --> $DIR/ifs_same_cond.rs:49:15 + | +LL | } else if a.contains("ah") { + | ^^^^^^^^^^^^^^^^ + | +note: same as this + --> $DIR/ifs_same_cond.rs:48:8 + | +LL | if a.contains("ah") { + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr index acfcc2144..803837435 100644 --- a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr +++ b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr @@ -5,7 +5,7 @@ LL | pub fn a(_: impl Trait) {} | ^^^^^^^^^^ | = note: `-D clippy::impl-trait-in-params` implied by `-D warnings` -help: add a type paremeter +help: add a type parameter | LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {} | +++++++++++++++++++++++++++++++ @@ -16,7 +16,7 @@ error: '`impl Trait` used as a function parameter' LL | pub fn c(_: C, _: impl Trait) {} | ^^^^^^^^^^ | -help: add a type paremeter +help: add a type parameter | LL | pub fn c(_: C, _: impl Trait) {} | +++++++++++++++++++++++++++++++ diff --git a/src/tools/clippy/tests/ui/implicit_clone.fixed b/src/tools/clippy/tests/ui/implicit_clone.fixed index 51b1afbe5..8ccc3da7b 100644 --- a/src/tools/clippy/tests/ui/implicit_clone.fixed +++ b/src/tools/clippy/tests/ui/implicit_clone.fixed @@ -87,7 +87,7 @@ fn main() { let kitten = Kitten {}; let _ = kitten.clone(); let _ = own_same_from_ref(&kitten); - // this shouln't lint + // this shouldn't lint let _ = kitten.to_vec(); // we expect no lints for this diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs index 8a9027433..593333126 100644 --- a/src/tools/clippy/tests/ui/implicit_clone.rs +++ b/src/tools/clippy/tests/ui/implicit_clone.rs @@ -87,7 +87,7 @@ fn main() { let kitten = Kitten {}; let _ = kitten.to_owned(); let _ = own_same_from_ref(&kitten); - // this shouln't lint + // this shouldn't lint let _ = kitten.to_vec(); // we expect no lints for this diff --git a/src/tools/clippy/tests/ui/implicit_hasher.rs b/src/tools/clippy/tests/ui/implicit_hasher.rs index fd96ca3f4..35d08a07b 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.rs +++ b/src/tools/clippy/tests/ui/implicit_hasher.rs @@ -1,9 +1,11 @@ -// aux-build:implicit_hasher_macros.rs +// aux-build:proc_macros.rs + #![deny(clippy::implicit_hasher)] #![allow(unused)] #[macro_use] -extern crate implicit_hasher_macros; +extern crate proc_macros; +use proc_macros::external; use std::cmp::Eq; use std::collections::{HashMap, HashSet}; @@ -68,22 +70,19 @@ impl Foo for HashSet { pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} -macro_rules! gen { - (impl) => { +#[proc_macros::inline_macros] +pub mod gen { + use super::*; + inline! { impl Foo for HashMap { fn make() -> (Self, Self) { (HashMap::new(), HashMap::with_capacity(10)) } } - }; - (fn $name:ident) => { - pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - }; + pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + } } -#[rustfmt::skip] -gen!(impl); -gen!(fn bar); // When the macro is in a different file, the suggestion spans can't be combined properly // and should not cause an ICE @@ -94,7 +93,9 @@ pub mod test_macro; __implicit_hasher_test_macro!(impl for HashMap where V: test_macro::A); // #4260 -implicit_hasher_fn!(); +external! { + pub fn f(input: &HashMap) {} +} // #7712 pub async fn election_vote(_data: HashMap) {} diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr index 59b0fba2a..83b46de2e 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.stderr +++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr @@ -1,11 +1,11 @@ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:16:35 + --> $DIR/implicit_hasher.rs:18:35 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/implicit_hasher.rs:2:9 + --> $DIR/implicit_hasher.rs:3:9 | LL | #![deny(clippy::implicit_hasher)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:25:36 + --> $DIR/implicit_hasher.rs:27:36 | LL | impl Foo for (HashMap,) { | ^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:30:19 + --> $DIR/implicit_hasher.rs:32:19 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:47:32 + --> $DIR/implicit_hasher.rs:49:32 | LL | impl Foo for HashSet { | ^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:52:19 + --> $DIR/implicit_hasher.rs:54:19 | LL | impl Foo for HashSet { | ^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:69:23 + --> $DIR/implicit_hasher.rs:71:23 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub fn foo(_map: &mut HashMap, _s | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:69:53 + --> $DIR/implicit_hasher.rs:71:53 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^ @@ -101,15 +101,12 @@ LL | pub fn foo(_map: &mut HashMap, _set: | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:73:43 + --> $DIR/implicit_hasher.rs:77:43 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ -... -LL | gen!(impl); - | ---------- in this macro invocation | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | LL | impl Foo for HashMap { @@ -120,37 +117,31 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:81:33 + --> $DIR/implicit_hasher.rs:83:31 | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | ^^^^^^^^^^^^^^^^^ -... -LL | gen!(fn bar); - | ------------ in this macro invocation +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:81:63 + --> $DIR/implicit_hasher.rs:83:61 | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | ^^^^^^^^^^^^ -... -LL | gen!(fn bar); - | ------------ in this macro invocation +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | ^^^^^^^^^^^^ | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:100:35 + --> $DIR/implicit_hasher.rs:101:35 | LL | pub async fn election_vote(_data: HashMap) {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed index 74ba2f1c5..5aaa00f85 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed @@ -1,10 +1,14 @@ // run-rustfix +// aux-build:proc_macros.rs + #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::no_effect)] #![allow(dead_code)] +extern crate proc_macros; + #[derive(Default)] struct Foo { x: i32, @@ -12,18 +16,10 @@ struct Foo { z: i32, } -macro_rules! new_foo { - () => { - let x = 1; - let y = 1; - let z = 1; - Foo { y, x, z } - }; -} - mod without_base { use super::Foo; + #[proc_macros::inline_macros] fn test() { let x = 1; let y = 1; @@ -34,7 +30,12 @@ mod without_base { // Should NOT lint. // issue #7069. - new_foo!(); + inline!({ + let x = 1; + let y = 1; + let z = 1; + Foo { y, x, z } + }); // Should NOT lint because the order is the same as in the definition. Foo { x, y, z }; diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs index ba96e1e33..2b2dd7f59 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs @@ -1,10 +1,14 @@ // run-rustfix +// aux-build:proc_macros.rs + #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::no_effect)] #![allow(dead_code)] +extern crate proc_macros; + #[derive(Default)] struct Foo { x: i32, @@ -12,18 +16,10 @@ struct Foo { z: i32, } -macro_rules! new_foo { - () => { - let x = 1; - let y = 1; - let z = 1; - Foo { y, x, z } - }; -} - mod without_base { use super::Foo; + #[proc_macros::inline_macros] fn test() { let x = 1; let y = 1; @@ -34,7 +30,12 @@ mod without_base { // Should NOT lint. // issue #7069. - new_foo!(); + inline!({ + let x = 1; + let y = 1; + let z = 1; + Foo { y, x, z } + }); // Should NOT lint because the order is the same as in the definition. Foo { x, y, z }; diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr index c90189e96..785a6dc9d 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr @@ -1,5 +1,5 @@ error: struct constructor field order is inconsistent with struct definition field order - --> $DIR/inconsistent_struct_constructor.rs:33:9 + --> $DIR/inconsistent_struct_constructor.rs:29:9 | LL | Foo { y, x, z }; | ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }` @@ -7,7 +7,7 @@ LL | Foo { y, x, z }; = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings` error: struct constructor field order is inconsistent with struct definition field order - --> $DIR/inconsistent_struct_constructor.rs:55:9 + --> $DIR/inconsistent_struct_constructor.rs:56:9 | LL | / Foo { LL | | z, diff --git a/src/tools/clippy/tests/ui/integer_arithmetic.rs b/src/tools/clippy/tests/ui/integer_arithmetic.rs index 67f24b454..8dfdee662 100644 --- a/src/tools/clippy/tests/ui/integer_arithmetic.rs +++ b/src/tools/clippy/tests/ui/integer_arithmetic.rs @@ -4,7 +4,7 @@ #[rustfmt::skip] fn main() { let mut i = 1i32; - let mut var1 = 0i32; + let mut var1 = 13i32; let mut var2 = -1i32; 1 + i; i * 2; diff --git a/src/tools/clippy/tests/ui/item_after_statement.rs b/src/tools/clippy/tests/ui/item_after_statement.rs deleted file mode 100644 index 5e92dcab1..000000000 --- a/src/tools/clippy/tests/ui/item_after_statement.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![warn(clippy::items_after_statements)] -#![allow(clippy::uninlined_format_args)] - -fn ok() { - fn foo() { - println!("foo"); - } - foo(); -} - -fn last() { - foo(); - fn foo() { - println!("foo"); - } -} - -fn main() { - foo(); - fn foo() { - println!("foo"); - } - foo(); -} - -fn mac() { - let mut a = 5; - println!("{}", a); - // do not lint this, because it needs to be after `a` - macro_rules! b { - () => {{ - a = 6; - fn say_something() { - println!("something"); - } - }}; - } - b!(); - println!("{}", a); -} - -fn semicolon() { - struct S { - a: u32, - }; - impl S { - fn new(a: u32) -> Self { - Self { a } - } - } - - let _ = S::new(3); -} diff --git a/src/tools/clippy/tests/ui/item_after_statement.stderr b/src/tools/clippy/tests/ui/item_after_statement.stderr deleted file mode 100644 index 2523c53ac..000000000 --- a/src/tools/clippy/tests/ui/item_after_statement.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error: adding items after statements is confusing, since items exist from the start of the scope - --> $DIR/item_after_statement.rs:13:5 - | -LL | / fn foo() { -LL | | println!("foo"); -LL | | } - | |_____^ - | - = note: `-D clippy::items-after-statements` implied by `-D warnings` - -error: adding items after statements is confusing, since items exist from the start of the scope - --> $DIR/item_after_statement.rs:20:5 - | -LL | / fn foo() { -LL | | println!("foo"); -LL | | } - | |_____^ - -error: adding items after statements is confusing, since items exist from the start of the scope - --> $DIR/item_after_statement.rs:33:13 - | -LL | / fn say_something() { -LL | | println!("something"); -LL | | } - | |_____________^ -... -LL | b!(); - | ---- in this macro invocation - | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors - diff --git a/src/tools/clippy/tests/ui/items_after_statement.rs b/src/tools/clippy/tests/ui/items_after_statement.rs new file mode 100644 index 000000000..f12cb8f22 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_statement.rs @@ -0,0 +1,70 @@ +#![warn(clippy::items_after_statements)] +#![allow(clippy::uninlined_format_args)] + +fn ok() { + fn foo() { + println!("foo"); + } + foo(); +} + +fn last() { + foo(); + fn foo() { + println!("foo"); + } +} + +fn main() { + foo(); + fn foo() { + println!("foo"); + } + foo(); +} + +fn mac() { + let mut a = 5; + println!("{}", a); + // do not lint this, because it needs to be after `a` + macro_rules! b { + () => {{ + a = 6; + fn say_something() { + println!("something"); + } + }}; + } + b!(); + println!("{}", a); +} + +fn semicolon() { + struct S { + a: u32, + }; + impl S { + fn new(a: u32) -> Self { + Self { a } + } + } + + let _ = S::new(3); +} + +fn item_from_macro() { + macro_rules! static_assert_size { + ($ty:ty, $size:expr) => { + const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; + }; + } + + let _ = 1; + static_assert_size!(u32, 4); +} + +fn allow_attribute() { + let _ = 1; + #[allow(clippy::items_after_statements)] + const _: usize = 1; +} diff --git a/src/tools/clippy/tests/ui/items_after_statement.stderr b/src/tools/clippy/tests/ui/items_after_statement.stderr new file mode 100644 index 000000000..f69635a97 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_statement.stderr @@ -0,0 +1,33 @@ +error: adding items after statements is confusing, since items exist from the start of the scope + --> $DIR/items_after_statement.rs:13:5 + | +LL | / fn foo() { +LL | | println!("foo"); +LL | | } + | |_____^ + | + = note: `-D clippy::items-after-statements` implied by `-D warnings` + +error: adding items after statements is confusing, since items exist from the start of the scope + --> $DIR/items_after_statement.rs:20:5 + | +LL | / fn foo() { +LL | | println!("foo"); +LL | | } + | |_____^ + +error: adding items after statements is confusing, since items exist from the start of the scope + --> $DIR/items_after_statement.rs:33:13 + | +LL | / fn say_something() { +LL | | println!("something"); +LL | | } + | |_____________^ +... +LL | b!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/large_enum_variant.rs b/src/tools/clippy/tests/ui/large_enum_variant.rs index 3b96f09d7..f09f8ae0c 100644 --- a/src/tools/clippy/tests/ui/large_enum_variant.rs +++ b/src/tools/clippy/tests/ui/large_enum_variant.rs @@ -1,11 +1,11 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(dead_code)] #![allow(unused_variables)] #![warn(clippy::large_enum_variant)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; enum LargeEnum { A(i32), @@ -155,5 +155,10 @@ enum LargeEnumOfConst { } fn main() { - large_enum_variant!(); + external!( + enum LargeEnumInMacro { + A(i32), + B([i32; 8000]), + } + ); } diff --git a/src/tools/clippy/tests/ui/large_futures.rs b/src/tools/clippy/tests/ui/large_futures.rs new file mode 100644 index 000000000..4a8ba995d --- /dev/null +++ b/src/tools/clippy/tests/ui/large_futures.rs @@ -0,0 +1,61 @@ +#![feature(generators)] +#![warn(clippy::large_futures)] +#![allow(clippy::future_not_send)] +#![allow(clippy::manual_async_fn)] + +async fn big_fut(_arg: [u8; 1024 * 16]) {} + +async fn wait() { + let f = async { + big_fut([0u8; 1024 * 16]).await; + }; + f.await +} +async fn calls_fut(fut: impl std::future::Future) { + loop { + wait().await; + if true { + return fut.await; + } else { + wait().await; + } + } +} + +pub async fn test() { + let fut = big_fut([0u8; 1024 * 16]); + foo().await; + calls_fut(fut).await; +} + +pub fn foo() -> impl std::future::Future { + async { + let x = [0i32; 1024 * 16]; + async {}.await; + dbg!(x); + } +} + +pub async fn lines() { + async { + let x = [0i32; 1024 * 16]; + async {}.await; + println!("{:?}", x); + } + .await; +} + +pub async fn macro_expn() { + macro_rules! macro_ { + () => { + async { + let x = [0i32; 1024 * 16]; + async {}.await; + println!("macro: {:?}", x); + } + }; + } + macro_!().await +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/large_futures.stderr b/src/tools/clippy/tests/ui/large_futures.stderr new file mode 100644 index 000000000..67e0fceff --- /dev/null +++ b/src/tools/clippy/tests/ui/large_futures.stderr @@ -0,0 +1,82 @@ +error: large future with a size of 16385 bytes + --> $DIR/large_futures.rs:10:9 + | +LL | big_fut([0u8; 1024 * 16]).await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))` + | + = note: `-D clippy::large-futures` implied by `-D warnings` + +error: large future with a size of 16386 bytes + --> $DIR/large_futures.rs:12:5 + | +LL | f.await + | ^ help: consider `Box::pin` on it: `Box::pin(f)` + +error: large future with a size of 16387 bytes + --> $DIR/large_futures.rs:16:9 + | +LL | wait().await; + | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` + +error: large future with a size of 16387 bytes + --> $DIR/large_futures.rs:20:13 + | +LL | wait().await; + | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` + +error: large future with a size of 65540 bytes + --> $DIR/large_futures.rs:27:5 + | +LL | foo().await; + | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` + +error: large future with a size of 49159 bytes + --> $DIR/large_futures.rs:28:5 + | +LL | calls_fut(fut).await; + | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` + +error: large future with a size of 65540 bytes + --> $DIR/large_futures.rs:40:5 + | +LL | / async { +LL | | let x = [0i32; 1024 * 16]; +LL | | async {}.await; +LL | | println!("{:?}", x); +LL | | } + | |_____^ + | +help: consider `Box::pin` on it + | +LL ~ Box::pin(async { +LL + let x = [0i32; 1024 * 16]; +LL + async {}.await; +LL + println!("{:?}", x); +LL + }) + | + +error: large future with a size of 65540 bytes + --> $DIR/large_futures.rs:51:13 + | +LL | / async { +LL | | let x = [0i32; 1024 * 16]; +LL | | async {}.await; +LL | | println!("macro: {:?}", x); +LL | | } + | |_____________^ +... +LL | macro_!().await + | --------- in this macro invocation + | + = note: this error originates in the macro `macro_` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider `Box::pin` on it + | +LL ~ Box::pin(async { +LL + let x = [0i32; 1024 * 16]; +LL + async {}.await; +LL + println!("macro: {:?}", x); +LL + }) + | + +error: aborting due to 8 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 b5dec6c46..52aabefae 100644 --- a/src/tools/clippy/tests/ui/len_without_is_empty.rs +++ b/src/tools/clippy/tests/ui/len_without_is_empty.rs @@ -282,6 +282,87 @@ impl AsyncLen { } } +// issue #7232 +pub struct AsyncLenWithoutIsEmpty; +impl AsyncLenWithoutIsEmpty { + pub async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> usize { + usize::from(!self.async_task().await) + } +} + +// issue #7232 +pub struct AsyncOptionLenWithoutIsEmpty; +impl AsyncOptionLenWithoutIsEmpty { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Option { + None + } +} + +// issue #7232 +pub struct AsyncOptionLenNonIntegral; +impl AsyncOptionLenNonIntegral { + // don't lint + pub async fn len(&self) -> Option { + None + } +} + +// issue #7232 +pub struct AsyncResultLenWithoutIsEmpty; +impl AsyncResultLenWithoutIsEmpty { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Result { + Err(()) + } +} + +// issue #7232 +pub struct AsyncOptionLen; +impl AsyncOptionLen { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Result { + Err(()) + } + + pub async fn is_empty(&self) -> bool { + true + } +} + +pub struct AsyncLenSyncIsEmpty; +impl AsyncLenSyncIsEmpty { + pub async fn len(&self) -> u32 { + 0 + } + + pub fn is_empty(&self) -> bool { + true + } +} + +// issue #9520 +pub struct NonStandardLen; +impl NonStandardLen { + // don't lint + pub fn len(&self, something: usize) -> usize { + something + } +} + // issue #9520 pub struct NonStandardLenAndIsEmptySignature; impl NonStandardLenAndIsEmptySignature { @@ -328,4 +409,15 @@ impl NonStandardSignatureWithGenerics { } } +pub struct DifferingErrors; +impl DifferingErrors { + pub fn len(&self) -> Result { + Ok(0) + } + + pub fn is_empty(&self) -> Result { + Ok(true) + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr index 8e890e2e2..1bce1734b 100644 --- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr +++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr @@ -119,5 +119,23 @@ LL | pub fn len(&self) -> Result { | = help: use a custom `Error` type instead -error: aborting due to 12 previous errors +error: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:292:5 + | +LL | pub async fn len(&self) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:304:5 + | +LL | pub async fn len(&self) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:325:5 + | +LL | pub async fn len(&self) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 15 previous errors diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed index 6343cff0f..76ff0645f 100644 --- a/src/tools/clippy/tests/ui/let_unit.fixed +++ b/src/tools/clippy/tests/ui/let_unit.fixed @@ -175,3 +175,7 @@ fn attributes() { #[expect(clippy::let_unit_value)] let _ = f(); } + +async fn issue10433() { + let _pending: () = std::future::pending().await; +} diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs index c9bb2849f..895ccfe36 100644 --- a/src/tools/clippy/tests/ui/let_unit.rs +++ b/src/tools/clippy/tests/ui/let_unit.rs @@ -175,3 +175,7 @@ fn attributes() { #[expect(clippy::let_unit_value)] let _ = f(); } + +async fn issue10433() { + let _pending: () = std::future::pending().await; +} diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.rs b/src/tools/clippy/tests/ui/let_with_type_underscore.rs new file mode 100644 index 000000000..175718b94 --- /dev/null +++ b/src/tools/clippy/tests/ui/let_with_type_underscore.rs @@ -0,0 +1,19 @@ +#![allow(unused)] +#![warn(clippy::let_with_type_underscore)] +#![allow(clippy::let_unit_value)] + +fn func() -> &'static str { + "" +} + +fn main() { + // Will lint + let x: _ = 1; + let _: _ = 2; + let x: _ = func(); + + let x = 1; // Will not lint, Rust inferres this to an integer before Clippy + let x = func(); + let x: Vec<_> = Vec::::new(); + let x: [_; 1] = [1]; +} diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.stderr b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr new file mode 100644 index 000000000..16bf83c70 --- /dev/null +++ b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr @@ -0,0 +1,39 @@ +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:11:5 + | +LL | let x: _ = 1; + | ^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:11:10 + | +LL | let x: _ = 1; + | ^^^ + = note: `-D clippy::let-with-type-underscore` implied by `-D warnings` + +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:12:5 + | +LL | let _: _ = 2; + | ^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:12:10 + | +LL | let _: _ = 2; + | ^^^ + +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:13:5 + | +LL | let x: _ = func(); + | ^^^^^^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:13:10 + | +LL | let x: _ = func(); + | ^^^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed new file mode 100644 index 000000000..f4033cd8e --- /dev/null +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed @@ -0,0 +1,29 @@ +// run-rustfix + +#![allow(unused, clippy::map_identity)] +#![warn(clippy::lines_filter_map_ok)] + +use std::io::{self, BufRead, BufReader}; + +fn main() -> io::Result<()> { + let f = std::fs::File::open("/")?; + // Lint + BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + // Lint + let f = std::fs::File::open("/")?; + BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + let s = "foo\nbar\nbaz\n"; + // Lint + io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + // Lint + io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + // Do not lint (not a `Lines` iterator) + io::stdin() + .lines() + .map(std::convert::identity) + .filter_map(|x| x.ok()) + .for_each(|_| ()); + // Do not lint (not a `Result::ok()` extractor) + io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); + Ok(()) +} diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs new file mode 100644 index 000000000..7e11816b2 --- /dev/null +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs @@ -0,0 +1,29 @@ +// run-rustfix + +#![allow(unused, clippy::map_identity)] +#![warn(clippy::lines_filter_map_ok)] + +use std::io::{self, BufRead, BufReader}; + +fn main() -> io::Result<()> { + let f = std::fs::File::open("/")?; + // Lint + BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ()); + // Lint + let f = std::fs::File::open("/")?; + BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); + let s = "foo\nbar\nbaz\n"; + // Lint + io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); + // Lint + io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); + // Do not lint (not a `Lines` iterator) + io::stdin() + .lines() + .map(std::convert::identity) + .filter_map(|x| x.ok()) + .for_each(|_| ()); + // Do not lint (not a `Result::ok()` extractor) + io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); + Ok(()) +} diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr new file mode 100644 index 000000000..cddd403d5 --- /dev/null +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr @@ -0,0 +1,51 @@ +error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:11:31 + | +LL | BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:11:5 + | +LL | BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::lines-filter-map-ok` implied by `-D warnings` + +error: `flat_map()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:14:31 + | +LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:14:5 + | +LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:17:25 + | +LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:17:5 + | +LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^ + +error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:19:25 + | +LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:19:5 + | +LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed index e612480d2..a395e4f56 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.fixed +++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed @@ -16,11 +16,11 @@ extern crate macro_use_helper as mac; extern crate proc_macro_derive as mini_mac; mod a { - use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro}; + use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro}; use mac; use mini_mac::ClippyMiniMacroTest; use mini_mac; - use mac::{inner::foofoo, inner::try_err}; + use mac::{inner::mut_mut, inner::try_err}; use mac::inner; use mac::inner::nested::string_add; use mac::inner::nested; @@ -36,7 +36,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/src/tools/clippy/tests/ui/macro_use_imports.rs b/src/tools/clippy/tests/ui/macro_use_imports.rs index b34817cc3..b1a287332 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.rs +++ b/src/tools/clippy/tests/ui/macro_use_imports.rs @@ -36,7 +36,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/src/tools/clippy/tests/ui/macro_use_imports.stderr b/src/tools/clippy/tests/ui/macro_use_imports.stderr index 61843124c..6fd338cef 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.stderr +++ b/src/tools/clippy/tests/ui/macro_use_imports.stderr @@ -16,13 +16,13 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition --> $DIR/macro_use_imports.rs:23:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition --> $DIR/macro_use_imports.rs:19:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs index 8a1b05da9..5aac5af26 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs +++ b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs @@ -39,7 +39,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed index b7e46a4a8..5cc4a43af 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.fixed +++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed @@ -107,4 +107,10 @@ mod issue_5765 { } } +pub async fn issue_10450() -> i32 { 42 } + +pub(crate) async fn issue_10450_2() -> i32 { 42 } + +pub(self) async fn issue_10450_3() -> i32 { 42 } + fn main() {} diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs index b05429da6..ba504b8a8 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.rs +++ b/src/tools/clippy/tests/ui/manual_async_fn.rs @@ -127,4 +127,16 @@ mod issue_5765 { } } +pub fn issue_10450() -> impl Future { + async { 42 } +} + +pub(crate) fn issue_10450_2() -> impl Future { + async { 42 } +} + +pub(self) fn issue_10450_3() -> impl Future { + async { 42 } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr index 0a903ed6f..f5ee3eb7c 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.stderr +++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr @@ -161,5 +161,50 @@ help: move the body of the async block to the enclosing function LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { 42 } | ~~~~~~ -error: aborting due to 10 previous errors +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:130:1 + | +LL | pub fn issue_10450() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub async fn issue_10450() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub fn issue_10450() -> impl Future { 42 } + | ~~~~~~ + +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:134:1 + | +LL | pub(crate) fn issue_10450_2() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub(crate) async fn issue_10450_2() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub(crate) fn issue_10450_2() -> impl Future { 42 } + | ~~~~~~ + +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:138:1 + | +LL | pub(self) fn issue_10450_3() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub(self) async fn issue_10450_3() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub(self) fn issue_10450_3() -> impl Future { 42 } + | ~~~~~~ + +error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/manual_clamp.rs b/src/tools/clippy/tests/ui/manual_clamp.rs index f7902e6fd..cdfd8e4c3 100644 --- a/src/tools/clippy/tests/ui/manual_clamp.rs +++ b/src/tools/clippy/tests/ui/manual_clamp.rs @@ -326,3 +326,22 @@ fn msrv_1_50() { input }; } + +const fn _const() { + let (input, min, max) = (0, -1, 2); + let _ = if input < min { + min + } else if input > max { + max + } else { + input + }; + + let mut x = input; + if max < x { + let x = max; + } + if min > x { + x = min; + } +} diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.fixed b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed new file mode 100644 index 000000000..50f46d6b3 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed @@ -0,0 +1,39 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_main_separator_str)] + +use std::path::MAIN_SEPARATOR; + +fn len(s: &str) -> usize { + s.len() +} + +struct U<'a> { + f: &'a str, + g: &'a String, +} + +struct V { + f: T, +} + +fn main() { + // Should lint + let _: &str = std::path::MAIN_SEPARATOR_STR; + let _ = len(std::path::MAIN_SEPARATOR_STR); + let _: Vec = std::path::MAIN_SEPARATOR_STR.encode_utf16().collect(); + + // Should lint for field `f` only + let _ = U { + f: std::path::MAIN_SEPARATOR_STR, + g: &MAIN_SEPARATOR.to_string(), + }; + + // Should not lint + let _: &String = &MAIN_SEPARATOR.to_string(); + let _ = &MAIN_SEPARATOR.to_string(); + let _ = V { + f: &MAIN_SEPARATOR.to_string(), + }; +} diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.rs b/src/tools/clippy/tests/ui/manual_main_separator_str.rs new file mode 100644 index 000000000..2dbb9e661 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_main_separator_str.rs @@ -0,0 +1,39 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_main_separator_str)] + +use std::path::MAIN_SEPARATOR; + +fn len(s: &str) -> usize { + s.len() +} + +struct U<'a> { + f: &'a str, + g: &'a String, +} + +struct V { + f: T, +} + +fn main() { + // Should lint + let _: &str = &MAIN_SEPARATOR.to_string(); + let _ = len(&MAIN_SEPARATOR.to_string()); + let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); + + // Should lint for field `f` only + let _ = U { + f: &MAIN_SEPARATOR.to_string(), + g: &MAIN_SEPARATOR.to_string(), + }; + + // Should not lint + let _: &String = &MAIN_SEPARATOR.to_string(); + let _ = &MAIN_SEPARATOR.to_string(); + let _ = V { + f: &MAIN_SEPARATOR.to_string(), + }; +} diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.stderr b/src/tools/clippy/tests/ui/manual_main_separator_str.stderr new file mode 100644 index 000000000..e6cefde66 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_main_separator_str.stderr @@ -0,0 +1,28 @@ +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:23:19 + | +LL | let _: &str = &MAIN_SEPARATOR.to_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + | + = note: `-D clippy::manual-main-separator-str` implied by `-D warnings` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:24:17 + | +LL | let _ = len(&MAIN_SEPARATOR.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:25:23 + | +LL | let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:29:12 + | +LL | f: &MAIN_SEPARATOR.to_string(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed index 4cdc0546a..1f6df1b0a 100644 --- a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed +++ b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed @@ -1,18 +1,13 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] +#![allow(clippy::let_with_type_underscore)] -#[macro_use] -extern crate macro_rules; - -macro_rules! internal_rem_euclid { - () => { - let value: i32 = 5; - let _: i32 = value.rem_euclid(4); - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let value: i32 = 5; @@ -38,10 +33,16 @@ fn main() { let _: i32 = ((4 % value) + 4) % 4; // Lint in internal macros - internal_rem_euclid!(); + inline!( + let value: i32 = 5; + let _: i32 = value.rem_euclid(4); + ); // Do not lint in external macros - manual_rem_euclid!(); + external!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); } // Should lint for params too diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.rs b/src/tools/clippy/tests/ui/manual_rem_euclid.rs index 58a9e20f3..b275e8a38 100644 --- a/src/tools/clippy/tests/ui/manual_rem_euclid.rs +++ b/src/tools/clippy/tests/ui/manual_rem_euclid.rs @@ -1,18 +1,13 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] +#![allow(clippy::let_with_type_underscore)] -#[macro_use] -extern crate macro_rules; - -macro_rules! internal_rem_euclid { - () => { - let value: i32 = 5; - let _: i32 = ((value % 4) + 4) % 4; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let value: i32 = 5; @@ -38,10 +33,16 @@ fn main() { let _: i32 = ((4 % value) + 4) % 4; // Lint in internal macros - internal_rem_euclid!(); + inline!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); // Do not lint in external macros - manual_rem_euclid!(); + external!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); } // Should lint for params too diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr index e3122a588..a43707f89 100644 --- a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr +++ b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr @@ -1,5 +1,5 @@ error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:19:18 + --> $DIR/manual_rem_euclid.rs:14:18 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` @@ -7,60 +7,57 @@ LL | let _: i32 = ((value % 4) + 4) % 4; = note: `-D clippy::manual-rem-euclid` implied by `-D warnings` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:20:18 + --> $DIR/manual_rem_euclid.rs:15:18 | LL | let _: i32 = (4 + (value % 4)) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:21:18 + --> $DIR/manual_rem_euclid.rs:16:18 | LL | let _: i32 = (value % 4 + 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:22:18 + --> $DIR/manual_rem_euclid.rs:17:18 | LL | let _: i32 = (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:23:22 + --> $DIR/manual_rem_euclid.rs:18:22 | LL | let _: i32 = 1 + (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:12:22 + --> $DIR/manual_rem_euclid.rs:38:22 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` -... -LL | internal_rem_euclid!(); - | ---------------------- in this macro invocation | - = note: this error originates in the macro `internal_rem_euclid` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:49:5 + --> $DIR/manual_rem_euclid.rs:50:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:54:5 + --> $DIR/manual_rem_euclid.rs:55:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:66:18 + --> $DIR/manual_rem_euclid.rs:67:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:79:18 + --> $DIR/manual_rem_euclid.rs:80:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs new file mode 100644 index 000000000..5082f931f --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs @@ -0,0 +1,36 @@ +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +use core::mem::{align_of, size_of}; + +fn main() { + let v_i32 = Vec::::new(); + let s_i32 = v_i32.as_slice(); + + // True positives: + let _ = s_i32.len() * size_of::(); // WARNING + let _ = size_of::() * s_i32.len(); // WARNING + let _ = size_of::() * s_i32.len() * 5; // WARNING + + let len = s_i32.len(); + let size = size_of::(); + let _ = len * size_of::(); // WARNING + let _ = s_i32.len() * size; // WARNING + let _ = len * size; // WARNING + + // True negatives: + let _ = size_of::() + s_i32.len(); // Ok, not a multiplication + let _ = size_of::() * s_i32.partition_point(|_| true); // Ok, not len() + let _ = size_of::() * v_i32.len(); // Ok, not a slice + let _ = align_of::() * s_i32.len(); // Ok, not size_of() + let _ = size_of::() * s_i32.len(); // Ok, different types + + // False negatives: + let _ = 5 * size_of::() * s_i32.len(); // Ok (MISSED OPPORTUNITY) + let _ = size_of::() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY) +} + +const fn _const(s_i32: &[i32]) { + // True negative: + let _ = s_i32.len() * size_of::(); // Ok, can't use size_of_val in const +} diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr new file mode 100644 index 000000000..4a24fc60a --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr @@ -0,0 +1,51 @@ +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:11:13 + | +LL | let _ = s_i32.len() * size_of::(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:12:13 + | +LL | let _ = size_of::() * s_i32.len(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:13:13 + | +LL | let _ = size_of::() * s_i32.len() * 5; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:17:13 + | +LL | let _ = len * size_of::(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:18:13 + | +LL | let _ = s_i32.len() * size; // WARNING + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:19:13 + | +LL | let _ = len * size; // WARNING + | ^^^^^^^^^^ + | + = help: consider using std::mem::size_of_value instead + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/match_result_ok.fixed b/src/tools/clippy/tests/ui/match_result_ok.fixed index 8b91b9854..10ae1ee52 100644 --- a/src/tools/clippy/tests/ui/match_result_ok.fixed +++ b/src/tools/clippy/tests/ui/match_result_ok.fixed @@ -16,7 +16,7 @@ fn str_to_int_ok(x: &str) -> i32 { #[rustfmt::skip] fn strange_some_no_else(x: &str) -> i32 { { - if let Ok(y) = x . parse() { + if let Ok(y) = x . parse() { return y; }; 0 diff --git a/src/tools/clippy/tests/ui/match_result_ok.stderr b/src/tools/clippy/tests/ui/match_result_ok.stderr index 98a95705c..cbdc56aa2 100644 --- a/src/tools/clippy/tests/ui/match_result_ok.stderr +++ b/src/tools/clippy/tests/ui/match_result_ok.stderr @@ -18,7 +18,7 @@ LL | if let Some(y) = x . parse() . ok () { | help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x . parse() { +LL | if let Ok(y) = x . parse() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant diff --git a/src/tools/clippy/tests/ui/match_single_binding.fixed b/src/tools/clippy/tests/ui/match_single_binding.fixed index 6cfb6661a..201301cc9 100644 --- a/src/tools/clippy/tests/ui/match_single_binding.fixed +++ b/src/tools/clippy/tests/ui/match_single_binding.fixed @@ -1,7 +1,12 @@ // run-rustfix #![warn(clippy::match_single_binding)] -#![allow(unused_variables)] -#![allow(clippy::toplevel_ref_arg, clippy::uninlined_format_args)] +#![allow( + unused, + clippy::let_unit_value, + clippy::no_effect, + clippy::toplevel_ref_arg, + clippy::uninlined_format_args +)] struct Point { x: i32, @@ -109,10 +114,9 @@ fn main() { // Lint let x = 1; - println!("Not an array index start"); + println!("Not an array index start") } -#[allow(dead_code)] fn issue_8723() { let (mut val, idx) = ("a b", 1); @@ -125,16 +129,15 @@ fn issue_8723() { let _ = val; } -#[allow(dead_code)] +fn side_effects() {} + fn issue_9575() { - fn side_effects() {} let _ = || { side_effects(); - println!("Needs curlies"); + println!("Needs curlies") }; } -#[allow(dead_code)] fn issue_9725(r: Option) { let x = r; match x { @@ -146,3 +149,25 @@ fn issue_9725(r: Option) { }, }; } + +fn issue_10447() -> usize { + (); + + let a = (); + + side_effects(); + + let b = side_effects(); + + println!("1"); + + let c = println!("1"); + + let in_expr = [ + (), + side_effects(), + println!("1"), + ]; + + 2 +} diff --git a/src/tools/clippy/tests/ui/match_single_binding.rs b/src/tools/clippy/tests/ui/match_single_binding.rs index f188aeb5f..8b047b19c 100644 --- a/src/tools/clippy/tests/ui/match_single_binding.rs +++ b/src/tools/clippy/tests/ui/match_single_binding.rs @@ -1,7 +1,12 @@ // run-rustfix #![warn(clippy::match_single_binding)] -#![allow(unused_variables)] -#![allow(clippy::toplevel_ref_arg, clippy::uninlined_format_args)] +#![allow( + unused, + clippy::let_unit_value, + clippy::no_effect, + clippy::toplevel_ref_arg, + clippy::uninlined_format_args +)] struct Point { x: i32, @@ -127,7 +132,6 @@ fn main() { } } -#[allow(dead_code)] fn issue_8723() { let (mut val, idx) = ("a b", 1); @@ -141,15 +145,14 @@ fn issue_8723() { let _ = val; } -#[allow(dead_code)] +fn side_effects() {} + fn issue_9575() { - fn side_effects() {} let _ = || match side_effects() { _ => println!("Needs curlies"), }; } -#[allow(dead_code)] fn issue_9725(r: Option) { match r { x => match x { @@ -162,3 +165,43 @@ fn issue_9725(r: Option) { }, }; } + +fn issue_10447() -> usize { + match 1 { + _ => (), + } + + let a = match 1 { + _ => (), + }; + + match 1 { + _ => side_effects(), + } + + let b = match 1 { + _ => side_effects(), + }; + + match 1 { + _ => println!("1"), + } + + let c = match 1 { + _ => println!("1"), + }; + + let in_expr = [ + match 1 { + _ => (), + }, + match 1 { + _ => side_effects(), + }, + match 1 { + _ => println!("1"), + }, + ]; + + 2 +} diff --git a/src/tools/clippy/tests/ui/match_single_binding.stderr b/src/tools/clippy/tests/ui/match_single_binding.stderr index e960d64ad..9d16af76c 100644 --- a/src/tools/clippy/tests/ui/match_single_binding.stderr +++ b/src/tools/clippy/tests/ui/match_single_binding.stderr @@ -1,5 +1,5 @@ error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:28:5 + --> $DIR/match_single_binding.rs:33:5 | LL | / match (a, b, c) { LL | | (x, y, z) => { @@ -18,7 +18,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:34:5 + --> $DIR/match_single_binding.rs:39:5 | LL | / match (a, b, c) { LL | | (x, y, z) => println!("{} {} {}", x, y, z), @@ -32,7 +32,7 @@ LL + println!("{} {} {}", x, y, z); | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:51:5 + --> $DIR/match_single_binding.rs:56:5 | LL | / match a { LL | | _ => println!("whatever"), @@ -40,7 +40,7 @@ LL | | } | |_____^ help: consider using the match body instead: `println!("whatever");` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:55:5 + --> $DIR/match_single_binding.rs:60:5 | LL | / match a { LL | | _ => { @@ -59,7 +59,7 @@ LL + } | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:62:5 + --> $DIR/match_single_binding.rs:67:5 | LL | / match a { LL | | _ => { @@ -81,7 +81,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:72:5 + --> $DIR/match_single_binding.rs:77:5 | LL | / match p { LL | | Point { x, y } => println!("Coords: ({}, {})", x, y), @@ -95,7 +95,7 @@ LL + println!("Coords: ({}, {})", x, y); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:76:5 + --> $DIR/match_single_binding.rs:81:5 | LL | / match p { LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), @@ -109,7 +109,7 @@ LL + println!("Coords: ({}, {})", x1, y1); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:81:5 + --> $DIR/match_single_binding.rs:86:5 | LL | / match x { LL | | ref r => println!("Got a reference to {}", r), @@ -123,7 +123,7 @@ LL + println!("Got a reference to {}", r); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:86:5 + --> $DIR/match_single_binding.rs:91:5 | LL | / match x { LL | | ref mut mr => println!("Got a mutable reference to {}", mr), @@ -137,7 +137,7 @@ LL + println!("Got a mutable reference to {}", mr); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:90:5 + --> $DIR/match_single_binding.rs:95:5 | LL | / let product = match coords() { LL | | Point { x, y } => x * y, @@ -151,7 +151,7 @@ LL + let product = x * y; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:98:18 + --> $DIR/match_single_binding.rs:103:18 | LL | .map(|i| match i.unwrap() { | __________________^ @@ -168,16 +168,16 @@ LL ~ }) | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:124:5 + --> $DIR/match_single_binding.rs:129:5 | LL | / match x { LL | | // => LL | | _ => println!("Not an array index start"), LL | | } - | |_____^ help: consider using the match body instead: `println!("Not an array index start");` + | |_____^ help: consider using the match body instead: `println!("Not an array index start")` error: this assignment could be simplified - --> $DIR/match_single_binding.rs:134:5 + --> $DIR/match_single_binding.rs:138:5 | LL | / val = match val.split_at(idx) { LL | | (pre, suf) => { @@ -197,7 +197,7 @@ LL ~ }; | error: this match could be replaced by its scrutinee and body - --> $DIR/match_single_binding.rs:147:16 + --> $DIR/match_single_binding.rs:151:16 | LL | let _ = || match side_effects() { | ________________^ @@ -209,12 +209,12 @@ help: consider using the scrutinee and body instead | LL ~ let _ = || { LL + side_effects(); -LL + println!("Needs curlies"); +LL + println!("Needs curlies") LL ~ }; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:154:5 + --> $DIR/match_single_binding.rs:157:5 | LL | / match r { LL | | x => match x { @@ -238,5 +238,80 @@ LL + }, LL ~ }; | -error: aborting due to 15 previous errors +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:170:5 + | +LL | / match 1 { +LL | | _ => (), +LL | | } + | |_____^ help: consider using the match body instead: `();` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:174:13 + | +LL | let a = match 1 { + | _____________^ +LL | | _ => (), +LL | | }; + | |_____^ help: consider using the match body instead: `()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:178:5 + | +LL | / match 1 { +LL | | _ => side_effects(), +LL | | } + | |_____^ help: consider using the match body instead: `side_effects();` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:182:13 + | +LL | let b = match 1 { + | _____________^ +LL | | _ => side_effects(), +LL | | }; + | |_____^ help: consider using the match body instead: `side_effects()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:186:5 + | +LL | / match 1 { +LL | | _ => println!("1"), +LL | | } + | |_____^ help: consider using the match body instead: `println!("1");` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:190:13 + | +LL | let c = match 1 { + | _____________^ +LL | | _ => println!("1"), +LL | | }; + | |_____^ help: consider using the match body instead: `println!("1")` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:195:9 + | +LL | / match 1 { +LL | | _ => (), +LL | | }, + | |_________^ help: consider using the match body instead: `()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:198:9 + | +LL | / match 1 { +LL | | _ => side_effects(), +LL | | }, + | |_________^ help: consider using the match body instead: `side_effects()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:201:9 + | +LL | / match 1 { +LL | | _ => println!("1"), +LL | | }, + | |_________^ help: consider using the match body instead: `println!("1")` + +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/match_single_binding2.fixed b/src/tools/clippy/tests/ui/match_single_binding2.fixed index 6a7db67e3..e3cf56a42 100644 --- a/src/tools/clippy/tests/ui/match_single_binding2.fixed +++ b/src/tools/clippy/tests/ui/match_single_binding2.fixed @@ -30,7 +30,7 @@ fn main() { #[rustfmt::skip] Some((first, _second)) => { let (a, b) = get_tup(); - println!("a {:?} and b {:?}", a, b); + println!("a {:?} and b {:?}", a, b) }, None => println!("nothing"), } @@ -49,5 +49,5 @@ fn main() { 0 => 1, _ => 2, }; - println!("Single branch"); + println!("Single branch") } diff --git a/src/tools/clippy/tests/ui/match_single_binding2.stderr b/src/tools/clippy/tests/ui/match_single_binding2.stderr index 22bf7d8be..e180b93e7 100644 --- a/src/tools/clippy/tests/ui/match_single_binding2.stderr +++ b/src/tools/clippy/tests/ui/match_single_binding2.stderr @@ -27,7 +27,7 @@ LL | | } help: consider using a `let` statement | LL ~ let (a, b) = get_tup(); -LL + println!("a {:?} and b {:?}", a, b); +LL + println!("a {:?} and b {:?}", a, b) | error: this match could be replaced by its scrutinee and body @@ -61,7 +61,7 @@ LL ~ match x { LL + 0 => 1, LL + _ => 2, LL + }; -LL + println!("Single branch"); +LL + println!("Single branch") | error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed index 874d55843..7fd340173 100644 --- a/src/tools/clippy/tests/ui/mem_replace.fixed +++ b/src/tools/clippy/tests/ui/mem_replace.fixed @@ -90,3 +90,37 @@ fn msrv_1_40() { let mut s = String::from("foo"); let _ = std::mem::take(&mut s); } + +fn issue9824() { + struct Foo<'a>(Option<&'a str>); + impl<'a> std::ops::Deref for Foo<'a> { + type Target = Option<&'a str>; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl<'a> std::ops::DerefMut for Foo<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct Bar { + opt: Option, + val: String, + } + + let mut f = Foo(Some("foo")); + let mut b = Bar { + opt: Some(1), + val: String::from("bar"), + }; + + // replace option with none + let _ = f.0.take(); + let _ = (*f).take(); + let _ = b.opt.take(); + // replace with default + let _ = std::mem::take(&mut b.val); +} diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs index f4f3bff51..fa2903add 100644 --- a/src/tools/clippy/tests/ui/mem_replace.rs +++ b/src/tools/clippy/tests/ui/mem_replace.rs @@ -90,3 +90,37 @@ fn msrv_1_40() { let mut s = String::from("foo"); let _ = std::mem::replace(&mut s, String::default()); } + +fn issue9824() { + struct Foo<'a>(Option<&'a str>); + impl<'a> std::ops::Deref for Foo<'a> { + type Target = Option<&'a str>; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl<'a> std::ops::DerefMut for Foo<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct Bar { + opt: Option, + val: String, + } + + let mut f = Foo(Some("foo")); + let mut b = Bar { + opt: Some(1), + val: String::from("bar"), + }; + + // replace option with none + let _ = std::mem::replace(&mut f.0, None); + let _ = std::mem::replace(&mut *f, None); + let _ = std::mem::replace(&mut b.opt, None); + // replace with default + let _ = std::mem::replace(&mut b.val, String::default()); +} diff --git a/src/tools/clippy/tests/ui/mem_replace.stderr b/src/tools/clippy/tests/ui/mem_replace.stderr index caa127f76..58b57be75 100644 --- a/src/tools/clippy/tests/ui/mem_replace.stderr +++ b/src/tools/clippy/tests/ui/mem_replace.stderr @@ -122,5 +122,29 @@ error: replacing a value of type `T` with `T::default()` is better expressed usi LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` -error: aborting due to 20 previous errors +error: replacing an `Option` with `None` + --> $DIR/mem_replace.rs:121:13 + | +LL | let _ = std::mem::replace(&mut f.0, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` + +error: replacing an `Option` with `None` + --> $DIR/mem_replace.rs:122:13 + | +LL | let _ = std::mem::replace(&mut *f, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` + +error: replacing an `Option` with `None` + --> $DIR/mem_replace.rs:123:13 + | +LL | let _ = std::mem::replace(&mut b.opt, None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` + +error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` + --> $DIR/mem_replace.rs:125:13 + | +LL | let _ = std::mem::replace(&mut b.val, String::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` + +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.rs b/src/tools/clippy/tests/ui/mem_replace_macro.rs index 0c09344b8..3932e7d00 100644 --- a/src/tools/clippy/tests/ui/mem_replace_macro.rs +++ b/src/tools/clippy/tests/ui/mem_replace_macro.rs @@ -1,21 +1,12 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] -#[macro_use] -extern crate macro_rules; - -macro_rules! take { - ($s:expr) => { - std::mem::replace($s, Default::default()) - }; -} - -fn replace_with_default() { - let s = &mut String::from("foo"); - take!(s); - take_external!(s); -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { - replace_with_default(); + let s = &mut String::from("foo"); + inline!(std::mem::replace($s, Default::default())); + external!(std::mem::replace($s, Default::default())); } diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.stderr b/src/tools/clippy/tests/ui/mem_replace_macro.stderr index dd69ab8b5..35dda93da 100644 --- a/src/tools/clippy/tests/ui/mem_replace_macro.stderr +++ b/src/tools/clippy/tests/ui/mem_replace_macro.stderr @@ -1,14 +1,11 @@ error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> $DIR/mem_replace_macro.rs:9:9 + --> $DIR/mem_replace_macro.rs:10:13 | -LL | std::mem::replace($s, Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | take!(s); - | -------- in this macro invocation +LL | inline!(std::mem::replace($s, Default::default())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` - = note: this error originates in the macro `take` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/missing_assert_message.rs b/src/tools/clippy/tests/ui/missing_assert_message.rs new file mode 100644 index 000000000..89404ca88 --- /dev/null +++ b/src/tools/clippy/tests/ui/missing_assert_message.rs @@ -0,0 +1,84 @@ +#![allow(unused)] +#![warn(clippy::missing_assert_message)] + +macro_rules! bar { + ($( $x:expr ),*) => { + foo() + }; +} + +fn main() {} + +// Should trigger warning +fn asserts_without_message() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); +} + +// Should trigger warning +fn asserts_without_message_but_with_macro_calls() { + assert!(bar!(true)); + assert!(bar!(true, false)); + assert_eq!(bar!(true), foo()); + assert_ne!(bar!(true, true), bar!(true)); +} + +// Should trigger warning +fn asserts_with_trailing_commas() { + assert!(foo(),); + assert_eq!(foo(), foo(),); + assert_ne!(foo(), foo(),); + debug_assert!(foo(),); + debug_assert_eq!(foo(), foo(),); + debug_assert_ne!(foo(), foo(),); +} + +// Should not trigger warning +fn asserts_with_message_and_with_macro_calls() { + assert!(bar!(true), "msg"); + assert!(bar!(true, false), "msg"); + assert_eq!(bar!(true), foo(), "msg"); + assert_ne!(bar!(true, true), bar!(true), "msg"); +} + +// Should not trigger warning +fn asserts_with_message() { + assert!(foo(), "msg"); + assert_eq!(foo(), foo(), "msg"); + assert_ne!(foo(), foo(), "msg"); + debug_assert!(foo(), "msg"); + debug_assert_eq!(foo(), foo(), "msg"); + debug_assert_ne!(foo(), foo(), "msg"); +} + +// Should not trigger warning +#[test] +fn asserts_without_message_but_inside_a_test_function() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); +} + +// Should not trigger warning +#[cfg(test)] +mod tests { + fn asserts_without_message_but_inside_a_test_module() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); + } +} + +fn foo() -> bool { + true +} diff --git a/src/tools/clippy/tests/ui/missing_assert_message.stderr b/src/tools/clippy/tests/ui/missing_assert_message.stderr new file mode 100644 index 000000000..ecd038012 --- /dev/null +++ b/src/tools/clippy/tests/ui/missing_assert_message.stderr @@ -0,0 +1,131 @@ +error: assert without any message + --> $DIR/missing_assert_message.rs:14:5 + | +LL | assert!(foo()); + | ^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + = note: `-D clippy::missing-assert-message` implied by `-D warnings` + +error: assert without any message + --> $DIR/missing_assert_message.rs:15:5 + | +LL | assert_eq!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:16:5 + | +LL | assert_ne!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:17:5 + | +LL | debug_assert!(foo()); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:18:5 + | +LL | debug_assert_eq!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:19:5 + | +LL | debug_assert_ne!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:24:5 + | +LL | assert!(bar!(true)); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:25:5 + | +LL | assert!(bar!(true, false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:26:5 + | +LL | assert_eq!(bar!(true), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:27:5 + | +LL | assert_ne!(bar!(true, true), bar!(true)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:32:5 + | +LL | assert!(foo(),); + | ^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:33:5 + | +LL | assert_eq!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:34:5 + | +LL | assert_ne!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:35:5 + | +LL | debug_assert!(foo(),); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:36:5 + | +LL | debug_assert_eq!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:37:5 + | +LL | debug_assert_ne!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: aborting due to 16 previous errors + diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs index 75cace181..e6f88c6e6 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -3,15 +3,15 @@ //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. // aux-build:helper.rs -// aux-build:../../auxiliary/proc_macro_with_span.rs +// aux-build:../../auxiliary/proc_macros.rs #![warn(clippy::missing_const_for_fn)] #![feature(start)] extern crate helper; -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; struct Game; diff --git a/src/tools/clippy/tests/ui/missing_doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs index 590ad63c9..575204894 100644 --- a/src/tools/clippy/tests/ui/missing_doc.rs +++ b/src/tools/clippy/tests/ui/missing_doc.rs @@ -1,5 +1,5 @@ // needs-asm-support -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] // When denying at the crate level, be sure to not get random warnings from the @@ -8,9 +8,9 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::arch::global_asm; type Typedef = String; diff --git a/src/tools/clippy/tests/ui/missing_doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr index d3bef28bf..4e8a49bf1 100644 --- a/src/tools/clippy/tests/ui/missing_doc.stderr +++ b/src/tools/clippy/tests/ui/missing_doc.stderr @@ -6,30 +6,12 @@ LL | type Typedef = String; | = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` -error: missing documentation for a type alias - --> $DIR/missing_doc.rs:17:1 - | -LL | pub type PubTypedef = String; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a module --> $DIR/missing_doc.rs:19:1 | LL | mod module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a module - --> $DIR/missing_doc.rs:20:1 - | -LL | pub mod pub_module_no_dox {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> $DIR/missing_doc.rs:24:1 - | -LL | pub fn foo2() {} - | ^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:25:1 | @@ -69,50 +51,18 @@ error: missing documentation for a variant LL | BarB, | ^^^^ -error: missing documentation for an enum - --> $DIR/missing_doc.rs:44:1 - | -LL | / pub enum PubBaz { -LL | | PubBazA { a: isize }, -LL | | } - | |_^ - -error: missing documentation for a variant - --> $DIR/missing_doc.rs:45:5 - | -LL | PubBazA { a: isize }, - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a struct field - --> $DIR/missing_doc.rs:45:15 - | -LL | PubBazA { a: isize }, - | ^^^^^^^^ - error: missing documentation for a constant --> $DIR/missing_doc.rs:65:1 | LL | const FOO: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a constant - --> $DIR/missing_doc.rs:72:1 - | -LL | pub const FOO4: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a static --> $DIR/missing_doc.rs:74:1 | LL | static BAR: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a static - --> $DIR/missing_doc.rs:81:1 - | -LL | pub static BAR4: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a module --> $DIR/missing_doc.rs:83:1 | @@ -125,35 +75,17 @@ LL | | } LL | | } | |_^ -error: missing documentation for a function - --> $DIR/missing_doc.rs:86:5 - | -LL | pub fn undocumented1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> $DIR/missing_doc.rs:87:5 - | -LL | pub fn undocumented2() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:88:5 | LL | fn undocumented3() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a function - --> $DIR/missing_doc.rs:93:9 - | -LL | pub fn also_undocumented1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:94:9 | LL | fn also_undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.rs b/src/tools/clippy/tests/ui/missing_doc_impl.rs index 0396d1193..e2d49b090 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.rs +++ b/src/tools/clippy/tests/ui/missing_doc_impl.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] #![allow(dead_code)] @@ -7,8 +7,8 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Foo { a: isize, diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr index b410f56e1..111d65469 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr @@ -21,60 +21,12 @@ error: missing documentation for a struct field LL | b: isize, | ^^^^^^^^ -error: missing documentation for a struct - --> $DIR/missing_doc_impl.rs:18:1 - | -LL | / pub struct PubFoo { -LL | | pub a: isize, -LL | | b: isize, -LL | | } - | |_^ - -error: missing documentation for a struct field - --> $DIR/missing_doc_impl.rs:19:5 - | -LL | pub a: isize, - | ^^^^^^^^^^^^ - error: missing documentation for a struct field --> $DIR/missing_doc_impl.rs:20:5 | LL | b: isize, | ^^^^^^^^ -error: missing documentation for a trait - --> $DIR/missing_doc_impl.rs:43:1 - | -LL | / pub trait C { -LL | | fn foo(&self); -LL | | fn foo_with_impl(&self) {} -LL | | } - | |_^ - -error: missing documentation for a method - --> $DIR/missing_doc_impl.rs:44:5 - | -LL | fn foo(&self); - | ^^^^^^^^^^^^^^ - -error: missing documentation for a method - --> $DIR/missing_doc_impl.rs:45:5 - | -LL | fn foo_with_impl(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for an associated type - --> $DIR/missing_doc_impl.rs:55:5 - | -LL | type AssociatedType; - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for an associated type - --> $DIR/missing_doc_impl.rs:56:5 - | -LL | type AssociatedTypeDef = Self; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for an associated function --> $DIR/missing_doc_impl.rs:67:5 | @@ -89,12 +41,6 @@ error: missing documentation for an associated function LL | fn bar() {} | ^^^^^^^^^^^ -error: missing documentation for an associated function - --> $DIR/missing_doc_impl.rs:74:5 - | -LL | pub fn foo() {} - | ^^^^^^^^^^^^^^^ - error: missing documentation for an associated function --> $DIR/missing_doc_impl.rs:78:5 | @@ -103,5 +49,5 @@ LL | | 1 LL | | } | |_____^ -error: aborting due to 15 previous errors +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed index becb9562a..9a47d7c56 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![allow( dead_code, @@ -10,8 +10,8 @@ clippy::unusual_byte_groupings )] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; fn main() { let fail14 = 2_i32; diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs index ee841bcd7..04261cba5 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![allow( dead_code, @@ -10,8 +10,8 @@ clippy::unusual_byte_groupings )] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; fn main() { let fail14 = 2_32; diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs index 4511bc99c..9082f1675 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,12 +1,12 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.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; +extern crate proc_macros; +use proc_macros::external; use core::arch::asm; @@ -113,7 +113,38 @@ unsafe fn read_char_good(ptr: *const u8) -> char { // no lint fn issue10259() { - unsafe_macro!(); + external!(unsafe { + *core::ptr::null::<()>(); + *core::ptr::null::<()>(); + }); +} + +fn _fn_ptr(x: unsafe fn()) { + unsafe { + x(); + x(); + } +} + +fn _assoc_const() { + trait X { + const X: unsafe fn(); + } + fn _f() { + unsafe { + T::X(); + T::X(); + } + } +} + +fn _field_fn_ptr(x: unsafe fn()) { + struct X(unsafe fn()); + let x = X(x); + unsafe { + x.0(); + x.0(); + } } 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 index 303aeb7ae..badc284ec 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -125,5 +125,65 @@ note: raw pointer dereference occurs here LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:123:5 + | +LL | / unsafe { +LL | | x(); +LL | | x(); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:124:9 + | +LL | x(); + | ^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:125:9 + | +LL | x(); + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:134:9 + | +LL | / unsafe { +LL | | T::X(); +LL | | T::X(); +LL | | } + | |_________^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:135:13 + | +LL | T::X(); + | ^^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:136:13 + | +LL | T::X(); + | ^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:144:5 + | +LL | / unsafe { +LL | | x.0(); +LL | | x.0(); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:145:9 + | +LL | x.0(); + | ^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:146:9 + | +LL | x.0(); + | ^^^^^ + +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/must_use_unit.fixed b/src/tools/clippy/tests/ui/must_use_unit.fixed index 6c9aa434a..b7d375ff8 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.fixed +++ b/src/tools/clippy/tests/ui/must_use_unit.fixed @@ -1,11 +1,11 @@ //run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; pub fn must_use_default() {} @@ -22,5 +22,8 @@ fn main() { must_use_with_note(); // We should not lint in external macros - must_use_unit!(); + external!( + #[must_use] + fn foo() {} + ); } diff --git a/src/tools/clippy/tests/ui/must_use_unit.rs b/src/tools/clippy/tests/ui/must_use_unit.rs index 8a395dc28..74d6b4ca8 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.rs +++ b/src/tools/clippy/tests/ui/must_use_unit.rs @@ -1,11 +1,11 @@ //run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; #[must_use] pub fn must_use_default() {} @@ -22,5 +22,8 @@ fn main() { must_use_with_note(); // We should not lint in external macros - must_use_unit!(); + external!( + #[must_use] + fn foo() {} + ); } diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs index ee3a85656..06bb08544 100644 --- a/src/tools/clippy/tests/ui/mut_mut.rs +++ b/src/tools/clippy/tests/ui/mut_mut.rs @@ -1,10 +1,10 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::mut_mut)] #![allow(unused)] #![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn fun(x: &mut &mut u32) -> bool { **x > 0 @@ -21,6 +21,7 @@ macro_rules! mut_ptr { } #[allow(unused_mut, unused_variables)] +#[inline_macros] fn main() { let mut x = &mut &mut 1u32; { @@ -37,7 +38,7 @@ fn main() { ***y + **x; } - let mut z = mut_ptr!(&mut 3u32); + let mut z = inline!(&mut $(&mut 3u32)); } fn issue939() { @@ -55,7 +56,7 @@ fn issue939() { fn issue6922() { // do not lint from an external macro - mut_mut!(); + external!(let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;); } mod issue9035 { diff --git a/src/tools/clippy/tests/ui/mut_mut.stderr b/src/tools/clippy/tests/ui/mut_mut.stderr index 6820a85aa..93b857eb2 100644 --- a/src/tools/clippy/tests/ui/mut_mut.stderr +++ b/src/tools/clippy/tests/ui/mut_mut.stderr @@ -7,54 +7,51 @@ LL | fn fun(x: &mut &mut u32) -> bool { = note: `-D clippy::mut-mut` implied by `-D warnings` error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:25:17 + --> $DIR/mut_mut.rs:26:17 | LL | let mut x = &mut &mut 1u32; | ^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:19:9 + --> $DIR/mut_mut.rs:41:25 | -LL | &mut $p - | ^^^^^^^ -... -LL | let mut z = mut_ptr!(&mut 3u32); - | ------------------- in this macro invocation +LL | let mut z = inline!(&mut $(&mut 3u32)); + | ^ | - = note: this error originates in the macro `mut_ptr` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this expression mutably borrows a mutable reference. Consider reborrowing - --> $DIR/mut_mut.rs:27:21 + --> $DIR/mut_mut.rs:28:21 | LL | let mut y = &mut x; | ^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:31:32 + --> $DIR/mut_mut.rs:32:32 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:31:16 + --> $DIR/mut_mut.rs:32:16 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:37 + --> $DIR/mut_mut.rs:37:37 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:16 + --> $DIR/mut_mut.rs:37:16 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:21 + --> $DIR/mut_mut.rs:37:21 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed index 17f2227ba..86d899bb4 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.fixed +++ b/src/tools/clippy/tests/ui/needless_late_init.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( @@ -10,6 +11,8 @@ clippy::uninlined_format_args )] +extern crate proc_macros; + use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::rc::Rc; @@ -138,6 +141,7 @@ const fn in_const() -> &'static str { a } +#[proc_macros::inline_macros] fn does_not_lint() { let z; if false { @@ -195,35 +199,27 @@ fn does_not_lint() { } y = 3; - macro_rules! assign { - ($i:ident) => { - $i = 1; - }; - } let x; - assign!(x); + inline!($x = 1;); let x; if true { - assign!(x); + inline!($x = 1;); } else { x = 2; } - macro_rules! in_macro { - () => { - let x; - x = 1; + inline!({ + let x; + x = 1; - let x; - if true { - x = 1; - } else { - x = 2; - } - }; - } - in_macro!(); + let x; + if true { + x = 1; + } else { + x = 2; + } + }); // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 let x; diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs index d84457a29..969afb38e 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.rs +++ b/src/tools/clippy/tests/ui/needless_late_init.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( @@ -10,6 +11,8 @@ clippy::uninlined_format_args )] +extern crate proc_macros; + use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::rc::Rc; @@ -138,6 +141,7 @@ const fn in_const() -> &'static str { a } +#[proc_macros::inline_macros] fn does_not_lint() { let z; if false { @@ -195,35 +199,27 @@ fn does_not_lint() { } y = 3; - macro_rules! assign { - ($i:ident) => { - $i = 1; - }; - } let x; - assign!(x); + inline!($x = 1;); let x; if true { - assign!(x); + inline!($x = 1;); } else { x = 2; } - macro_rules! in_macro { - () => { - let x; - x = 1; + inline!({ + let x; + x = 1; - let x; - if true { - x = 1; - } else { - x = 2; - } - }; - } - in_macro!(); + let x; + if true { + x = 1; + } else { + x = 2; + } + }); // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 let x; diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr index 0a256fb4a..eff782f8b 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.stderr +++ b/src/tools/clippy/tests/ui/needless_late_init.stderr @@ -1,5 +1,5 @@ error: unneeded late initialization - --> $DIR/needless_late_init.rs:24:5 + --> $DIR/needless_late_init.rs:27:5 | LL | let a; | ^^^^^^ created here @@ -13,7 +13,7 @@ LL | let a = "zero"; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:27:5 + --> $DIR/needless_late_init.rs:30:5 | LL | let b; | ^^^^^^ created here @@ -27,7 +27,7 @@ LL | let b = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:28:5 + --> $DIR/needless_late_init.rs:31:5 | LL | let c; | ^^^^^^ created here @@ -41,7 +41,7 @@ LL | let c = 2; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:32:5 + --> $DIR/needless_late_init.rs:35:5 | LL | let d: usize; | ^^^^^^^^^^^^^ created here @@ -54,7 +54,7 @@ LL | let d: usize = 1; | ~~~~~~~~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:35:5 + --> $DIR/needless_late_init.rs:38:5 | LL | let e; | ^^^^^^ created here @@ -67,7 +67,7 @@ LL | let e = format!("{}", d); | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:40:5 + --> $DIR/needless_late_init.rs:43:5 | LL | let a; | ^^^^^^ @@ -88,7 +88,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:49:5 + --> $DIR/needless_late_init.rs:52:5 | LL | let b; | ^^^^^^ @@ -109,7 +109,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:56:5 + --> $DIR/needless_late_init.rs:59:5 | LL | let d; | ^^^^^^ @@ -130,7 +130,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:64:5 + --> $DIR/needless_late_init.rs:67:5 | LL | let e; | ^^^^^^ @@ -151,7 +151,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:71:5 + --> $DIR/needless_late_init.rs:74:5 | LL | let f; | ^^^^^^ @@ -167,7 +167,7 @@ LL + 1 => "three", | error: unneeded late initialization - --> $DIR/needless_late_init.rs:77:5 + --> $DIR/needless_late_init.rs:80:5 | LL | let g: usize; | ^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:85:5 + --> $DIR/needless_late_init.rs:88:5 | LL | let x; | ^^^^^^ created here @@ -201,7 +201,7 @@ LL | let x = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:89:5 + --> $DIR/needless_late_init.rs:92:5 | LL | let x; | ^^^^^^ created here @@ -215,7 +215,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:93:5 + --> $DIR/needless_late_init.rs:96:5 | LL | let x; | ^^^^^^ created here @@ -229,7 +229,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:112:5 + --> $DIR/needless_late_init.rs:115:5 | LL | let a; | ^^^^^^ @@ -250,7 +250,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:129:5 + --> $DIR/needless_late_init.rs:132:5 | LL | let a; | ^^^^^^ diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed index f0f1f9298..e6ead69d1 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed +++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( @@ -12,8 +12,8 @@ clippy::get_first )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::inline_macros; fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} @@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks { } } +#[inline_macros] mod in_macro { - macro_rules! local_one_input_macro { - () => { - fn one_input(x: &u8) -> &u8 { - unimplemented!() - } - }; - } + use proc_macros::external; // lint local macro expands to function with needless lifetimes - local_one_input_macro!(); + inline! { + fn one_input(x: &u8) -> &u8 { + unimplemented!() + } + } // no lint on external macro - macro_rules::needless_lifetime!(); - - macro_rules! expanded_lifetime { - ($l:lifetime) => { - fn f<$l>(arg: &$l str) -> &$l str { - arg - } + external! { + fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() } } - expanded_lifetime!('a); + inline! { + fn f<$'a>(arg: &$'a str) -> &$'a str { + arg + } + } } mod issue5787 { diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs index ddfd10430..06eb43050 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.rs +++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( @@ -12,8 +12,8 @@ clippy::get_first )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::inline_macros; fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} @@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks { } } +#[inline_macros] mod in_macro { - macro_rules! local_one_input_macro { - () => { - fn one_input<'a>(x: &'a u8) -> &'a u8 { - unimplemented!() - } - }; - } + use proc_macros::external; // lint local macro expands to function with needless lifetimes - local_one_input_macro!(); + inline! { + fn one_input<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + } // no lint on external macro - macro_rules::needless_lifetime!(); - - macro_rules! expanded_lifetime { - ($l:lifetime) => { - fn f<$l>(arg: &$l str) -> &$l str { - arg - } + external! { + fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() } } - expanded_lifetime!('a); + inline! { + fn f<$'a>(arg: &$'a str) -> &$'a str { + arg + } + } } mod issue5787 { diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr index 4e3c8f20d..86acc4e00 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr +++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr @@ -540,19 +540,16 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:508:13 + --> $DIR/needless_lifetimes.rs:511:9 | -LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | local_one_input_macro!(); - | ------------------------ in this macro invocation +LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `local_one_input_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_in_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 { +LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { +LL + fn one_input(x: &u8) -> &u8 { | error: aborting due to 46 previous errors diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index 0f525dd29..57c08996c 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -307,4 +307,13 @@ mod issue10049 { } } +fn test_match_as_stmt() { + let x = 9; + match x { + 1 => 2, + 2 => return, + _ => 0, + }; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index a1db8375d..7c1feefbe 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -317,4 +317,13 @@ mod issue10049 { } } +fn test_match_as_stmt() { + let x = 9; + match x { + 1 => 2, + 2 => return, + _ => 0, + }; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_update.rs b/src/tools/clippy/tests/ui/needless_update.rs index b93ff048a..4e8517cad 100644 --- a/src/tools/clippy/tests/ui/needless_update.rs +++ b/src/tools/clippy/tests/ui/needless_update.rs @@ -1,5 +1,5 @@ #![warn(clippy::needless_update)] -#![allow(clippy::no_effect)] +#![allow(clippy::no_effect, clippy::unnecessary_struct_initialization)] struct S { pub a: i32, diff --git a/src/tools/clippy/tests/ui/new_ret_no_self.rs b/src/tools/clippy/tests/ui/new_ret_no_self.rs index beec42f08..a2a30c8b9 100644 --- a/src/tools/clippy/tests/ui/new_ret_no_self.rs +++ b/src/tools/clippy/tests/ui/new_ret_no_self.rs @@ -406,7 +406,7 @@ mod issue10041 { struct Bomb; impl Bomb { - // Hidden default generic paramter. + // Hidden default generic parameter. pub fn new() -> impl PartialOrd { 0i32 } diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs index f08eb092e..1e42e1fba 100644 --- a/src/tools/clippy/tests/ui/no_effect.rs +++ b/src/tools/clippy/tests/ui/no_effect.rs @@ -1,7 +1,12 @@ -#![feature(box_syntax, fn_traits, unboxed_closures)] +#![feature(fn_traits, unboxed_closures)] #![warn(clippy::no_effect_underscore_binding)] #![allow(dead_code, path_statements)] -#![allow(clippy::deref_addrof, clippy::redundant_field_names, clippy::uninlined_format_args)] +#![allow( + clippy::deref_addrof, + clippy::redundant_field_names, + clippy::uninlined_format_args, + clippy::unnecessary_struct_initialization +)] struct Unit; struct Tuple(i32); @@ -102,7 +107,6 @@ fn main() { *&42; &6; (5, 6, 7); - box 42; ..; 5..; ..5; diff --git a/src/tools/clippy/tests/ui/no_effect.stderr b/src/tools/clippy/tests/ui/no_effect.stderr index 6a1e636f9..f10f2bcf2 100644 --- a/src/tools/clippy/tests/ui/no_effect.stderr +++ b/src/tools/clippy/tests/ui/no_effect.stderr @@ -1,5 +1,5 @@ error: statement with no effect - --> $DIR/no_effect.rs:92:5 + --> $DIR/no_effect.rs:97:5 | LL | 0; | ^^ @@ -7,157 +7,151 @@ LL | 0; = note: `-D clippy::no-effect` implied by `-D warnings` error: statement with no effect - --> $DIR/no_effect.rs:93:5 + --> $DIR/no_effect.rs:98:5 | LL | s2; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:94:5 + --> $DIR/no_effect.rs:99:5 | LL | Unit; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:95:5 + --> $DIR/no_effect.rs:100:5 | LL | Tuple(0); | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:96:5 + --> $DIR/no_effect.rs:101:5 | LL | Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:97:5 + --> $DIR/no_effect.rs:102:5 | LL | Struct { ..s }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:98:5 + --> $DIR/no_effect.rs:103:5 | LL | Union { a: 0 }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:99:5 + --> $DIR/no_effect.rs:104:5 | LL | Enum::Tuple(0); | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:100:5 + --> $DIR/no_effect.rs:105:5 | LL | Enum::Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:101:5 + --> $DIR/no_effect.rs:106:5 | LL | 5 + 6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:102:5 + --> $DIR/no_effect.rs:107:5 | LL | *&42; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:103:5 + --> $DIR/no_effect.rs:108:5 | LL | &6; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:104:5 + --> $DIR/no_effect.rs:109:5 | LL | (5, 6, 7); | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:105:5 - | -LL | box 42; - | ^^^^^^^ - -error: statement with no effect - --> $DIR/no_effect.rs:106:5 + --> $DIR/no_effect.rs:110:5 | LL | ..; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:107:5 + --> $DIR/no_effect.rs:111:5 | LL | 5..; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:108:5 + --> $DIR/no_effect.rs:112:5 | LL | ..5; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:109:5 + --> $DIR/no_effect.rs:113:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:110:5 + --> $DIR/no_effect.rs:114:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:111:5 + --> $DIR/no_effect.rs:115:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:112:5 + --> $DIR/no_effect.rs:116:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:113:5 + --> $DIR/no_effect.rs:117:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:114:5 + --> $DIR/no_effect.rs:118:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:115:5 + --> $DIR/no_effect.rs:119:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:117:5 + --> $DIR/no_effect.rs:121:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:119:5 + --> $DIR/no_effect.rs:123:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:120:5 + --> $DIR/no_effect.rs:124:5 | LL | let _unused = 1; | ^^^^^^^^^^^^^^^^ @@ -165,22 +159,22 @@ LL | let _unused = 1; = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings` error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:121:5 + --> $DIR/no_effect.rs:125:5 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:122:5 + --> $DIR/no_effect.rs:126:5 | LL | let _duck = Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:123:5 + --> $DIR/no_effect.rs:127:5 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 30 previous errors +error: aborting due to 29 previous errors 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 deleted file mode 100644 index d18dec22a..000000000 --- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.fixed +++ /dev/null @@ -1,48 +0,0 @@ -// 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 index 481e1b6d9..b32e72111 100644 --- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs @@ -1,5 +1,3 @@ -// run-rustfix - #![allow(unused)] #![warn(clippy::no_mangle_with_rust_abi)] 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 index 71517d318..da5d31d8f 100644 --- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr +++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr @@ -1,31 +1,66 @@ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:7:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:5: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` +help: set an ABI + | +LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + | +++++++++++++ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:10:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:8: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)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | pub extern "Rust" 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 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:13: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)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | pub unsafe extern "Rust" 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 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:18: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)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | unsafe extern "Rust" 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 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:21:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | arg_one: u32, @@ -33,13 +68,14 @@ LL | | arg_two: usize, LL | | ) -> u32 { | |________^ | -help: try +help: set an ABI | -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 { +LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + | ++++++++++ +help: or explicitly set the default | +LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + | +++++++++++++ error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs index e9b4367ca..80cc7c60f 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool.rs +++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs @@ -63,3 +63,50 @@ fn issue9428() { println!("foo"); } } + +fn issue_10523() { + macro_rules! a { + ($v:expr) => { + $v.is_some() + }; + } + let x: Option = None; + if !a!(x) {} +} + +fn issue_10523_1() { + macro_rules! a { + ($v:expr) => { + !$v.is_some() + }; + } + let x: Option = None; + if a!(x) {} +} + +fn issue_10523_2() { + macro_rules! a { + () => { + !None::.is_some() + }; + } + if a!() {} +} + +fn issue_10435() { + let x = vec![0]; + let y = vec![1]; + let z = vec![2]; + + // vvv Should not lint + #[allow(clippy::nonminimal_bool)] + if !x.is_empty() && !(y.is_empty() || z.is_empty()) { + println!("{}", line!()); + } + + // vvv Should not lint (#10435 talks about a bug where it lints) + #[allow(clippy::nonminimal_bool)] + if !(x == [0]) { + println!("{}", line!()); + } +} diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.rs b/src/tools/clippy/tests/ui/option_env_unwrap.rs index 0141fb785..9a56cf40d 100644 --- a/src/tools/clippy/tests/ui/option_env_unwrap.rs +++ b/src/tools/clippy/tests/ui/option_env_unwrap.rs @@ -1,24 +1,16 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::option_env_unwrap)] #![allow(clippy::map_flatten)] -#[macro_use] -extern crate macro_rules; - -macro_rules! option_env_unwrap { - ($env: expr) => { - option_env!($env).unwrap() - }; - ($env: expr, $message: expr) => { - option_env!($env).expect($message) - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let _ = option_env!("PATH").unwrap(); let _ = option_env!("PATH").expect("environment variable PATH isn't set"); - let _ = option_env_unwrap!("PATH"); - let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set"); - let _ = option_env_unwrap_external!("PATH"); - let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); + let _ = inline!(option_env!($"PATH").unwrap()); + let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + let _ = external!(option_env!($"PATH").unwrap()); + let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); } diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.stderr b/src/tools/clippy/tests/ui/option_env_unwrap.stderr index bc188a07e..7bba62686 100644 --- a/src/tools/clippy/tests/ui/option_env_unwrap.stderr +++ b/src/tools/clippy/tests/ui/option_env_unwrap.stderr @@ -1,5 +1,5 @@ error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:18:13 + --> $DIR/option_env_unwrap.rs:10:13 | LL | let _ = option_env!("PATH").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = option_env!("PATH").unwrap(); = note: `-D clippy::option-env-unwrap` implied by `-D warnings` error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:19:13 + --> $DIR/option_env_unwrap.rs:11:13 | LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,46 +16,40 @@ LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set = help: consider using the `env!` macro instead error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:10:9 + --> $DIR/option_env_unwrap.rs:12:21 | -LL | option_env!($env).unwrap() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | let _ = option_env_unwrap!("PATH"); - | -------------------------- in this macro invocation +LL | let _ = inline!(option_env!($"PATH").unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:13:9 + --> $DIR/option_env_unwrap.rs:13:21 | -LL | option_env!($env).expect($message) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set"); - | ----------------------------------------------------------------- in this macro invocation +LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:22:13 + --> $DIR/option_env_unwrap.rs:14:13 | -LL | let _ = option_env_unwrap_external!("PATH"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = external!(option_env!($"PATH").unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:23:13 + --> $DIR/option_env_unwrap.rs:15:13 | -LL | let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/overflow_check_conditional.rs b/src/tools/clippy/tests/ui/overflow_check_conditional.rs index 5db75f529..e1e301140 100644 --- a/src/tools/clippy/tests/ui/overflow_check_conditional.rs +++ b/src/tools/clippy/tests/ui/overflow_check_conditional.rs @@ -1,9 +1,6 @@ #![warn(clippy::overflow_check_conditional)] -fn main() { - let a: u32 = 1; - let b: u32 = 2; - let c: u32 = 3; +fn test(a: u32, b: u32, c: u32) { if a + b < a {} if a > a + b {} if a + b < b {} @@ -23,3 +20,7 @@ fn main() { if i > i + j {} if i - j < i {} } + +fn main() { + test(1, 2, 3) +} diff --git a/src/tools/clippy/tests/ui/overflow_check_conditional.stderr b/src/tools/clippy/tests/ui/overflow_check_conditional.stderr index 1b8b146b6..92d1d8ef9 100644 --- a/src/tools/clippy/tests/ui/overflow_check_conditional.stderr +++ b/src/tools/clippy/tests/ui/overflow_check_conditional.stderr @@ -1,5 +1,5 @@ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:7:8 + --> $DIR/overflow_check_conditional.rs:4:8 | LL | if a + b < a {} | ^^^^^^^^^ @@ -7,43 +7,43 @@ LL | if a + b < a {} = note: `-D clippy::overflow-check-conditional` implied by `-D warnings` error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:8:8 + --> $DIR/overflow_check_conditional.rs:5:8 | LL | if a > a + b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:9:8 + --> $DIR/overflow_check_conditional.rs:6:8 | LL | if a + b < b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:10:8 + --> $DIR/overflow_check_conditional.rs:7:8 | LL | if b > a + b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:11:8 + --> $DIR/overflow_check_conditional.rs:8:8 | LL | if a - b > b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:12:8 + --> $DIR/overflow_check_conditional.rs:9:8 | LL | if b < a - b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:13:8 + --> $DIR/overflow_check_conditional.rs:10:8 | LL | if a - b > a {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:14:8 + --> $DIR/overflow_check_conditional.rs:11:8 | LL | if a < a - b {} | ^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs index 86f908f66..538513e91 100644 --- a/src/tools/clippy/tests/ui/print_literal.rs +++ b/src/tools/clippy/tests/ui/print_literal.rs @@ -38,4 +38,8 @@ fn main() { // named args shouldn't change anything either println!("{foo} {bar}", foo = "hello", bar = "world"); println!("{bar} {foo}", foo = "hello", bar = "world"); + + // The string literal from `file!()` has a callsite span that isn't marked as coming from an + // expansion + println!("file: {}", file!()); } diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed index df36a9b84..ee7b998a0 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed @@ -1,16 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] -extern crate macro_rules; - -macro_rules! cast_it { - ($ptr: ident) => { - $ptr.cast::() - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let ptr: *const u32 = &42_u32; let mut_ptr: *mut u32 = &mut 42_u32; @@ -38,10 +34,10 @@ fn main() { let _: *mut i32 = mut_ptr.cast(); // Make sure the lint is triggered inside a macro - let _ = cast_it!(ptr); + let _ = inline!($ptr.cast::()); // Do not lint inside macros from external crates - let _ = macro_rules::ptr_as_ptr_cast!(ptr); + let _ = external!($ptr as *const i32); } #[clippy::msrv = "1.37"] diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs index 302c66462..c88329ce4 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs @@ -1,16 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] -extern crate macro_rules; - -macro_rules! cast_it { - ($ptr: ident) => { - $ptr as *const i32 - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let ptr: *const u32 = &42_u32; let mut_ptr: *mut u32 = &mut 42_u32; @@ -38,10 +34,10 @@ fn main() { let _: *mut i32 = mut_ptr as _; // Make sure the lint is triggered inside a macro - let _ = cast_it!(ptr); + let _ = inline!($ptr as *const i32); // Do not lint inside macros from external crates - let _ = macro_rules::ptr_as_ptr_cast!(ptr); + let _ = external!($ptr as *const i32); } #[clippy::msrv = "1.37"] diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr index a68e1cab6..78d733994 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr @@ -1,5 +1,5 @@ error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:18:13 + --> $DIR/ptr_as_ptr.rs:14:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` @@ -7,48 +7,45 @@ LL | let _ = ptr as *const i32; = note: `-D clippy::ptr-as-ptr` implied by `-D warnings` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:19:13 + --> $DIR/ptr_as_ptr.rs:15:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:24:17 + --> $DIR/ptr_as_ptr.rs:20:17 | LL | let _ = *ptr_ptr as *const i32; | ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:37:25 + --> $DIR/ptr_as_ptr.rs:33:25 | LL | let _: *const i32 = ptr as *const _; | ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:38:23 + --> $DIR/ptr_as_ptr.rs:34:23 | LL | let _: *mut i32 = mut_ptr as _; | ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:10:9 + --> $DIR/ptr_as_ptr.rs:37:21 | -LL | $ptr as *const i32 - | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` -... -LL | let _ = cast_it!(ptr); - | ------------- in this macro invocation +LL | let _ = inline!($ptr as *const i32); + | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` | - = note: this error originates in the macro `cast_it` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:62:13 + --> $DIR/ptr_as_ptr.rs:58:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:63:13 + --> $DIR/ptr_as_ptr.rs:59:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` diff --git a/src/tools/clippy/tests/ui/redundant_async_block.fixed b/src/tools/clippy/tests/ui/redundant_async_block.fixed new file mode 100644 index 000000000..ad96993c4 --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_async_block.fixed @@ -0,0 +1,193 @@ +// run-rustfix + +#![allow(unused, clippy::manual_async_fn)] +#![warn(clippy::redundant_async_block)] + +use std::future::Future; + +async fn func1(n: usize) -> usize { + n + 1 +} + +async fn func2() -> String { + let s = String::from("some string"); + let f = async { (*s).to_owned() }; + let x = f; + x.await +} + +fn main() { + let fut1 = async { 17 }; + // Lint + let fut2 = fut1; + + let fut1 = async { 25 }; + // Lint + let fut2 = fut1; + + // Lint + let fut = async { 42 }; + + // Do not lint: not a single expression + let fut = async { + func1(10).await; + func2().await + }; + + // Do not lint: expression contains `.await` + let fut = async { func1(func2().await.len()).await }; +} + +#[allow(clippy::let_and_return)] +fn capture_local() -> impl Future { + let fut = async { 17 }; + // Lint + fut +} + +fn capture_local_closure(s: &str) -> impl Future { + let f = move || std::future::ready(s); + // Do not lint: `f` would not live long enough + async move { f().await } +} + +#[allow(clippy::let_and_return)] +fn capture_arg(s: &str) -> impl Future { + let fut = async move { s }; + // Lint + fut +} + +fn capture_future_arg(f: impl Future) -> impl Future { + // Lint + f +} + +fn capture_func_result(f: FN) -> impl Future +where + F: Future, + FN: FnOnce() -> F, +{ + // Do not lint, as f() would be evaluated prematurely + async { f().await } +} + +fn double_future(f: impl Future>) -> impl Future { + // Do not lint, we will get a `.await` outside a `.async` + async { f.await.await } +} + +fn await_in_async(f: F) -> impl Future +where + F: FnOnce() -> R, + R: Future, +{ + // Lint + async { f().await + 1 } +} + +#[derive(Debug, Clone)] +struct F {} + +impl F { + async fn run(&self) {} +} + +pub async fn run() { + let f = F {}; + let c = f.clone(); + // Do not lint: `c` would not live long enough + spawn(async move { c.run().await }); + let _f = f; +} + +fn spawn(_: F) {} + +async fn work(_: &str) {} + +fn capture() { + let val = "Hello World".to_owned(); + // Do not lint: `val` would not live long enough + spawn(async { work(&{ val }).await }); +} + +fn await_from_macro() -> impl Future { + macro_rules! mac { + ($e:expr) => { + $e.await + }; + } + // Do not lint: the macro may change in the future + // or return different things depending on its argument + async { mac!(async { 42 }) } +} + +fn async_expr_from_macro() -> impl Future { + macro_rules! mac { + () => { + async { 42 } + }; + } + // Do not lint: the macro may change in the future + async { mac!().await } +} + +fn async_expr_from_macro_deep() -> impl Future { + macro_rules! mac { + () => { + async { 42 } + }; + } + // Do not lint: the macro may change in the future + async { ({ mac!() }).await } +} + +fn all_from_macro() -> impl Future { + macro_rules! mac { + () => { + // Lint + async { 42 } + }; + } + mac!() +} + +fn parts_from_macro() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Do not lint: `$e` might not always be side-effect free + async { $e.await } + }; + } + mac!(async { 42 }) +} + +fn safe_parts_from_macro() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Lint + async { $e } + }; + } + mac!(42) +} + +fn parts_from_macro_deep() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Do not lint: `$e` might not always be side-effect free + async { ($e,).0.await } + }; + } + let f = std::future::ready(42); + mac!(f) +} + +fn await_from_macro_deep() -> impl Future { + macro_rules! mac { + ($e:expr) => {{ $e }.await}; + } + // Do not lint: the macro may change in the future + // or return different things depending on its argument + async { mac!(async { 42 }) } +} diff --git a/src/tools/clippy/tests/ui/redundant_async_block.rs b/src/tools/clippy/tests/ui/redundant_async_block.rs new file mode 100644 index 000000000..7ae235583 --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_async_block.rs @@ -0,0 +1,193 @@ +// run-rustfix + +#![allow(unused, clippy::manual_async_fn)] +#![warn(clippy::redundant_async_block)] + +use std::future::Future; + +async fn func1(n: usize) -> usize { + n + 1 +} + +async fn func2() -> String { + let s = String::from("some string"); + let f = async { (*s).to_owned() }; + let x = async { f.await }; + x.await +} + +fn main() { + let fut1 = async { 17 }; + // Lint + let fut2 = async { fut1.await }; + + let fut1 = async { 25 }; + // Lint + let fut2 = async move { fut1.await }; + + // Lint + let fut = async { async { 42 }.await }; + + // Do not lint: not a single expression + let fut = async { + func1(10).await; + func2().await + }; + + // Do not lint: expression contains `.await` + let fut = async { func1(func2().await.len()).await }; +} + +#[allow(clippy::let_and_return)] +fn capture_local() -> impl Future { + let fut = async { 17 }; + // Lint + async move { fut.await } +} + +fn capture_local_closure(s: &str) -> impl Future { + let f = move || std::future::ready(s); + // Do not lint: `f` would not live long enough + async move { f().await } +} + +#[allow(clippy::let_and_return)] +fn capture_arg(s: &str) -> impl Future { + let fut = async move { s }; + // Lint + async move { fut.await } +} + +fn capture_future_arg(f: impl Future) -> impl Future { + // Lint + async { f.await } +} + +fn capture_func_result(f: FN) -> impl Future +where + F: Future, + FN: FnOnce() -> F, +{ + // Do not lint, as f() would be evaluated prematurely + async { f().await } +} + +fn double_future(f: impl Future>) -> impl Future { + // Do not lint, we will get a `.await` outside a `.async` + async { f.await.await } +} + +fn await_in_async(f: F) -> impl Future +where + F: FnOnce() -> R, + R: Future, +{ + // Lint + async { async { f().await + 1 }.await } +} + +#[derive(Debug, Clone)] +struct F {} + +impl F { + async fn run(&self) {} +} + +pub async fn run() { + let f = F {}; + let c = f.clone(); + // Do not lint: `c` would not live long enough + spawn(async move { c.run().await }); + let _f = f; +} + +fn spawn(_: F) {} + +async fn work(_: &str) {} + +fn capture() { + let val = "Hello World".to_owned(); + // Do not lint: `val` would not live long enough + spawn(async { work(&{ val }).await }); +} + +fn await_from_macro() -> impl Future { + macro_rules! mac { + ($e:expr) => { + $e.await + }; + } + // Do not lint: the macro may change in the future + // or return different things depending on its argument + async { mac!(async { 42 }) } +} + +fn async_expr_from_macro() -> impl Future { + macro_rules! mac { + () => { + async { 42 } + }; + } + // Do not lint: the macro may change in the future + async { mac!().await } +} + +fn async_expr_from_macro_deep() -> impl Future { + macro_rules! mac { + () => { + async { 42 } + }; + } + // Do not lint: the macro may change in the future + async { ({ mac!() }).await } +} + +fn all_from_macro() -> impl Future { + macro_rules! mac { + () => { + // Lint + async { async { 42 }.await } + }; + } + mac!() +} + +fn parts_from_macro() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Do not lint: `$e` might not always be side-effect free + async { $e.await } + }; + } + mac!(async { 42 }) +} + +fn safe_parts_from_macro() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Lint + async { async { $e }.await } + }; + } + mac!(42) +} + +fn parts_from_macro_deep() -> impl Future { + macro_rules! mac { + ($e: expr) => { + // Do not lint: `$e` might not always be side-effect free + async { ($e,).0.await } + }; + } + let f = std::future::ready(42); + mac!(f) +} + +fn await_from_macro_deep() -> impl Future { + macro_rules! mac { + ($e:expr) => {{ $e }.await}; + } + // Do not lint: the macro may change in the future + // or return different things depending on its argument + async { mac!(async { 42 }) } +} diff --git a/src/tools/clippy/tests/ui/redundant_async_block.stderr b/src/tools/clippy/tests/ui/redundant_async_block.stderr new file mode 100644 index 000000000..f3dcb09b4 --- /dev/null +++ b/src/tools/clippy/tests/ui/redundant_async_block.stderr @@ -0,0 +1,74 @@ +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:15:13 + | +LL | let x = async { f.await }; + | ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f` + | + = note: `-D clippy::redundant-async-block` implied by `-D warnings` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:22:16 + | +LL | let fut2 = async { fut1.await }; + | ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:26:16 + | +LL | let fut2 = async move { fut1.await }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:29:15 + | +LL | let fut = async { async { 42 }.await }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:45:5 + | +LL | async move { fut.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:58:5 + | +LL | async move { fut.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:63:5 + | +LL | async { f.await } + | ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:86:5 + | +LL | async { async { f().await + 1 }.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { f().await + 1 }` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:149:13 + | +LL | async { async { 42 }.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` +... +LL | mac!() + | ------ in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:169:13 + | +LL | async { async { $e }.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { $e }` +... +LL | mac!(42) + | -------- in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 10 previous errors + diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed index c0e49ff4c..b987fd2ce 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed @@ -2,6 +2,7 @@ #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] +#![allow(clippy::redundant_async_block)] #![allow(unused)] async fn something() -> u32 { diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs index 9e6e54348..633a2979d 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs @@ -2,6 +2,7 @@ #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] +#![allow(clippy::redundant_async_block)] #![allow(unused)] async fn something() -> u32 { diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr index d71bcba2a..8a1f07716 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr @@ -1,5 +1,5 @@ error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:16:13 + --> $DIR/redundant_closure_call_fixable.rs:17:13 | LL | let a = (|| 42)(); | ^^^^^^^^^ help: try doing something like: `42` @@ -7,7 +7,7 @@ LL | let a = (|| 42)(); = note: `-D clippy::redundant-closure-call` implied by `-D warnings` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:17:13 + --> $DIR/redundant_closure_call_fixable.rs:18:13 | LL | let b = (async || { | _____________^ @@ -27,7 +27,7 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:22:13 + --> $DIR/redundant_closure_call_fixable.rs:23:13 | LL | let c = (|| { | _____________^ @@ -47,13 +47,13 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:27:13 + --> $DIR/redundant_closure_call_fixable.rs:28:13 | LL | let d = (async || something().await)(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:36:13 + --> $DIR/redundant_closure_call_fixable.rs:37:13 | LL | (|| m!())() | ^^^^^^^^^^^ help: try doing something like: `m!()` @@ -64,7 +64,7 @@ LL | m2!(); = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:31:13 + --> $DIR/redundant_closure_call_fixable.rs:32:13 | LL | (|| 0)() | ^^^^^^^^ help: try doing something like: `0` diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed index b88c5d0be..42348df44 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed @@ -69,8 +69,8 @@ fn issue5504() { } fn try_result_opt() -> Result { - while (r#try!(result_opt())).is_some() {} - if (r#try!(result_opt())).is_some() {} + while r#try!(result_opt()).is_some() {} + if r#try!(result_opt()).is_some() {} Ok(42) } diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr index e6afe9eb7..d6a46babb 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr @@ -88,13 +88,13 @@ error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:84:19 | LL | while let Some(_) = r#try!(result_opt()) {} - | ----------^^^^^^^----------------------- help: try this: `while (r#try!(result_opt())).is_some()` + | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:85:16 | LL | if let Some(_) = r#try!(result_opt()) {} - | -------^^^^^^^----------------------- help: try this: `if (r#try!(result_opt())).is_some()` + | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:91:12 diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.fixed b/src/tools/clippy/tests/ui/single_component_path_imports.fixed index 4c40739d6..8c96c4715 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports.fixed +++ b/src/tools/clippy/tests/ui/single_component_path_imports.fixed @@ -2,9 +2,11 @@ #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] +use core; use serde as edres; pub use serde; +use std; macro_rules! m { () => { @@ -17,6 +19,10 @@ fn main() { // False positive #5154, shouldn't trigger lint. m!(); + + // False positive #10549 + let _ = self::std::io::stdout(); + let _ = 0 as self::core::ffi::c_uint; } mod hello_mod { diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.rs b/src/tools/clippy/tests/ui/single_component_path_imports.rs index 9280bab3c..8434bf7ea 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports.rs +++ b/src/tools/clippy/tests/ui/single_component_path_imports.rs @@ -2,9 +2,11 @@ #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] +use core; use regex; use serde as edres; pub use serde; +use std; macro_rules! m { () => { @@ -17,6 +19,10 @@ fn main() { // False positive #5154, shouldn't trigger lint. m!(); + + // False positive #10549 + let _ = self::std::io::stdout(); + let _ = 0 as self::core::ffi::c_uint; } mod hello_mod { diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.stderr b/src/tools/clippy/tests/ui/single_component_path_imports.stderr index 71dcc25d6..d69a86470 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports.stderr +++ b/src/tools/clippy/tests/ui/single_component_path_imports.stderr @@ -1,5 +1,5 @@ error: this import is redundant - --> $DIR/single_component_path_imports.rs:5:1 + --> $DIR/single_component_path_imports.rs:6:1 | LL | use regex; | ^^^^^^^^^^ help: remove it entirely @@ -7,7 +7,7 @@ LL | use regex; = note: `-D clippy::single-component-path-imports` implied by `-D warnings` error: this import is redundant - --> $DIR/single_component_path_imports.rs:23:5 + --> $DIR/single_component_path_imports.rs:29:5 | LL | use regex; | ^^^^^^^^^^ help: remove it entirely diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs index 5d03f77e9..3c86f41f3 100644 --- a/src/tools/clippy/tests/ui/single_match_else.rs +++ b/src/tools/clippy/tests/ui/single_match_else.rs @@ -1,9 +1,9 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::single_match_else)] #![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; enum ExprNode { ExprAddrOf, diff --git a/src/tools/clippy/tests/ui/string_add.rs b/src/tools/clippy/tests/ui/string_add.rs index 16673c01e..20edbe31f 100644 --- a/src/tools/clippy/tests/ui/string_add.rs +++ b/src/tools/clippy/tests/ui/string_add.rs @@ -1,7 +1,7 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; #[warn(clippy::string_add)] #[allow(clippy::string_add_assign, unused)] @@ -22,5 +22,8 @@ fn main() { x = x + 1; assert_eq!(2, x); - string_add!(); + external!({ + let y = "".to_owned(); + let z = y + "..."; + }); } diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed new file mode 100644 index 000000000..b404df94d --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed @@ -0,0 +1,81 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::suspicious_doc_comments)] + +//! Real module documentation. +//! Fake module documentation. +fn baz() {} + +pub mod singleline_outer_doc { + //! This module contains useful functions. + + pub fn bar() {} +} + +pub mod singleline_inner_doc { + //! This module contains useful functions. + + pub fn bar() {} +} + +pub mod multiline_outer_doc { + /*! This module contains useful functions. + */ + + pub fn bar() {} +} + +pub mod multiline_inner_doc { + /*! This module contains useful functions. + */ + + pub fn bar() {} +} + +pub mod multiline_outer_doc2 { + //! This module + //! contains + //! useful functions. + + pub fn bar() {} +} + +pub mod multiline_outer_doc3 { + //! a + //! b + + /// c + pub fn bar() {} +} + +pub mod multiline_outer_doc4 { + //! a + /// b + pub fn bar() {} +} + +pub mod multiline_outer_doc_gap { + //! a + + //! b + pub fn bar() {} +} + +pub mod multiline_outer_doc_commented { + /////! This outer doc comment was commented out. + pub fn bar() {} +} + +pub mod outer_doc_macro { + //! Very cool macro + macro_rules! x { + () => {}; + } +} + +pub mod useless_outer_doc { + //! Huh. + use std::mem; +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs new file mode 100644 index 000000000..46eff51e2 --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs @@ -0,0 +1,81 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::suspicious_doc_comments)] + +//! Real module documentation. +///! Fake module documentation. +fn baz() {} + +pub mod singleline_outer_doc { + ///! This module contains useful functions. + + pub fn bar() {} +} + +pub mod singleline_inner_doc { + //! This module contains useful functions. + + pub fn bar() {} +} + +pub mod multiline_outer_doc { + /**! This module contains useful functions. + */ + + pub fn bar() {} +} + +pub mod multiline_inner_doc { + /*! This module contains useful functions. + */ + + pub fn bar() {} +} + +pub mod multiline_outer_doc2 { + ///! This module + ///! contains + ///! useful functions. + + pub fn bar() {} +} + +pub mod multiline_outer_doc3 { + ///! a + ///! b + + /// c + pub fn bar() {} +} + +pub mod multiline_outer_doc4 { + ///! a + /// b + pub fn bar() {} +} + +pub mod multiline_outer_doc_gap { + ///! a + + ///! b + pub fn bar() {} +} + +pub mod multiline_outer_doc_commented { + /////! This outer doc comment was commented out. + pub fn bar() {} +} + +pub mod outer_doc_macro { + ///! Very cool macro + macro_rules! x { + () => {}; + } +} + +pub mod useless_outer_doc { + ///! Huh. + use std::mem; +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr new file mode 100644 index 000000000..6c167df27 --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr @@ -0,0 +1,114 @@ +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:6:1 + | +LL | ///! Fake module documentation. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::suspicious-doc-comments` implied by `-D warnings` +help: use an inner doc comment to document the parent module or crate + | +LL | //! Fake module documentation. + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:10:5 + | +LL | ///! This module contains useful functions. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use an inner doc comment to document the parent module or crate + | +LL | //! This module contains useful functions. + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:22:5 + | +LL | / /**! This module contains useful functions. +LL | | */ + | |_______^ + | +help: use an inner doc comment to document the parent module or crate + | +LL ~ /*! This module contains useful functions. +LL + */ + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:36:5 + | +LL | / ///! This module +LL | | ///! contains +LL | | ///! useful functions. + | |__________________________^ + | +help: use an inner doc comment to document the parent module or crate + | +LL ~ //! This module +LL ~ //! contains +LL ~ //! useful functions. + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:44:5 + | +LL | / ///! a +LL | | ///! b + | |__________^ + | +help: use an inner doc comment to document the parent module or crate + | +LL ~ //! a +LL ~ //! b + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:52:5 + | +LL | ///! a + | ^^^^^^ + | +help: use an inner doc comment to document the parent module or crate + | +LL | //! a + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:58:5 + | +LL | / ///! a +LL | | +LL | | ///! b + | |__________^ + | +help: use an inner doc comment to document the parent module or crate + | +LL ~ //! a +LL | +LL ~ //! b + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:70:5 + | +LL | ///! Very cool macro + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use an inner doc comment to document the parent module or crate + | +LL | //! Very cool macro + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments.rs:77:5 + | +LL | ///! Huh. + | ^^^^^^^^^ + | +help: use an inner doc comment to document the parent module or crate + | +LL | //! Huh. + | + +error: aborting due to 9 previous errors + diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs new file mode 100644 index 000000000..ad98c7f49 --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs @@ -0,0 +1,16 @@ +#![allow(unused)] +#![warn(clippy::suspicious_doc_comments)] + +///! a +///! b +/// c +///! d +pub fn foo() {} + +///! a +///! b +/// c +///! d +use std::mem; + +fn main() {} diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr new file mode 100644 index 000000000..f89146dad --- /dev/null +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr @@ -0,0 +1,37 @@ +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments_unfixable.rs:4:1 + | +LL | / ///! a +LL | | ///! b +LL | | /// c +LL | | ///! d + | |______^ + | + = note: `-D clippy::suspicious-doc-comments` implied by `-D warnings` +help: use an inner doc comment to document the parent module or crate + | +LL + //! a +LL + //! b +LL | /// c +LL + //! d + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> $DIR/suspicious_doc_comments_unfixable.rs:10:1 + | +LL | / ///! a +LL | | ///! b +LL | | /// c +LL | | ///! d + | |______^ + | +help: use an inner doc comment to document the parent module or crate + | +LL + //! a +LL + //! b +LL | /// c +LL + //! d + | + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed index fa89706a8..9703674d1 100644 --- a/src/tools/clippy/tests/ui/swap.fixed +++ b/src/tools/clippy/tests/ui/swap.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -8,7 +9,8 @@ redundant_semicolons, dead_code, unused_assignments, - unused_variables + unused_variables, + clippy::let_and_return )] struct Foo(u32); @@ -65,19 +67,19 @@ fn xor_swap_locals() { // This is an xor-based swap of local variables. let mut a = 0; let mut b = 1; - std::mem::swap(&mut a, &mut b) + std::mem::swap(&mut a, &mut b); } fn xor_field_swap() { // This is an xor-based swap of fields in a struct. let mut bar = Bar { a: 0, b: 1 }; - std::mem::swap(&mut bar.a, &mut bar.b) + std::mem::swap(&mut bar.a, &mut bar.b); } fn xor_slice_swap() { // This is an xor-based swap of a slice let foo = &mut [1, 2]; - foo.swap(0, 1) + foo.swap(0, 1); } fn xor_no_swap() { @@ -186,3 +188,14 @@ const fn issue_9864(mut u: u32) -> u32 { v = temp; u + v } + +#[macro_use] +extern crate macro_rules; + +const fn issue_10421(x: u32) -> u32 { + issue_10421!(); + let a = x; + let a = a; + let a = a; + a +} diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs index ef8a81c83..a0228065e 100644 --- a/src/tools/clippy/tests/ui/swap.rs +++ b/src/tools/clippy/tests/ui/swap.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -8,7 +9,8 @@ redundant_semicolons, dead_code, unused_assignments, - unused_variables + unused_variables, + clippy::let_and_return )] struct Foo(u32); @@ -215,3 +217,14 @@ const fn issue_9864(mut u: u32) -> u32 { v = temp; u + v } + +#[macro_use] +extern crate macro_rules; + +const fn issue_10421(x: u32) -> u32 { + issue_10421!(); + let a = x; + let a = a; + let a = a; + a +} diff --git a/src/tools/clippy/tests/ui/swap.stderr b/src/tools/clippy/tests/ui/swap.stderr index f0acbfe25..0c2462684 100644 --- a/src/tools/clippy/tests/ui/swap.stderr +++ b/src/tools/clippy/tests/ui/swap.stderr @@ -1,106 +1,106 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:25:5 + --> $DIR/swap.rs:27:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; LL | | bar.b = temp; - | |________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)` + | |_________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` | = note: or maybe you should use `std::mem::replace`? = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:37:5 + --> $DIR/swap.rs:39:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:46:5 + --> $DIR/swap.rs:48:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:65:5 + --> $DIR/swap.rs:67:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:76:5 + --> $DIR/swap.rs:78:5 | LL | / a ^= b; LL | | b ^= a; LL | | a ^= b; - | |___________^ help: try: `std::mem::swap(&mut a, &mut 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:84:5 + --> $DIR/swap.rs:86:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; LL | | bar.a ^= bar.b; - | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut 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:92:5 + --> $DIR/swap.rs:94:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; LL | | foo[0] ^= foo[1]; - | |_____________________^ help: try: `foo.swap(0, 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:121:5 + --> $DIR/swap.rs:123:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; LL | | bar[1][0] = temp; - | |____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0])` + | |_____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0]);` | = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:135:7 + --> $DIR/swap.rs:137:7 | LL | ; let t = a; | _______^ LL | | a = b; LL | | b = t; - | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` + | |__________^ 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 `c.0` and `a` manually - --> $DIR/swap.rs:144:7 + --> $DIR/swap.rs:146:7 | LL | ; let t = c.0; | _______^ LL | | c.0 = a; LL | | a = t; - | |_________^ help: try: `std::mem::swap(&mut c.0, &mut a)` + | |__________^ help: try: `std::mem::swap(&mut c.0, &mut a);` | = 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 + --> $DIR/swap.rs:172:5 | LL | / let t = b; LL | | b = a; LL | | a = t; - | |_________^ help: try: `std::mem::swap(&mut b, &mut a)` + | |__________^ 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:132:5 + --> $DIR/swap.rs:134:5 | LL | / a = b; LL | | b = a; @@ -110,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:141:5 + --> $DIR/swap.rs:143:5 | LL | / c.0 = a; LL | | a = c.0; @@ -119,7 +119,7 @@ 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 + --> $DIR/swap.rs:150:5 | LL | / let a = b; LL | | let b = a; @@ -128,7 +128,7 @@ LL | | let b = a; = 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 + --> $DIR/swap.rs:155:5 | LL | / d = c; LL | | c = d; @@ -137,7 +137,7 @@ LL | | c = d; = 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 + --> $DIR/swap.rs:159:5 | LL | / let a = b; LL | | b = a; @@ -146,12 +146,12 @@ LL | | b = a; = 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:205:5 + --> $DIR/swap.rs:207:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y; LL | | s.0.y = t; - | |_____________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y)` + | |______________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y);` | = note: or maybe you should use `std::mem::replace`? diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.rs b/src/tools/clippy/tests/ui/tests_outside_test_module.rs new file mode 100644 index 000000000..1982b1d01 --- /dev/null +++ b/src/tools/clippy/tests/ui/tests_outside_test_module.rs @@ -0,0 +1,18 @@ +// compile-flags: --test +#![allow(unused)] +#![warn(clippy::tests_outside_test_module)] + +fn main() { + // test code goes here +} + +// Should lint +#[test] +fn my_test() {} + +#[cfg(test)] +mod tests { + // Should not lint + #[test] + fn my_test() {} +} diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.stderr b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr new file mode 100644 index 000000000..125a79d6e --- /dev/null +++ b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr @@ -0,0 +1,11 @@ +error: this function marked with #[test] is outside a #[cfg(test)] module + --> $DIR/tests_outside_test_module.rs:11:1 + | +LL | fn my_test() {} + | ^^^^^^^^^^^^^^^ + | + = note: move it to a testing module marked with #[cfg(test)] + = note: `-D clippy::tests-outside-test-module` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed index 09fb66ca3..174c858a4 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed @@ -1,17 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, unused)] -#[macro_use] -extern crate macro_rules; - -macro_rules! gen_binding { - () => { - let _y = &42; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { // Closures should not warn let y = |ref x| println!("{:?}", x); @@ -38,13 +33,8 @@ fn main() { for ref _x in 0..10 {} // lint in macro - #[allow(unused)] - { - gen_binding!(); - } + inline!(let _y = &42;); // do not lint in external macro - { - ref_arg_binding!(); - } + external!(let ref _y = 42;); } diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs index 9d1f2f810..4b81a0611 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs @@ -1,17 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, unused)] -#[macro_use] -extern crate macro_rules; - -macro_rules! gen_binding { - () => { - let ref _y = 42; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { // Closures should not warn let y = |ref x| println!("{:?}", x); @@ -38,13 +33,8 @@ fn main() { for ref _x in 0..10 {} // lint in macro - #[allow(unused)] - { - gen_binding!(); - } + inline!(let ref _y = 42;); // do not lint in external macro - { - ref_arg_binding!(); - } + external!(let ref _y = 42;); } diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr b/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr index 9c853020a..407c2d9fc 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr @@ -1,5 +1,5 @@ error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:20:9 + --> $DIR/toplevel_ref_arg.rs:15:9 | LL | let ref _x = 1; | ----^^^^^^----- help: try: `let _x = &1;` @@ -7,39 +7,36 @@ LL | let ref _x = 1; = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:22:9 + --> $DIR/toplevel_ref_arg.rs:17:9 | LL | let ref _y: (&_, u8) = (&1, 2); | ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:24:9 + --> $DIR/toplevel_ref_arg.rs:19:9 | LL | let ref _z = 1 + 2; | ----^^^^^^--------- help: try: `let _z = &(1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:26:9 + --> $DIR/toplevel_ref_arg.rs:21:9 | LL | let ref mut _z = 1 + 2; | ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:31:9 + --> $DIR/toplevel_ref_arg.rs:26:9 | LL | let ref _x = vec![1, 2, 3]; | ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:11:13 + --> $DIR/toplevel_ref_arg.rs:36:17 | -LL | let ref _y = 42; - | ----^^^^^^------ help: try: `let _y = &42;` -... -LL | gen_binding!(); - | -------------- in this macro invocation +LL | inline!(let ref _y = 42;); + | ----^^^^^^------ help: try: `let _y = &42;` | - = note: this error originates in the macro `gen_binding` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs index 1a493fbce..2047593e7 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -1,33 +1,27 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] #![allow(unused)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn the_answer(ref mut x: u8) { *x = 42; } -macro_rules! gen_function { - () => { - fn fun_example(ref _x: usize) {} - }; -} - +#[inline_macros] fn main() { let mut x = 0; the_answer(x); // lint in macro - #[allow(unused)] - { - gen_function!(); + inline! { + fn fun_example(ref _x: usize) {} } // do not lint in external macro - { - ref_arg_function!(); + external! { + fn fun_example2(ref _x: usize) {} } } diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr index e97011c7f..7307bd599 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr @@ -7,15 +7,12 @@ LL | fn the_answer(ref mut x: u8) { = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` error: `ref` directly on a function argument is ignored. Consider using a reference type instead - --> $DIR/toplevel_ref_arg_non_rustfix.rs:15:24 + --> $DIR/toplevel_ref_arg_non_rustfix.rs:20:24 | LL | fn fun_example(ref _x: usize) {} | ^^^^^^ -... -LL | gen_function!(); - | --------------- in this macro invocation | - = note: this error originates in the macro `gen_function` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.rs b/src/tools/clippy/tests/ui/trailing_empty_array.rs index c39b0bcaf..8e3749eef 100644 --- a/src/tools/clippy/tests/ui/trailing_empty_array.rs +++ b/src/tools/clippy/tests/ui/trailing_empty_array.rs @@ -155,7 +155,6 @@ struct TupleStructReprC(i32, [usize; 0]); type NamedTuple = (i32, [usize; 0]); -#[rustfmt::skip] // [rustfmt#4995](https://github.com/rust-lang/rustfmt/issues/4995) struct ConstParamZeroDefault { field: i32, last: [usize; N], @@ -166,7 +165,6 @@ struct ConstParamNoDefault { last: [usize; N], } -#[rustfmt::skip] struct ConstParamNonZeroDefault { field: i32, last: [usize; N], 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 55307506e..cc84ba25b 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 @@ -4,7 +4,7 @@ // would otherwise be responsible for #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] -#![allow(dead_code, unused_unsafe, clippy::borrow_as_ptr)] +#![allow(unused, clippy::borrow_as_ptr)] use std::mem::{size_of, transmute}; @@ -77,3 +77,9 @@ fn cannot_be_expressed_as_pointer_cast(in_param: Single) -> Pair { unsafe { transmute::(in_param) } } + +fn issue_10449() { + fn f() {} + + let _x: u8 = unsafe { *(f as *const u8) }; +} 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 e7360f3f9..aa65ab4dd 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 @@ -4,7 +4,7 @@ // would otherwise be responsible for #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] -#![allow(dead_code, unused_unsafe, clippy::borrow_as_ptr)] +#![allow(unused, clippy::borrow_as_ptr)] use std::mem::{size_of, transmute}; @@ -77,3 +77,9 @@ fn cannot_be_expressed_as_pointer_cast(in_param: Single) -> Pair { unsafe { transmute::(in_param) } } + +fn issue_10449() { + fn f() {} + + let _x: u8 = unsafe { *std::mem::transmute::(f) }; +} 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 e862fcb67..58f5162c7 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 @@ -58,5 +58,11 @@ error: transmute from a reference to a pointer LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8` -error: aborting due to 9 previous errors +error: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead + --> $DIR/transmutes_expressible_as_ptr_casts.rs:84:28 + | +LL | let _x: u8 = unsafe { *std::mem::transmute::(f) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)` + +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/try_err.fixed b/src/tools/clippy/tests/ui/try_err.fixed index 264194419..dc497b169 100644 --- a/src/tools/clippy/tests/ui/try_err.fixed +++ b/src/tools/clippy/tests/ui/try_err.fixed @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::io; use std::task::Poll; @@ -79,36 +79,22 @@ fn nested_error() -> Result { Ok(1) } -// Bad suggestion when in macro (see #6242) -macro_rules! try_validation { - ($e: expr) => {{ - match $e { +#[inline_macros] +fn calling_macro() -> Result { + // macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => return Err(1), } - }}; -} - -macro_rules! ret_one { - () => { - 1 - }; -} - -macro_rules! try_validation_in_macro { - ($e: expr) => {{ - match $e { + ); + // `Err` arg is another macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, - Err(_) => return Err(ret_one!()), + Err(_) => return Err(inline!(1)), } - }}; -} - -fn calling_macro() -> Result { - // macro - try_validation!(Ok::<_, i32>(5)); - // `Err` arg is another macro - try_validation_in_macro!(Ok::<_, i32>(5)); + ); Ok(5) } @@ -121,24 +107,19 @@ fn main() { calling_macro().unwrap(); // We don't want to lint in external macros - try_err!(); -} - -macro_rules! bar { - () => { - String::from("aasdfasdfasdfa") - }; -} - -macro_rules! foo { - () => { - bar!() - }; + external! { + pub fn try_err_fn() -> Result { + let err: i32 = 1; + // To avoid warnings during rustfix + if true { Err(err)? } else { Ok(2) } + } + } } +#[inline_macros] pub fn macro_inside(fail: bool) -> Result { if fail { - return Err(foo!()); + return Err(inline!(inline!(String::from("aasdfasdfasdfa")))); } Ok(0) } diff --git a/src/tools/clippy/tests/ui/try_err.rs b/src/tools/clippy/tests/ui/try_err.rs index bc6979bf4..86aeb75cd 100644 --- a/src/tools/clippy/tests/ui/try_err.rs +++ b/src/tools/clippy/tests/ui/try_err.rs @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::io; use std::task::Poll; @@ -79,36 +79,22 @@ fn nested_error() -> Result { Ok(1) } -// Bad suggestion when in macro (see #6242) -macro_rules! try_validation { - ($e: expr) => {{ - match $e { +#[inline_macros] +fn calling_macro() -> Result { + // macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => Err(1)?, } - }}; -} - -macro_rules! ret_one { - () => { - 1 - }; -} - -macro_rules! try_validation_in_macro { - ($e: expr) => {{ - match $e { + ); + // `Err` arg is another macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, - Err(_) => Err(ret_one!())?, + Err(_) => Err(inline!(1))?, } - }}; -} - -fn calling_macro() -> Result { - // macro - try_validation!(Ok::<_, i32>(5)); - // `Err` arg is another macro - try_validation_in_macro!(Ok::<_, i32>(5)); + ); Ok(5) } @@ -121,24 +107,19 @@ fn main() { calling_macro().unwrap(); // We don't want to lint in external macros - try_err!(); -} - -macro_rules! bar { - () => { - String::from("aasdfasdfasdfa") - }; -} - -macro_rules! foo { - () => { - bar!() - }; + external! { + pub fn try_err_fn() -> Result { + let err: i32 = 1; + // To avoid warnings during rustfix + if true { Err(err)? } else { Ok(2) } + } + } } +#[inline_macros] pub fn macro_inside(fail: bool) -> Result { if fail { - Err(foo!())?; + Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; } Ok(0) } diff --git a/src/tools/clippy/tests/ui/try_err.stderr b/src/tools/clippy/tests/ui/try_err.stderr index 0cb1328fb..4ad0e2e56 100644 --- a/src/tools/clippy/tests/ui/try_err.stderr +++ b/src/tools/clippy/tests/ui/try_err.stderr @@ -29,53 +29,47 @@ LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:87:23 + --> $DIR/try_err.rs:88:23 | LL | Err(_) => Err(1)?, | ^^^^^^^ help: try this: `return Err(1)` -... -LL | try_validation!(Ok::<_, i32>(5)); - | -------------------------------- in this macro invocation | - = note: this error originates in the macro `try_validation` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:102:23 + --> $DIR/try_err.rs:95:23 | -LL | Err(_) => Err(ret_one!())?, - | ^^^^^^^^^^^^^^^^ help: try this: `return Err(ret_one!())` -... -LL | try_validation_in_macro!(Ok::<_, i32>(5)); - | ----------------------------------------- in this macro invocation +LL | Err(_) => Err(inline!(1))?, + | ^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(1))` | - = note: this error originates in the macro `try_validation_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:141:9 + --> $DIR/try_err.rs:122:9 | -LL | Err(foo!())?; - | ^^^^^^^^^^^^ help: try this: `return Err(foo!())` +LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:148:9 + --> $DIR/try_err.rs:129:9 | LL | Err(io::ErrorKind::WriteZero)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:150:9 + --> $DIR/try_err.rs:131:9 | LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:158:9 + --> $DIR/try_err.rs:139:9 | LL | Err(io::ErrorKind::NotFound)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:167:16 + --> $DIR/try_err.rs:148:16 | LL | return Err(42)?; | ^^^^^^^^ help: try this: `Err(42)` diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs index 211317317..c996de894 100644 --- a/src/tools/clippy/tests/ui/uninit.rs +++ b/src/tools/clippy/tests/ui/uninit.rs @@ -1,15 +1,17 @@ #![feature(stmt_expr_attributes)] #![allow(clippy::let_unit_value, invalid_value)] -use std::mem::{self, MaybeUninit}; +use std::mem::MaybeUninit; + +union MyOwnMaybeUninit { + value: u8, + uninit: (), +} fn main() { let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; - // edge case: For now we lint on empty arrays - let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; - - // edge case: For now we accept unit tuples + // This is OK, because ZSTs do not contain data. let _: () = unsafe { MaybeUninit::uninit().assume_init() }; // This is OK, because `MaybeUninit` allows uninitialized data. @@ -21,6 +23,31 @@ fn main() { // This is OK, because all constitutent types are uninit-compatible. let _: (MaybeUninit, [MaybeUninit; 2]) = unsafe { MaybeUninit::uninit().assume_init() }; + // This is OK, because our own MaybeUninit is just as fine as the one from core. + let _: MyOwnMaybeUninit = unsafe { MaybeUninit::uninit().assume_init() }; + + // This is OK, because empty arrays don't contain data. + let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; + // Was a false negative. - let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() }; + let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; + + polymorphic::<()>(); + polymorphic_maybe_uninit_array::<10>(); + polymorphic_maybe_uninit::(); + + fn polymorphic() { + // We are conservative around polymorphic types. + let _: T = unsafe { MaybeUninit::uninit().assume_init() }; + } + + fn polymorphic_maybe_uninit_array() { + // While the type is polymorphic, MaybeUninit is not. + let _: [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; + } + + fn polymorphic_maybe_uninit() { + // The entire type is polymorphic, but it's wrapped in a MaybeUninit. + let _: MaybeUninit = unsafe { MaybeUninit::uninit().assume_init() }; + } } diff --git a/src/tools/clippy/tests/ui/uninit.stderr b/src/tools/clippy/tests/ui/uninit.stderr index 15ef23494..248de56da 100644 --- a/src/tools/clippy/tests/ui/uninit.stderr +++ b/src/tools/clippy/tests/ui/uninit.stderr @@ -1,5 +1,5 @@ error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:7:29 + --> $DIR/uninit.rs:12:29 | LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,16 +7,16 @@ LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; = note: `#[deny(clippy::uninit_assumed_init)]` on by default error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:10:31 + --> $DIR/uninit.rs:33:29 | -LL | let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:25:29 + --> $DIR/uninit.rs:41:29 | -LL | let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _: T = unsafe { MaybeUninit::uninit().assume_init() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/uninit_vec.rs b/src/tools/clippy/tests/ui/uninit_vec.rs index 194e4fc15..79effc82f 100644 --- a/src/tools/clippy/tests/ui/uninit_vec.rs +++ b/src/tools/clippy/tests/ui/uninit_vec.rs @@ -7,6 +7,11 @@ struct MyVec { vec: Vec, } +union MyOwnMaybeUninit { + value: u8, + uninit: (), +} + fn main() { // with_capacity() -> set_len() should be detected let mut vec: Vec = Vec::with_capacity(1000); @@ -97,4 +102,34 @@ fn main() { unsafe { vec.set_len(0); } + + // ZSTs should not be detected + let mut vec: Vec<()> = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + + // unions should not be detected + let mut vec: Vec = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + + polymorphic::<()>(); + + fn polymorphic() { + // We are conservative around polymorphic types. + let mut vec: Vec = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + } + + fn poly_maybe_uninit() { + // We are conservative around polymorphic types. + let mut vec: Vec> = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + } } diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr index 77fc689f0..9cdf0c95a 100644 --- a/src/tools/clippy/tests/ui/uninit_vec.stderr +++ b/src/tools/clippy/tests/ui/uninit_vec.stderr @@ -1,5 +1,5 @@ error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:12:5 + --> $DIR/uninit_vec.rs:17:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | vec.set_len(200); = note: `-D clippy::uninit-vec` implied by `-D warnings` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:18:5 + --> $DIR/uninit_vec.rs:23:5 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:24:5 + --> $DIR/uninit_vec.rs:29:5 | LL | let mut vec: Vec = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:30:5 + --> $DIR/uninit_vec.rs:35:5 | LL | let mut vec: Vec = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:35:5 + --> $DIR/uninit_vec.rs:40:5 | LL | let mut vec: Vec = Vec::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:49:5 + --> $DIR/uninit_vec.rs:54:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:58:5 + --> $DIR/uninit_vec.rs:63:5 | LL | my_vec.vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:63:5 + --> $DIR/uninit_vec.rs:68:5 | LL | my_vec.vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:42:9 + --> $DIR/uninit_vec.rs:47:9 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:45:9 + --> $DIR/uninit_vec.rs:50:9 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ @@ -101,5 +101,16 @@ LL | vec.set_len(200); | = help: initialize the buffer or wrap the content in `MaybeUninit` -error: aborting due to 10 previous errors +error: calling `set_len()` immediately after reserving a buffer creates uninitialized values + --> $DIR/uninit_vec.rs:122:9 + | +LL | let mut vec: Vec = Vec::with_capacity(1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { +LL | vec.set_len(10); + | ^^^^^^^^^^^^^^^ + | + = help: initialize the buffer or wrap the content in `MaybeUninit` + +error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed index cbd5cc5fc..3122081a4 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed @@ -1,11 +1,11 @@ -// aux-build:proc_macro_with_span.rs +// aux-build:proc_macros.rs // run-rustfix #![warn(clippy::uninlined_format_args)] -#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] +#![allow(named_arguments_used_positionally, unused)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; macro_rules! no_param_str { () => { @@ -119,7 +119,7 @@ fn tester(fn_arg: i32) { println!("Width = {local_i32}, value with width = {local_f64:local_i32$}"); println!("{local_i32:width$.prec$}"); println!("{width:width$.prec$}"); - println!("{}", format!("{local_i32}")); + println!("{}", format!("{}", local_i32)); my_println!("{}", local_i32); my_println_args!("{}", local_i32); @@ -178,3 +178,87 @@ fn _meets_msrv() { fn _do_not_fire() { println!("{:?}", None::<()>); } + +macro_rules! _internal { + ($($args:tt)*) => { + println!("{}", format_args!($($args)*)) + }; +} + +macro_rules! my_println2 { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!($($args)+) + } + }}; +} + +macro_rules! my_println2_args { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!("foo: {}", format_args!($($args)+)) + } + }}; +} + +macro_rules! my_concat { + ($fmt:literal $(, $e:expr)*) => { + println!(concat!("ERROR: ", $fmt), $($e,)*) + } +} + +macro_rules! my_good_macro { + ($fmt:literal $(, $e:expr)* $(,)?) => { + println!($fmt $(, $e)*) + } +} + +macro_rules! my_bad_macro { + ($fmt:literal, $($e:expr),*) => { + println!($fmt, $($e,)*) + } +} + +macro_rules! my_bad_macro2 { + ($fmt:literal) => { + let s = $fmt.clone(); + println!("{}", s); + }; + ($fmt:literal, $($e:expr)+) => { + println!($fmt, $($e,)*) + }; +} + +// This abomination was suggested by @Alexendoo, may the Rust gods have mercy on their soul... +// https://github.com/rust-lang/rust-clippy/pull/9948#issuecomment-1327965962 +macro_rules! used_twice { + ( + large = $large:literal, + small = $small:literal, + $val:expr, + ) => { + if $val < 5 { + println!($small, $val); + } else { + println!($large, $val); + } + }; +} + +fn tester2() { + let local_i32 = 1; + my_println2_args!(true, "{}", local_i32); + my_println2!(true, "{}", local_i32); + my_concat!("{}", local_i32); + my_good_macro!("{}", local_i32); + my_good_macro!("{}", local_i32,); + + // FIXME: Broken false positives, currently unhandled + my_bad_macro!("{}", local_i32); + my_bad_macro2!("{}", local_i32); + used_twice! { + large = "large value: {}", + small = "small value: {}", + local_i32, + }; +} diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs index cf0ea5be4..b153ef256 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.rs +++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs @@ -1,11 +1,11 @@ -// aux-build:proc_macro_with_span.rs +// aux-build:proc_macros.rs // run-rustfix #![warn(clippy::uninlined_format_args)] -#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] +#![allow(named_arguments_used_positionally, unused)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; macro_rules! no_param_str { () => { @@ -183,3 +183,87 @@ fn _meets_msrv() { fn _do_not_fire() { println!("{:?}", None::<()>); } + +macro_rules! _internal { + ($($args:tt)*) => { + println!("{}", format_args!($($args)*)) + }; +} + +macro_rules! my_println2 { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!($($args)+) + } + }}; +} + +macro_rules! my_println2_args { + ($target:expr, $($args:tt)+) => {{ + if $target { + _internal!("foo: {}", format_args!($($args)+)) + } + }}; +} + +macro_rules! my_concat { + ($fmt:literal $(, $e:expr)*) => { + println!(concat!("ERROR: ", $fmt), $($e,)*) + } +} + +macro_rules! my_good_macro { + ($fmt:literal $(, $e:expr)* $(,)?) => { + println!($fmt $(, $e)*) + } +} + +macro_rules! my_bad_macro { + ($fmt:literal, $($e:expr),*) => { + println!($fmt, $($e,)*) + } +} + +macro_rules! my_bad_macro2 { + ($fmt:literal) => { + let s = $fmt.clone(); + println!("{}", s); + }; + ($fmt:literal, $($e:expr)+) => { + println!($fmt, $($e,)*) + }; +} + +// This abomination was suggested by @Alexendoo, may the Rust gods have mercy on their soul... +// https://github.com/rust-lang/rust-clippy/pull/9948#issuecomment-1327965962 +macro_rules! used_twice { + ( + large = $large:literal, + small = $small:literal, + $val:expr, + ) => { + if $val < 5 { + println!($small, $val); + } else { + println!($large, $val); + } + }; +} + +fn tester2() { + let local_i32 = 1; + my_println2_args!(true, "{}", local_i32); + my_println2!(true, "{}", local_i32); + my_concat!("{}", local_i32); + my_good_macro!("{}", local_i32); + my_good_macro!("{}", local_i32,); + + // FIXME: Broken false positives, currently unhandled + my_bad_macro!("{}", local_i32); + my_bad_macro2!("{}", local_i32); + used_twice! { + large = "large value: {}", + small = "small value: {}", + local_i32, + }; +} diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.stderr b/src/tools/clippy/tests/ui/uninlined_format_args.stderr index a12abf8be..dc4af6ef4 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.stderr +++ b/src/tools/clippy/tests/ui/uninlined_format_args.stderr @@ -774,18 +774,6 @@ LL - println!("{:w$.p$}", w = width, p = prec); LL + println!("{width:width$.prec$}"); | -error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:125:20 - | -LL | println!("{}", format!("{}", local_i32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: change this to - | -LL - println!("{}", format!("{}", local_i32)); -LL + println!("{}", format!("{local_i32}")); - | - error: variables can be used directly in the `format!` string --> $DIR/uninlined_format_args.rs:143:5 | @@ -856,5 +844,5 @@ LL - println!("expand='{}'", local_i32); LL + println!("expand='{local_i32}'"); | -error: aborting due to 72 previous errors +error: aborting due to 71 previous errors diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs index 07e70873a..674ae4f1d 100644 --- a/src/tools/clippy/tests/ui/unit_arg.rs +++ b/src/tools/clippy/tests/ui/unit_arg.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow( @@ -13,9 +13,9 @@ clippy::unused_unit )] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::fmt::Debug; fn foo(t: T) { diff --git a/src/tools/clippy/tests/ui/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs new file mode 100644 index 000000000..fe60d9297 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs @@ -0,0 +1,60 @@ +#![warn(clippy::unnecessary_box_returns)] + +trait Bar { + // lint + fn baz(&self) -> Box; +} + +pub struct Foo {} + +impl Bar for Foo { + // don't lint: this is a problem with the trait, not the implementation + fn baz(&self) -> Box { + Box::new(42) + } +} + +impl Foo { + fn baz(&self) -> Box { + // lint + Box::new(13) + } +} + +// lint +fn bxed_usize() -> Box { + Box::new(5) +} + +// lint +fn _bxed_foo() -> Box { + Box::new(Foo {}) +} + +// don't lint: this is exported +pub fn bxed_foo() -> Box { + Box::new(Foo {}) +} + +// don't lint: str is unsized +fn bxed_str() -> Box { + "Hello, world!".to_string().into_boxed_str() +} + +// don't lint: function contains the word, "box" +fn boxed_usize() -> Box { + Box::new(7) +} + +// don't lint: this has an unspecified return type +fn default() {} + +// don't lint: this doesn't return a Box +fn string() -> String { + String::from("Hello, world") +} + +fn main() { + // don't lint: this is a closure + let a = || -> Box { Box::new(5) }; +} diff --git a/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr b/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr new file mode 100644 index 000000000..b17512c10 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr @@ -0,0 +1,35 @@ +error: boxed return of the sized type `usize` + --> $DIR/unnecessary_box_returns.rs:5:22 + | +LL | fn baz(&self) -> Box; + | ^^^^^^^^^^ help: try: `usize` + | + = help: changing this also requires a change to the return expressions in this function + = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings` + +error: boxed return of the sized type `usize` + --> $DIR/unnecessary_box_returns.rs:18:22 + | +LL | fn baz(&self) -> Box { + | ^^^^^^^^^^ help: try: `usize` + | + = help: changing this also requires a change to the return expressions in this function + +error: boxed return of the sized type `usize` + --> $DIR/unnecessary_box_returns.rs:25:20 + | +LL | fn bxed_usize() -> Box { + | ^^^^^^^^^^ help: try: `usize` + | + = help: changing this also requires a change to the return expressions in this function + +error: boxed return of the sized type `Foo` + --> $DIR/unnecessary_box_returns.rs:30:19 + | +LL | fn _bxed_foo() -> Box { + | ^^^^^^^^ help: try: `Foo` + | + = help: changing this also requires a change to the return expressions in this function + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed index 22e9bd8bd..3b93800f8 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Deep(Option); diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs index 8726d84a2..2851c0c51 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Deep(Option); diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed index d37163570..b046694f8 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed @@ -1,7 +1,12 @@ // run-rustfix -#![feature(box_syntax)] -#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] +#![allow( + clippy::deref_addrof, + dead_code, + unused, + clippy::no_effect, + clippy::unnecessary_struct_initialization +)] #![warn(clippy::unnecessary_operation)] struct Tuple(i32); @@ -59,7 +64,6 @@ fn main() { 5;6;get_number(); get_number(); get_number(); - get_number(); 5;get_number(); 42;get_number(); assert!([42, 55].len() > get_usize()); diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs index a14fd4bca..9ed9679e9 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.rs +++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs @@ -1,7 +1,12 @@ // run-rustfix -#![feature(box_syntax)] -#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] +#![allow( + clippy::deref_addrof, + dead_code, + unused, + clippy::no_effect, + clippy::unnecessary_struct_initialization +)] #![warn(clippy::unnecessary_operation)] struct Tuple(i32); @@ -57,7 +62,6 @@ fn main() { *&get_number(); &get_number(); (5, 6, get_number()); - box get_number(); get_number()..; ..get_number(); 5..get_number(); diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.stderr b/src/tools/clippy/tests/ui/unnecessary_operation.stderr index f66d08ecb..a1d0d9399 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_operation.stderr @@ -1,5 +1,5 @@ error: unnecessary operation - --> $DIR/unnecessary_operation.rs:51:5 + --> $DIR/unnecessary_operation.rs:56:5 | LL | Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` @@ -7,109 +7,103 @@ LL | Tuple(get_number()); = note: `-D clippy::unnecessary-operation` implied by `-D warnings` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:52:5 + --> $DIR/unnecessary_operation.rs:57:5 | LL | Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:53:5 + --> $DIR/unnecessary_operation.rs:58:5 | LL | Struct { ..get_struct() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:54:5 + --> $DIR/unnecessary_operation.rs:59:5 | LL | Enum::Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:55:5 + --> $DIR/unnecessary_operation.rs:60:5 | LL | Enum::Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:56:5 + --> $DIR/unnecessary_operation.rs:61:5 | LL | 5 + get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:57:5 + --> $DIR/unnecessary_operation.rs:62:5 | LL | *&get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:58:5 + --> $DIR/unnecessary_operation.rs:63:5 | LL | &get_number(); | ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:59:5 + --> $DIR/unnecessary_operation.rs:64:5 | LL | (5, 6, get_number()); | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:60:5 - | -LL | box get_number(); - | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` - -error: unnecessary operation - --> $DIR/unnecessary_operation.rs:61:5 + --> $DIR/unnecessary_operation.rs:65:5 | LL | get_number()..; | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:62:5 + --> $DIR/unnecessary_operation.rs:66:5 | LL | ..get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:63:5 + --> $DIR/unnecessary_operation.rs:67:5 | LL | 5..get_number(); | ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:64:5 + --> $DIR/unnecessary_operation.rs:68:5 | LL | [42, get_number()]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:65:5 + --> $DIR/unnecessary_operation.rs:69:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:66:5 + --> $DIR/unnecessary_operation.rs:70:5 | LL | (42, get_number()).1; | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:67:5 + --> $DIR/unnecessary_operation.rs:71:5 | LL | [get_number(); 55]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:68:5 + --> $DIR/unnecessary_operation.rs:72:5 | LL | [42; 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:69:5 + --> $DIR/unnecessary_operation.rs:73:5 | LL | / { LL | | get_number() @@ -117,12 +111,12 @@ LL | | }; | |______^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:72:5 + --> $DIR/unnecessary_operation.rs:76:5 | LL | / FooString { LL | | s: String::from("blah"), LL | | }; | |______^ help: statement can be reduced to: `String::from("blah");` -error: aborting due to 20 previous errors +error: aborting due to 19 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed new file mode 100644 index 000000000..b47129e4a --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::unnecessary_struct_initialization)] + +struct S { + f: String, +} + +#[derive(Clone, Copy)] +struct T { + f: u32, +} + +struct U { + f: u32, +} + +impl Clone for U { + fn clone(&self) -> Self { + // Do not lint: `Self` does not implement `Copy` + Self { ..*self } + } +} + +#[derive(Copy)] +struct V { + f: u32, +} + +impl Clone for V { + fn clone(&self) -> Self { + // Lint: `Self` implements `Copy` + *self + } +} + +fn main() { + // Should lint: `a` would be consumed anyway + let a = S { f: String::from("foo") }; + let mut b = a; + + // Should lint: `b` would be consumed, and is mutable + let c = &mut b; + + // Should not lint as `d` is not mutable + let d = S { f: String::from("foo") }; + let e = &mut S { ..d }; + + // Should lint as `f` would be consumed anyway + let f = S { f: String::from("foo") }; + let g = &f; + + // Should lint: the result of an expression is mutable + let h = &mut *Box::new(S { f: String::from("foo") }); + + // Should not lint: `m` would be both alive and borrowed + let m = T { f: 17 }; + let n = &T { ..m }; + + // Should not lint: `m` should not be modified + let o = &mut T { ..m }; + o.f = 32; + assert_eq!(m.f, 17); + + // Should not lint: `m` should not be modified + let o = &mut T { ..m } as *mut T; + unsafe { &mut *o }.f = 32; + assert_eq!(m.f, 17); + + // Should lint: the result of an expression is mutable and temporary + let p = &mut *Box::new(T { f: 5 }); +} diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs new file mode 100644 index 000000000..63b11c626 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs @@ -0,0 +1,77 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::unnecessary_struct_initialization)] + +struct S { + f: String, +} + +#[derive(Clone, Copy)] +struct T { + f: u32, +} + +struct U { + f: u32, +} + +impl Clone for U { + fn clone(&self) -> Self { + // Do not lint: `Self` does not implement `Copy` + Self { ..*self } + } +} + +#[derive(Copy)] +struct V { + f: u32, +} + +impl Clone for V { + fn clone(&self) -> Self { + // Lint: `Self` implements `Copy` + Self { ..*self } + } +} + +fn main() { + // Should lint: `a` would be consumed anyway + let a = S { f: String::from("foo") }; + let mut b = S { ..a }; + + // Should lint: `b` would be consumed, and is mutable + let c = &mut S { ..b }; + + // Should not lint as `d` is not mutable + let d = S { f: String::from("foo") }; + let e = &mut S { ..d }; + + // Should lint as `f` would be consumed anyway + let f = S { f: String::from("foo") }; + let g = &S { ..f }; + + // Should lint: the result of an expression is mutable + let h = &mut S { + ..*Box::new(S { f: String::from("foo") }) + }; + + // Should not lint: `m` would be both alive and borrowed + let m = T { f: 17 }; + let n = &T { ..m }; + + // Should not lint: `m` should not be modified + let o = &mut T { ..m }; + o.f = 32; + assert_eq!(m.f, 17); + + // Should not lint: `m` should not be modified + let o = &mut T { ..m } as *mut T; + unsafe { &mut *o }.f = 32; + assert_eq!(m.f, 17); + + // Should lint: the result of an expression is mutable and temporary + let p = &mut T { + ..*Box::new(T { f: 5 }) + }; +} diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr new file mode 100644 index 000000000..ca4970577 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr @@ -0,0 +1,46 @@ +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:34:9 + | +LL | Self { ..*self } + | ^^^^^^^^^^^^^^^^ help: replace with: `*self` + | + = note: `-D clippy::unnecessary-struct-initialization` implied by `-D warnings` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:41:17 + | +LL | let mut b = S { ..a }; + | ^^^^^^^^^ help: replace with: `a` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:44:18 + | +LL | let c = &mut S { ..b }; + | ^^^^^^^^^ help: replace with: `b` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:52:14 + | +LL | let g = &S { ..f }; + | ^^^^^^^^^ help: replace with: `f` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:55:18 + | +LL | let h = &mut S { + | __________________^ +LL | | ..*Box::new(S { f: String::from("foo") }) +LL | | }; + | |_____^ help: replace with: `*Box::new(S { f: String::from("foo") })` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:74:18 + | +LL | let p = &mut T { + | __________________^ +LL | | ..*Box::new(T { f: 5 }) +LL | | }; + | |_____^ help: replace with: `*Box::new(T { f: 5 })` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs index c160e31af..431093ab3 100644 --- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs +++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs @@ -1,10 +1,10 @@ -// aux-build:doc_unsafe_macros.rs +// aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] #![warn(clippy::unnecessary_safety_doc)] -#[macro_use] -extern crate doc_unsafe_macros; +extern crate proc_macros; +use proc_macros::external; /// This is has no safety section, and does not need one either pub fn destroy_the_planet() { @@ -129,7 +129,11 @@ macro_rules! very_safe { very_safe!(); // we don't lint code from external macros -undocd_safe!(); +external!( + pub fn vey_oy() { + unimplemented!(); + } +); fn main() {} diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr index 72898c93f..b0f20fdac 100644 --- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr @@ -42,7 +42,7 @@ LL | very_safe!(); = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info) error: docs for safe trait have unnecessary `# Safety` section - --> $DIR/unnecessary_unsafety_doc.rs:147:1 + --> $DIR/unnecessary_unsafety_doc.rs:151:1 | LL | pub trait DocumentedSafeTraitWithImplementationHeader { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/unused_format_specs.fixed b/src/tools/clippy/tests/ui/unused_format_specs.fixed deleted file mode 100644 index 2930722b4..000000000 --- a/src/tools/clippy/tests/ui/unused_format_specs.fixed +++ /dev/null @@ -1,18 +0,0 @@ -// run-rustfix - -#![warn(clippy::unused_format_specs)] -#![allow(unused)] - -fn main() { - let f = 1.0f64; - println!("{}", 1.0); - println!("{f} {f:?}"); - - println!("{}", 1); -} - -fn should_not_lint() { - let f = 1.0f64; - println!("{:.1}", 1.0); - println!("{f:.w$} {f:.*?}", 3, w = 2); -} diff --git a/src/tools/clippy/tests/ui/unused_format_specs.rs b/src/tools/clippy/tests/ui/unused_format_specs.rs deleted file mode 100644 index ee192a000..000000000 --- a/src/tools/clippy/tests/ui/unused_format_specs.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-rustfix - -#![warn(clippy::unused_format_specs)] -#![allow(unused)] - -fn main() { - let f = 1.0f64; - println!("{:.}", 1.0); - println!("{f:.} {f:.?}"); - - println!("{:.}", 1); -} - -fn should_not_lint() { - let f = 1.0f64; - println!("{:.1}", 1.0); - println!("{f:.w$} {f:.*?}", 3, w = 2); -} diff --git a/src/tools/clippy/tests/ui/unused_format_specs.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr deleted file mode 100644 index 7231c17e7..000000000 --- a/src/tools/clippy/tests/ui/unused_format_specs.stderr +++ /dev/null @@ -1,54 +0,0 @@ -error: empty precision specifier has no effect - --> $DIR/unused_format_specs.rs:8:17 - | -LL | println!("{:.}", 1.0); - | ^ - | - = note: a precision specifier is not required to format floats - = note: `-D clippy::unused-format-specs` implied by `-D warnings` -help: remove the `.` - | -LL - println!("{:.}", 1.0); -LL + println!("{}", 1.0); - | - -error: empty precision specifier has no effect - --> $DIR/unused_format_specs.rs:9:18 - | -LL | println!("{f:.} {f:.?}"); - | ^ - | - = note: a precision specifier is not required to format floats -help: remove the `.` - | -LL - println!("{f:.} {f:.?}"); -LL + println!("{f} {f:.?}"); - | - -error: empty precision specifier has no effect - --> $DIR/unused_format_specs.rs:9:24 - | -LL | println!("{f:.} {f:.?}"); - | ^ - | - = note: a precision specifier is not required to format floats -help: remove the `.` - | -LL - println!("{f:.} {f:.?}"); -LL + println!("{f:.} {f:?}"); - | - -error: empty precision specifier has no effect - --> $DIR/unused_format_specs.rs:11:17 - | -LL | println!("{:.}", 1); - | ^ - | -help: remove the `.` - | -LL - println!("{:.}", 1); -LL + println!("{}", 1); - | - -error: aborting due to 4 previous errors - diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr index 9f1890282..cb7156b6b 100644 --- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr @@ -37,11 +37,7 @@ error: format specifiers have no effect on `format_args!()` LL | println!("{:5}.", format_args_from_macro!()); | ^^^^ | -help: for the width to apply consider using `format!()` - --> $DIR/unused_format_specs_unfixable.rs:16:17 - | -LL | println!("{:5}.", format_args_from_macro!()); - | ^ + = help: for the width to apply consider using `format!()` help: if the current behavior is intentional, remove the format specifiers | LL - println!("{:5}.", format_args_from_macro!()); @@ -54,11 +50,7 @@ error: format specifiers have no effect on `format_args!()` LL | println!("{args:5}"); | ^^^^^^^^ | -help: for the width to apply consider using `format!()` - --> $DIR/unused_format_specs_unfixable.rs:19:21 - | -LL | println!("{args:5}"); - | ^ + = help: for the width to apply consider using `format!()` help: if the current behavior is intentional, remove the format specifiers | LL - println!("{args:5}"); diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed index 0a6166571..3ac621731 100644 --- a/src/tools/clippy/tests/ui/use_self.fixed +++ b/src/tools/clippy/tests/ui/use_self.fixed @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +} diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs index 39c2b431f..9dc5d1e3f 100644 --- a/src/tools/clippy/tests/ui/use_self.rs +++ b/src/tools/clippy/tests/ui/use_self.rs @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +} -- cgit v1.2.3