diff --git a/Cargo.lock b/Cargo.lock index 01083d7c43f49..115553f9050a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -658,7 +658,7 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clippy" -version = "0.1.99" +version = "0.1.100" dependencies = [ "anstream 0.6.21", "askama", @@ -683,7 +683,7 @@ dependencies = [ [[package]] name = "clippy_config" -version = "0.1.99" +version = "0.1.100" dependencies = [ "arrayvec", "clippy_utils", @@ -707,7 +707,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.99" +version = "0.1.100" dependencies = [ "arrayvec", "cargo_metadata 0.23.1", @@ -738,7 +738,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.99" +version = "0.1.100" dependencies = [ "arrayvec", "itertools", @@ -1152,7 +1152,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69" [[package]] name = "declare_clippy_lint" -version = "0.1.99" +version = "0.1.100" [[package]] name = "derive-where" diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index de36ddbe1d10f..102a3013b38ad 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -401,12 +401,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Like for trait refs, verify that `dummy_self` did not leak inside default type // parameters. - let references_self = b.projection_term.args.iter().skip(1).any(|arg| { - if arg.walk().any(|arg| arg == dummy_self.into()) { - return true; - } - false - }); + let references_self = b + .projection_term + .args + .iter() + .skip(1) + .any(|arg| arg.walk().any(|arg| arg == dummy_self.into())); if references_self { let guar = tcx .dcx() diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ae20d21ea665f..8d21eae971e7b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -343,11 +343,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> { // Avoid inlining into coroutines, since their `optimized_mir` is used for layout computation, // which can create a cycle, even when no attempt is made to inline the function in the other // direction. - if body.coroutine.is_some() { - return false; - } - - true + body.coroutine.is_none() } #[instrument(level = "debug", skip(self, callee_body))] diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 78ccf04d456a3..ec854e25a6aa2 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -698,12 +698,7 @@ fn try_prove_negated_where_clause<'tcx>( // FIXME: We could use the assumed_wf_types from both impls, I think, // if that wasn't implemented just for LocalDefId, and we'd need to do // the normalization ourselves since this is totally fallible... - let errors = ocx.resolve_regions(CRATE_DEF_ID, param_env, []); - if !errors.is_empty() { - return false; - } - - true + ocx.resolve_regions(CRATE_DEF_ID, param_env, []).is_empty() } /// Compute the `intercrate_ambiguity_causes` for the new solver using diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8b4d02725bb0a..f48621288d69a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -859,12 +859,7 @@ pub fn impossible_clauses<'tcx>(tcx: TyCtxt<'tcx>, clauses: Vec // vs user-written impls to AMBIGUOUS, this may return ambiguity even // with no infer vars. There may also be ways to encounter ambiguity due // to post-mono overflow. - let true_errors = ocx.try_evaluate_obligations(); - if !true_errors.no_errors() { - return true; - } - - false + !ocx.try_evaluate_obligations().no_errors() } fn instantiate_and_check_impossible_clauses<'tcx>( diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 5d188bcd25570..4d52941cd38fe 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -356,13 +356,10 @@ pub(crate) fn is_ci_llvm_available_for_target( ("x86_64-unknown-netbsd", false), ]; - if !supported_platforms.contains(&(&*host_target.triple, asserts)) - && (asserts || !supported_platforms.contains(&(&*host_target.triple, true))) - { - return false; - } - - true + // Check if the host target is available with the requested assertions (true/false), + supported_platforms.contains(&(&*host_target.triple, asserts)) + // if it is not available for the given `asserts`, check if it is available with assertions (superset). + || supported_platforms.contains(&(&*host_target.triple, true)) } #[derive(Clone)] diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 27a400406e144..a04dc3b8afb0d 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -375,11 +375,7 @@ fn ensure_stage1_toolchain_placeholder_exists(stage_path: &str) -> bool { // Take care not to overwrite the file let result = File::options().append(true).create(true).open(&pathbuf); - if result.is_err() { - return false; - } - - true + result.is_ok() } // Used to get the path for `Subcommand::Setup` diff --git a/src/tools/clippy/.github/FUNDING.yml b/src/tools/clippy/.github/FUNDING.yml index 16ac7b6eb9bc9..4268752aca2b9 100644 --- a/src/tools/clippy/.github/FUNDING.yml +++ b/src/tools/clippy/.github/FUNDING.yml @@ -1,2 +1,2 @@ github: rustfoundation -custom: [ "rust-lang.org/funding" ] +custom: [ "https://rust-lang.org/funding" ] diff --git a/src/tools/clippy/.github/deploy.sh b/src/tools/clippy/.github/deploy.sh index 2f062799a3607..724a39db0c58f 100644 --- a/src/tools/clippy/.github/deploy.sh +++ b/src/tools/clippy/.github/deploy.sh @@ -4,6 +4,7 @@ set -ex echo "Removing the current docs for master" rm -rf out/master/ || exit 0 +rm -rf out/main/ || exit 0 echo "Making the docs for master" mkdir out/master/ @@ -12,6 +13,9 @@ cp util/gh-pages/theme.js out/master cp util/gh-pages/script.js out/master cp util/gh-pages/style.css out/master +echo "Copying the docs into the main directory" +cp -Tr out/master/ out/main/ + if [[ -n $TAG_NAME ]]; then echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it" cp -Tr out/master "out/$TAG_NAME" diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md index 3876af9b2f37b..37f5eb09e5247 100644 --- a/src/tools/clippy/CHANGELOG.md +++ b/src/tools/clippy/CHANGELOG.md @@ -6,7 +6,125 @@ document. ## Unreleased / Beta / In Rust Nightly -[b147b68...master](https://github.com/rust-lang/rust-clippy/compare/b147b68...master) +[64c7431...master](https://github.com/rust-lang/rust-clippy/compare/64c7431...master) + +## Rust 1.98 + +Current stable, released 2026-08-20 + +[View all merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2026-05-27T20%3A48%3A30Z..2026-06-25T09%3A21%3A14Z+base%3Amaster) + +### New Lints + +* Added [`unnecessary_unwrap_unchecked`] to `complexity` + [#16252](https://github.com/rust-lang/rust-clippy/pull/16252) +* Added [`chunks_exact_to_as_chunks`] to `style` + [#16931](https://github.com/rust-lang/rust-clippy/pull/16931) +* Added [`by_ref_peekable_peek`] to `suspicious` + [#17042](https://github.com/rust-lang/rust-clippy/pull/17042) +* Added [`with_capacity_zero`] to `pedantic` + [#17192](https://github.com/rust-lang/rust-clippy/pull/17192) +* Added [`manual_isolate_lowest_one`] to `complexity` + [#17037](https://github.com/rust-lang/rust-clippy/pull/17037) +* Added [`for_unbounded_range`] to `suspicious` + [#16257](https://github.com/rust-lang/rust-clippy/pull/16257) +* Added [`unused_async_trait_impl`] to `pedantic` + [#16244](https://github.com/rust-lang/rust-clippy/pull/16244) + +### Moves and Deprecations + +* Moved [`empty_enums`] from `pedantic` to `nursery` + [#17298](https://github.com/rust-lang/rust-clippy/pull/17298) +* Deprecated [`from_iter_instead_of_collect`] + [#17208](https://github.com/rust-lang/rust-clippy/pull/17208) + +### Enhancements + +* [`needless_late_init`] extend to cover grouped assignments, and fix FN for if/match in block expr + [#16746](https://github.com/rust-lang/rust-clippy/pull/16746) +* [`unnecessary_cast`] treat `!` the same as `-`, improving suggestions and precedence handling + [#17278](https://github.com/rust-lang/rust-clippy/pull/17278) +* [`manual_slice_fill`] detect `for` loops over `&mut [T; N]` and suggest `.fill()` + [#16926](https://github.com/rust-lang/rust-clippy/pull/16926) +* [`extra_unused_lifetimes`] detect unused `for<'a>` lifetime bounds + [#17031](https://github.com/rust-lang/rust-clippy/pull/17031) +* [`single_range_in_vec_init`] detect more ranges, including `..end`, `start..`, `start..=end`, + `..=end`, and `..` + [#17146](https://github.com/rust-lang/rust-clippy/pull/17146) +* [`iter_next_slice`] extend lint to support `iter_mut()` + [#17122](https://github.com/rust-lang/rust-clippy/pull/17122) +* [`large_const_arrays`] check nested large arrays + [#17141](https://github.com/rust-lang/rust-clippy/pull/17141) +* [`manual_is_variant_and`] lint `result.ok().is_some_and(f)` + [#17184](https://github.com/rust-lang/rust-clippy/pull/17184) +* [`mem_replace_with_default`] also emit inside macros + [#17191](https://github.com/rust-lang/rust-clippy/pull/17191) +* [`missing_const_for_fn`] lint more cases involving pointer metadata, such as slice lengths + [#17121](https://github.com/rust-lang/rust-clippy/pull/17121) +* [`never_loop`] add notes for non-trivial cases to indicate why a loop is detected as + non-terminating + [#17145](https://github.com/rust-lang/rust-clippy/pull/17145) +* [`double_must_use`] make the lint machine-applicable in the single-attribute case + [#17144](https://github.com/rust-lang/rust-clippy/pull/17144) +* [`result_large_err`] and [`result_unit_err`] fix not triggering on async functions + [#17130](https://github.com/rust-lang/rust-clippy/pull/17130) +* [`unnecessary_lazy_evaluations`] avoid a broken suggestion when the closure has an explicit return + type + [#17216](https://github.com/rust-lang/rust-clippy/pull/17216) +* [`unnecessary_sort_by`] fix the reverse-sort suggestion using the second closure parameter name + instead of the first + [#16868](https://github.com/rust-lang/rust-clippy/pull/16868) +* [`collapsible_match`] fix wrong suggestions when the match body has no braces + [#16749](https://github.com/rust-lang/rust-clippy/pull/16749) +* [`unused_async_trait_impl`] fix suggestions for statements containing `return` + [#17181](https://github.com/rust-lang/rust-clippy/pull/17181) +* [`map_unwrap_or`] avoid suggesting `map_or` when the `unwrap_or` default requires a type adjustment + [#16928](https://github.com/rust-lang/rust-clippy/pull/16928) +* [`doc_markdown`] add common database engines to the whitelist + [#16917](https://github.com/rust-lang/rust-clippy/pull/16917) +* [`std_instead_of_core`] fix MSRV-unaware issues + [#16964](https://github.com/rust-lang/rust-clippy/pull/16964) +* [`extra_unused_type_parameters`] don't suggest an autofix + [#15907](https://github.com/rust-lang/rust-clippy/pull/15907) +* [`extra_unused_lifetimes`] do not lint expanded code + [#17256](https://github.com/rust-lang/rust-clippy/pull/17256) +* [`unnecessary_box_returns`] no longer fires when the boxed type's size depends on generic + parameters, e.g. `Box<[T; N]>` + [#17249](https://github.com/rust-lang/rust-clippy/pull/17249) +* [`inline_trait_bounds`] do not trigger on code automatically derived from procedural macros + [#17131](https://github.com/rust-lang/rust-clippy/pull/17131) +* Fix duplicate diagnostics in `unknown_attribute` and `renamed_builtin_attr` + [#17164](https://github.com/rust-lang/rust-clippy/pull/17164) + +### False Positive Fixes + +* [`manual_option_zip`] don't trigger when the map receiver is a lazily evaluated expression + [#17270](https://github.com/rust-lang/rust-clippy/pull/17270) +* [`std_instead_of_core`] fix FPs for stable items in an unstable module, e.g. `core::io::ErrorKind` + [#16964](https://github.com/rust-lang/rust-clippy/pull/16964) +* [`ref_patterns`] don't trigger on `#[automatically_derived]` annotated code + [#17250](https://github.com/rust-lang/rust-clippy/pull/17250) +* [`needless_borrow`] fix FP for same-name methods, where auto-borrowing might prefer another method + [#17171](https://github.com/rust-lang/rust-clippy/pull/17171) +* [`redundant_closure_call`] fix FP on async closures with early returns + [#17107](https://github.com/rust-lang/rust-clippy/pull/17107) +* [`explicit_counter_loop`] fix FP when the counter is only modified inside the `else` block of a + `let...else` binding + [#17023](https://github.com/rust-lang/rust-clippy/pull/17023) +* [`unnecessary_unwrap_unchecked`] don't trigger inside the `_unchecked` function itself + [#17351](https://github.com/rust-lang/rust-clippy/pull/17351) + +### ICE Fixes + +* [`absurd_extreme_comparisons`] avoid an ICE when const evaluation encounters unsized generic type + args + [#16976](https://github.com/rust-lang/rust-clippy/pull/16976) +* [`uninit_vec`] fix an OOM panic on large types + [#17205](https://github.com/rust-lang/rust-clippy/pull/17205) +* Fix an ICE when the `clippy::author` attribute is applied to an item + [#17245](https://github.com/rust-lang/rust-clippy/pull/17245) +* [`unnecessary_unwrap_unchecked`] fix ICE when resolving a path to a local variable + [#17353](https://github.com/rust-lang/rust-clippy/pull/17353) ## Rust 1.97 @@ -6736,929 +6854,931 @@ Released 2018-09-13 -[`absolute_paths`]: https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths -[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons -[`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core -[`allow_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes -[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason -[`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range -[`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range -[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped -[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant -[`arbitrary_source_item_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering -[`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync -[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects -[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions -[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore -[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut -[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore -[`assert_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#assert_is_empty -[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants -[`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states -[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern -[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops -[`assigning_clones`]: https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones -[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async -[`await_holding_invalid_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type -[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock -[`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref -[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask -[`big_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#big_endian_bytes -[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map -[`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#blacklisted_name -[`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints -[`block_in_if_condition_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_expr -[`block_in_if_condition_stmt`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_stmt -[`block_scrutinee`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_scrutinee -[`blocks_in_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions -[`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions -[`bool_assert_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_assert_comparison -[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison -[`bool_to_int_with_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_to_int_with_if -[`borrow_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr -[`borrow_deref_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_deref_ref -[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const -[`borrowed_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrowed_box -[`box_collection`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_collection -[`box_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_default -[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec -[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local -[`branches_sharing_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#branches_sharing_code -[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow -[`by_ref_peekable_peek`]: https://rust-lang.github.io/rust-clippy/master/index.html#by_ref_peekable_peek -[`byte_char_slices`]: https://rust-lang.github.io/rust-clippy/master/index.html#byte_char_slices -[`bytes_count_to_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_count_to_len -[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth -[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata -[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons -[`cast_abs_to_unsigned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned -[`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_constructor -[`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_truncation -[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless -[`cast_nan_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_nan_to_int -[`cast_possible_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_truncation -[`cast_possible_wrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_wrap -[`cast_precision_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_precision_loss -[`cast_ptr_alignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ptr_alignment -[`cast_ref_to_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ref_to_mut -[`cast_sign_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_sign_loss -[`cast_slice_different_sizes`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_different_sizes -[`cast_slice_from_raw_parts`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_from_raw_parts -[`cfg_not_test`]: https://rust-lang.github.io/rust-clippy/master/index.html#cfg_not_test -[`char_indices_as_byte_indices`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_indices_as_byte_indices -[`char_lit_as_u8`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_lit_as_u8 -[`chars_last_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_last_cmp -[`chars_next_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_next_cmp -[`checked_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions -[`chunks_exact_to_as_chunks`]: https://rust-lang.github.io/rust-clippy/master/index.html#chunks_exact_to_as_chunks -[`clear_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#clear_with_drain -[`clone_double_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_double_ref -[`clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy -[`clone_on_ref_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr -[`cloned_instead_of_copied`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied -[`cloned_ref_to_slice_refs`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_ref_to_slice_refs -[`cmp_nan`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_nan -[`cmp_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_null -[`cmp_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_owned -[`coerce_container_to_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#coerce_container_to_any -[`cognitive_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity -[`collapsible_else_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if -[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if -[`collapsible_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match -[`collapsible_str_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace -[`collection_is_never_read`]: https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read -[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain -[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty -[`confusing_method_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#confusing_method_to_numeric_cast -[`const_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_is_empty -[`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime -[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator -[`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/master/index.html#crate_in_macro_def -[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir -[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute -[`cyclomatic_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cyclomatic_complexity -[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro -[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call -[`decimal_bitwise_operands`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_bitwise_operands -[`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation -[`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const -[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs -[`default_instead_of_iter_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_instead_of_iter_empty -[`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_numeric_fallback -[`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access -[`default_union_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_union_representation -[`definition_in_module_root`]: https://rust-lang.github.io/rust-clippy/master/index.html#definition_in_module_root -[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr -[`deprecated_clippy_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_clippy_cfg_attr -[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_semver -[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof -[`deref_by_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_by_slicing -[`derivable_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls -[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq -[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord -[`derive_partial_eq_without_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq -[`derived_hash_with_manual_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derived_hash_with_manual_eq -[`disallowed_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_fields -[`disallowed_macros`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros -[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method -[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods -[`disallowed_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names -[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents -[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type -[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types -[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression -[`doc_broken_link`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_broken_link -[`doc_comment_double_space_linebreaks`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_comment_double_space_linebreaks -[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg -[`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation -[`doc_link_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_code -[`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes -[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown -[`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs -[`doc_overindented_list_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items -[`doc_paragraphs_missing_punctuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_paragraphs_missing_punctuation -[`doc_suspicious_footnotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_suspicious_footnotes -[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons -[`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last -[`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use -[`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg -[`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens -[`drain_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#drain_collect -[`drop_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_bounds -[`drop_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_copy -[`drop_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_non_drop -[`drop_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_ref -[`duplicate_mod`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_mod -[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument -[`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicated_attributes -[`duration_suboptimal_units`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_suboptimal_units -[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec -[`eager_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#eager_transmute -[`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names -[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else -[`empty_docs`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_docs -[`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop -[`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum -[`empty_enum_variants_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum_variants_with_brackets -[`empty_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enums -[`empty_line_after_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments -[`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr -[`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop -[`empty_structs_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_structs_with_brackets -[`enum_clike_unportable_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_clike_unportable_variant -[`enum_glob_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_glob_use -[`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names -[`eq_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#eq_op -[`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let -[`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op -[`err_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#err_expect -[`error_impl_error`]: https://rust-lang.github.io/rust-clippy/master/index.html#error_impl_error -[`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence -[`excessive_nesting`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting -[`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision -[`exhaustive_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_enums -[`exhaustive_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_structs -[`exit`]: https://rust-lang.github.io/rust-clippy/master/index.html#exit -[`expect_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#expect_fun_call -[`expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#expect_used -[`expl_impl_clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#expl_impl_clone_on_copy -[`explicit_auto_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref -[`explicit_counter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_counter_loop -[`explicit_deref_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_deref_methods -[`explicit_into_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_into_iter_loop -[`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop -[`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write -[`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_from_slice -[`extend_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_with_drain -[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes -[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters -[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from -[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default -[`field_scoped_visibility_modifiers`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_scoped_visibility_modifiers -[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file -[`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map -[`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_bool_then -[`filter_map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_identity -[`filter_map_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next -[`filter_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_next -[`find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#find_map -[`flat_map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_identity -[`flat_map_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_option -[`float_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_arithmetic -[`float_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp -[`float_cmp_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp_const -[`float_equality_without_abs`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_equality_without_abs -[`fn_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_address_comparisons -[`fn_null_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_null_check -[`fn_params_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools -[`fn_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast -[`fn_to_numeric_cast_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast_any -[`fn_to_numeric_cast_with_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast_with_truncation -[`for_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_kv_map -[`for_loop_over_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loop_over_option -[`for_loop_over_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loop_over_result -[`for_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles -[`for_unbounded_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_unbounded_range -[`forget_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_copy -[`forget_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_non_drop -[`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref -[`format_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_collect -[`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_in_format_args -[`format_push_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_push_string -[`four_forward_slashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#four_forward_slashes -[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect -[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into -[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_raw_with_void_ptr -[`from_str_radix_10`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_str_radix_10 -[`future_not_send`]: https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send -[`get_first`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_first -[`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_last_with_len -[`get_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_unwrap -[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#host_endian_bytes -[`identity_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion -[`identity_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_op -[`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_mutex -[`if_let_redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_redundant_pattern_matching -[`if_let_some_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_some_result -[`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else -[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else -[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none -[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond -[`ignore_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignore_without_reason -[`ignored_unit_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignored_unit_patterns -[`impl_hash_borrow_with_str_and_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#impl_hash_borrow_with_str_and_bytes -[`impl_trait_in_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#impl_trait_in_params -[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone -[`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher -[`implicit_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_return -[`implicit_saturating_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_add -[`implicit_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub -[`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#implied_bounds_in_impls -[`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons -[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops -[`incompatible_msrv`]: https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv -[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping -[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor -[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type -[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type -[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice -[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing -[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask -[`ineffective_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_open_options -[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string -[`infallible_destructuring_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_destructuring_match -[`infallible_try_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_try_from -[`infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_iter -[`infinite_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_loop -[`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string -[`inherent_to_string_shadow_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string_shadow_display -[`init_numbered_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#init_numbered_fields -[`inline_always`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_always -[`inline_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_att_syntax -[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_intel_syntax -[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body -[`inline_modules`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_modules -[`inline_trait_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_trait_bounds -[`inspect_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#inspect_for_each -[`int_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#int_plus_one -[`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_arithmetic -[`integer_division`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division -[`integer_division_remainder_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division_remainder_used -[`into_iter_on_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_array -[`into_iter_on_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_ref -[`into_iter_without_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_without_iter -[`invalid_atomic_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering -[`invalid_null_ptr_usage`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_null_ptr_usage -[`invalid_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_ref -[`invalid_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_regex -[`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_upcast_comparisons -[`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked -[`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#inverted_saturating_sub -[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters -[`io_other_error`]: https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error -[`ip_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#ip_constant -[`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix -[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements -[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module -[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect -[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count -[`iter_filter_is_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_filter_is_ok -[`iter_filter_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_filter_is_some -[`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map -[`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop -[`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_slice -[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_not_returning_iterator -[`iter_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth -[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero -[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections -[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items -[`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_out_of_bounds -[`iter_over_hash_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_over_hash_type -[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned -[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next -[`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero -[`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain -[`iter_without_into_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_without_into_iter -[`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero -[`join_absolute_paths`]: https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths -[`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits -[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays -[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups -[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant -[`large_futures`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_futures -[`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file -[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays -[`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames -[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value -[`legacy_numeric_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants -[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty -[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero -[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return -[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop -[`let_underscore_future`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_future -[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock -[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use -[`let_underscore_untyped`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped -[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value -[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore -[`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok -[`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist -[`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/master/index.html#lint_groups_priority -[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#literal_string_with_formatting_args -[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes -[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug -[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal -[`macro_metavars_in_unsafe`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe -[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports -[`main_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#main_recursion -[`manual_abs_diff`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff -[`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert -[`manual_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert_eq -[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn -[`manual_bit_width`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bit_width -[`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits -[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals -[`manual_checked_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_checked_ops -[`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp -[`manual_clear`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clear -[`manual_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_contains -[`manual_dangling_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_dangling_ptr -[`manual_div_ceil`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil -[`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter -[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map -[`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find -[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map -[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten -[`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one -[`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp -[`manual_ilog2`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ilog2 -[`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect -[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed -[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check -[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite -[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite -[`manual_is_multiple_of`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_multiple_of -[`manual_is_power_of_two`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two -[`manual_is_variant_and`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_variant_and -[`manual_isolate_lowest_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_isolate_lowest_one -[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else -[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str -[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map -[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy -[`manual_midpoint`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint -[`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back -[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive -[`manual_noop_waker`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_noop_waker -[`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err -[`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or -[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice -[`manual_option_zip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_zip -[`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison -[`manual_pop_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pop_if -[`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains -[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns -[`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid -[`manual_repeat_n`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n -[`manual_retain`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain -[`manual_rotate`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rotate -[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic -[`manual_slice_fill`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill -[`manual_slice_size_calculation`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation -[`manual_split_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once -[`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat -[`manual_string_new`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new -[`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip -[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap -[`manual_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_take -[`manual_try_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold -[`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or -[`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default -[`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some -[`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names -[`map_all_any_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_all_any_identity -[`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone -[`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit -[`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry -[`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_err_ignore -[`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten -[`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity -[`map_or_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_or_identity -[`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or -[`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges -[`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref -[`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool -[`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro -[`match_on_vec_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_on_vec_items -[`match_overlapping_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_overlapping_arm -[`match_ref_pats`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_ref_pats -[`match_result_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_result_ok -[`match_same_arms`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_same_arms -[`match_single_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding -[`match_str_case_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_str_case_mismatch -[`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm -[`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants -[`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter -[`maybe_misused_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_misused_cfg -[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum -[`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget -[`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none -[`mem_replace_option_with_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some -[`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default -[`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_uninit -[`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars -[`min_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_max -[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute -[`mismatched_bit_width_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_bit_width_type -[`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os -[`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatching_type_param_order -[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters -[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op -[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_assert_message -[`missing_asserts_for_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_asserts_for_indexing -[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn -[`missing_const_for_thread_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_thread_local -[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items -[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames -[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc -[`missing_fields_in_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_fields_in_debug -[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items -[`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc -[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc -[`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop -[`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods -[`missing_transmute_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_transmute_annotations -[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes -[`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_attributes_style -[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals -[`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_read_write_in_expression -[`mod_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files -[`module_inception`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_inception -[`module_name_repetitions`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions -[`modulo_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic -[`modulo_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_one -[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/master/index.html#multi_assignments -[`multiple_bound_locations`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_bound_locations -[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions -[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl -[`multiple_unsafe_ops_per_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_unsafe_ops_per_block -[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate -[`must_use_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_unit -[`mut_from_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_from_ref -[`mut_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mut -[`mut_mutex_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mutex_lock -[`mut_range_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_range_bound -[`mutable_key_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type -[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic -[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer -[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount -[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type -[`needless_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_as_bytes -[`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool -[`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool -[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign -[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow -[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference -[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args -[`needless_character_iteration`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_character_iteration -[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect -[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue -[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main -[`needless_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_else -[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each -[`needless_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_if -[`needless_ifs`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_ifs -[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init -[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes -[`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match -[`needless_maybe_sized`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_maybe_sized -[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref -[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take -[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals -[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut -[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value -[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self -[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark -[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop -[`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes -[`needless_raw_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_strings -[`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return -[`needless_return_with_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return_with_question_mark -[`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn -[`needless_type_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_type_cast -[`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update -[`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord -[`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply -[`negative_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#negative_feature_names -[`never_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#never_loop -[`new_ret_no_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_ret_no_self -[`new_without_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default -[`new_without_default_derive`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default_derive -[`no_effect`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect -[`no_effect_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_replace -[`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_underscore_binding -[`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_mangle_with_rust_abi -[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal -[`non_canonical_clone_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_clone_impl -[`non_canonical_partial_ord_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_partial_ord_impl -[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg -[`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions -[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty -[`non_std_lazy_statics`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics -[`non_zero_suggestions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_zero_suggestions -[`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool -[`nonnull_unchecked_on_box_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonnull_unchecked_on_box_ptr -[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options -[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces -[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref -[`obfuscated_if_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#obfuscated_if_else -[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/master/index.html#octal_escapes -[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect -[`only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#only_used_in_recursion -[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref -[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some -[`option_as_ref_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_cloned -[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref -[`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_env_unwrap -[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_expect_used -[`option_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_filter_map -[`option_if_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else -[`option_map_or_err_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_err_ok -[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none -[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn -[`option_map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or -[`option_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or_else -[`option_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_option -[`option_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_unwrap_used -[`or_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call -[`or_then_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_then_unwrap -[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing -[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional -[`overly_complex_bool_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#overly_complex_bool_expr -[`owned_cow`]: https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow -[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic -[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn -[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params -[`panicking_overflow_checks`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_overflow_checks -[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap -[`partial_pub_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#partial_pub_fields -[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl -[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none -[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite -[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext -[`pathbuf_init_then_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#pathbuf_init_then_push -[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch -[`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false -[`pointer_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointer_format -[`pointers_in_nomem_asm_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointers_in_nomem_asm_block -[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters -[`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma -[`possible_missing_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_else -[`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence -[`precedence_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence_bits -[`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl -[`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal -[`print_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr -[`print_stdout`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout -[`print_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_with_newline -[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string -[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg -[`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr -[`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness -[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq -[`ptr_offset_by_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_by_literal -[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast -[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names -[`pub_underscore_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields -[`pub_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_use -[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_with_shorthand -[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_without_shorthand -[`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark -[`question_mark_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark_used -[`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one -[`range_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one -[`range_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_step_by_zero -[`range_zip_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_zip_with_len -[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer -[`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_clone_in_vec_init -[`rc_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex -[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_line_without_trim -[`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec -[`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#readonly_write_lock -[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl -[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation -[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_as_str -[`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block -[`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern -[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone -[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure -[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call -[`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls -[`redundant_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_comparisons -[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else -[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names -[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names -[`redundant_guards`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_guards -[`redundant_iter_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_iter_cloned -[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals -[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern -[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching -[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate -[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing -[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes -[`redundant_test_prefix`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_test_prefix -[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations -[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr -[`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference -[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref -[`ref_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option -[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref -[`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns -[`regex_creation_in_loops`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_creation_in_loops -[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro -[`renamed_function_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params -[`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once -[`repeat_vec_with_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity -[`replace_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_box -[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts -[`repr_packed_without_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#repr_packed_without_abi -[`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#reserve_after_initialization -[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs -[`rest_pattern_accessible_field`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pattern_accessible_field -[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used -[`result_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_filter_map -[`result_large_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err -[`result_map_or_into_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_or_into_option -[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn -[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else -[`result_unit_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err -[`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used -[`return_and_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_and_then -[`return_self_not_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use -[`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#reverse_range_loop -[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges -[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition -[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push -[`same_length_and_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_length_and_capacity -[`same_name_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method -[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some -[`seek_from_current`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current -[`seek_to_start_instead_of_rewind`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_to_start_instead_of_rewind -[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment -[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors -[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files -[`self_only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_only_used_in_recursion -[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned -[`semicolon_inside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block -[`semicolon_outside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block -[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix -[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse -[`set_contains_or_insert`]: https://rust-lang.github.io/rust-clippy/master/index.html#set_contains_or_insert -[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse -[`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same -[`shadow_unrelated`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_unrelated -[`short_circuit_statement`]: https://rust-lang.github.io/rust-clippy/master/index.html#short_circuit_statement -[`should_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_assert_eq -[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait -[`should_panic_without_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_panic_without_expect -[`significant_drop_in_scrutinee`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_in_scrutinee -[`significant_drop_tightening`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_tightening -[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names -[`single_call_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn -[`single_char_add_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str -[`single_char_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_lifetime_names -[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern -[`single_char_push_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_push_str -[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports -[`single_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop -[`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match -[`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else -[`single_option_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_option_map -[`single_range_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_range_in_vec_init -[`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count -[`size_of_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref -[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next -[`sliced_string_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#sliced_string_as_bytes -[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization -[`some_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#some_filter -[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive -[`std_instead_of_alloc`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_alloc -[`std_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_core -[`str_split_at_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_split_at_newline -[`str_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_to_string -[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add -[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign -[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars -[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes -[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes -[`string_lit_chars_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_chars_any -[`string_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_slice -[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string -[`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#strlen_on_c_strings -[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools -[`struct_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names -[`stutter`]: https://rust-lang.github.io/rust-clippy/master/index.html#stutter -[`suboptimal_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#suboptimal_flops -[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl -[`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting -[`suspicious_command_arg_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_command_arg_space -[`suspicious_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_doc_comments -[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting -[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map -[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl -[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options -[`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings -[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn -[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned -[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting -[`suspicious_xor_used_as_pow`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_xor_used_as_pow -[`swap_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_ptr_to_ref -[`swap_with_temporary`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_with_temporary -[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#tabs_in_doc_comments -[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment -[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr -[`test_attr_in_doctest`]: https://rust-lang.github.io/rust-clippy/master/index.html#test_attr_in_doctest -[`tests_outside_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#tests_outside_test_module -[`thread_local_initializer_can_be_made_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#thread_local_initializer_can_be_made_const -[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some -[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display -[`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args -[`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_trait_impl -[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo -[`too_long_first_doc_paragraph`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph -[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments -[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines -[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg -[`trailing_empty_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#trailing_empty_array -[`trait_duplication_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#trait_duplication_in_bounds -[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_bytes_to_str -[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_float_to_int -[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool -[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char -[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float -[`transmute_int_to_non_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_non_zero -[`transmute_null_to_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_null_to_fn -[`transmute_num_to_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_num_to_bytes -[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr -[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref -[`transmute_undefined_repr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_undefined_repr -[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmutes_expressible_as_ptr_casts -[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmuting_null -[`trim_split_whitespace`]: https://rust-lang.github.io/rust-clippy/master/index.html#trim_split_whitespace -[`trivial_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivial_regex -[`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref -[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err -[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions -[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity -[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box -[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds -[`unbuffered_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#unbuffered_bytes -[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction -[`unchecked_time_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction -[`unconditional_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#unconditional_recursion -[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks -[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops -[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc -[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented -[`uninhabited_references`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninhabited_references -[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init -[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec -[`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args -[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg -[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp -[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash -[`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_return_expecting_ord -[`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#unknown_clippy_lints -[`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns -[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast -[`unnecessary_clippy_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_clippy_cfg -[`unnecessary_debug_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_debug_formatting -[`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions -[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map -[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map -[`unnecessary_first_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_first_then_check -[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold -[`unnecessary_get_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check -[`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join -[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations -[`unnecessary_literal_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_bound -[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap -[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor -[`unnecessary_map_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or -[`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max -[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed -[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation -[`unnecessary_option_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_option_map_or_else -[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings -[`unnecessary_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_rest_pattern -[`unnecessary_result_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_result_map_or_else -[`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment -[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc -[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports -[`unnecessary_semicolon`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_semicolon -[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by -[`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_struct_initialization -[`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned -[`unnecessary_trailing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_trailing_comma -[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap -[`unnecessary_unwrap_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap_unchecked -[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps -[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern -[`unneeded_struct_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern -[`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_wildcard_pattern -[`unnested_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns -[`unreachable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreachable -[`unreadable_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal -[`unsafe_derive_deserialize`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_derive_deserialize -[`unsafe_removed_from_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_removed_from_name -[`unsafe_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_vector_initialization -[`unseparated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#unseparated_literal_suffix -[`unsound_collection_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsound_collection_transmute -[`unstable_as_mut_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_mut_slice -[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice -[`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async -[`unused_async_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async_trait_impl -[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect -[`unused_enumerate_index`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_enumerate_index -[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs -[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount -[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label -[`unused_peekable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_peekable -[`unused_result_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_result_ok -[`unused_rounding`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_rounding -[`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self -[`unused_trait_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names -[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit -[`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings -[`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_in_result -[`unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_or_default -[`unwrap_or_else_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_or_else_default -[`unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used -[`upper_case_acronyms`]: https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms -[`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug -[`use_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_self -[`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding -[`used_underscore_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_items -[`useless_asref`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref -[`useless_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_attribute -[`useless_borrows_in_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_borrows_in_formatting -[`useless_concat`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_concat -[`useless_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion -[`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format -[`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_let_if_seq -[`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_nonzero_new_unchecked -[`useless_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_transmute -[`useless_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec -[`vec_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_box -[`vec_init_then_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push -[`vec_resize_to_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_resize_to_zero -[`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask -[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads -[`volatile_composites`]: https://rust-lang.github.io/rust-clippy/master/index.html#volatile_composites -[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons -[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/master/index.html#waker_clone_wake -[`while_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_float -[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition -[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop -[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator -[`wildcard_dependencies`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_dependencies -[`wildcard_enum_match_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_enum_match_arm -[`wildcard_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports -[`wildcard_in_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_in_or_patterns -[`with_capacity_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#with_capacity_zero -[`write_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#write_literal -[`write_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#write_with_newline -[`writeln_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#writeln_empty_string -[`wrong_pub_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_pub_self_convention -[`wrong_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention -[`wrong_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_transmute -[`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_divided_by_zero -[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal -[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr -[`zero_repeat_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_repeat_side_effects -[`zero_sized_map_values`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_sized_map_values -[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space -[`zombie_processes`]: https://rust-lang.github.io/rust-clippy/master/index.html#zombie_processes -[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset +[`absolute_paths`]: https://rust-lang.github.io/rust-clippy/main/index.html#absolute_paths +[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#absurd_extreme_comparisons +[`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/main/index.html#alloc_instead_of_core +[`allow_attributes`]: https://rust-lang.github.io/rust-clippy/main/index.html#allow_attributes +[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/main/index.html#allow_attributes_without_reason +[`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/main/index.html#almost_complete_letter_range +[`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/main/index.html#almost_complete_range +[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/main/index.html#almost_swapped +[`approx_constant`]: https://rust-lang.github.io/rust-clippy/main/index.html#approx_constant +[`arbitrary_source_item_ordering`]: https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering +[`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/main/index.html#arc_with_non_send_sync +[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/main/index.html#arithmetic_side_effects +[`as_conversions`]: https://rust-lang.github.io/rust-clippy/main/index.html#as_conversions +[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/main/index.html#as_pointer_underscore +[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/main/index.html#as_ptr_cast_mut +[`as_underscore`]: https://rust-lang.github.io/rust-clippy/main/index.html#as_underscore +[`assert_is_empty`]: https://rust-lang.github.io/rust-clippy/main/index.html#assert_is_empty +[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/main/index.html#assertions_on_constants +[`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/main/index.html#assertions_on_result_states +[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#assign_op_pattern +[`assign_ops`]: https://rust-lang.github.io/rust-clippy/main/index.html#assign_ops +[`assigning_clones`]: https://rust-lang.github.io/rust-clippy/main/index.html#assigning_clones +[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/main/index.html#async_yields_async +[`await_holding_invalid_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#await_holding_invalid_type +[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/main/index.html#await_holding_lock +[`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#await_holding_refcell_ref +[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/main/index.html#bad_bit_mask +[`big_endian_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#big_endian_bytes +[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#bind_instead_of_map +[`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/main/index.html#blacklisted_name +[`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/main/index.html#blanket_clippy_restriction_lints +[`block_in_if_condition_expr`]: https://rust-lang.github.io/rust-clippy/main/index.html#block_in_if_condition_expr +[`block_in_if_condition_stmt`]: https://rust-lang.github.io/rust-clippy/main/index.html#block_in_if_condition_stmt +[`block_scrutinee`]: https://rust-lang.github.io/rust-clippy/main/index.html#block_scrutinee +[`blocks_in_conditions`]: https://rust-lang.github.io/rust-clippy/main/index.html#blocks_in_conditions +[`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/main/index.html#blocks_in_if_conditions +[`bool_assert_comparison`]: https://rust-lang.github.io/rust-clippy/main/index.html#bool_assert_comparison +[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/main/index.html#bool_comparison +[`bool_to_int_with_if`]: https://rust-lang.github.io/rust-clippy/main/index.html#bool_to_int_with_if +[`borrow_as_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#borrow_as_ptr +[`borrow_deref_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#borrow_deref_ref +[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/main/index.html#borrow_interior_mutable_const +[`borrowed_box`]: https://rust-lang.github.io/rust-clippy/main/index.html#borrowed_box +[`box_collection`]: https://rust-lang.github.io/rust-clippy/main/index.html#box_collection +[`box_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#box_default +[`box_vec`]: https://rust-lang.github.io/rust-clippy/main/index.html#box_vec +[`boxed_local`]: https://rust-lang.github.io/rust-clippy/main/index.html#boxed_local +[`branches_sharing_code`]: https://rust-lang.github.io/rust-clippy/main/index.html#branches_sharing_code +[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/main/index.html#builtin_type_shadow +[`by_ref_peekable_peek`]: https://rust-lang.github.io/rust-clippy/main/index.html#by_ref_peekable_peek +[`byte_char_slices`]: https://rust-lang.github.io/rust-clippy/main/index.html#byte_char_slices +[`bytes_count_to_len`]: https://rust-lang.github.io/rust-clippy/main/index.html#bytes_count_to_len +[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/main/index.html#bytes_nth +[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/main/index.html#cargo_common_metadata +[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#case_sensitive_file_extension_comparisons +[`cast_abs_to_unsigned`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_abs_to_unsigned +[`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_enum_constructor +[`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_enum_truncation +[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_lossless +[`cast_nan_to_int`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_nan_to_int +[`cast_possible_truncation`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_possible_truncation +[`cast_possible_wrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_possible_wrap +[`cast_precision_loss`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_precision_loss +[`cast_ptr_alignment`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_ptr_alignment +[`cast_ref_to_mut`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_ref_to_mut +[`cast_sign_loss`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_sign_loss +[`cast_slice_different_sizes`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_slice_different_sizes +[`cast_slice_from_raw_parts`]: https://rust-lang.github.io/rust-clippy/main/index.html#cast_slice_from_raw_parts +[`cfg_not_test`]: https://rust-lang.github.io/rust-clippy/main/index.html#cfg_not_test +[`char_indices_as_byte_indices`]: https://rust-lang.github.io/rust-clippy/main/index.html#char_indices_as_byte_indices +[`char_lit_as_u8`]: https://rust-lang.github.io/rust-clippy/main/index.html#char_lit_as_u8 +[`chars_last_cmp`]: https://rust-lang.github.io/rust-clippy/main/index.html#chars_last_cmp +[`chars_next_cmp`]: https://rust-lang.github.io/rust-clippy/main/index.html#chars_next_cmp +[`checked_conversions`]: https://rust-lang.github.io/rust-clippy/main/index.html#checked_conversions +[`chunks_exact_to_as_chunks`]: https://rust-lang.github.io/rust-clippy/main/index.html#chunks_exact_to_as_chunks +[`clear_with_drain`]: https://rust-lang.github.io/rust-clippy/main/index.html#clear_with_drain +[`clone_double_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#clone_double_ref +[`clone_on_copy`]: https://rust-lang.github.io/rust-clippy/main/index.html#clone_on_copy +[`clone_on_ref_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#clone_on_ref_ptr +[`cloned_instead_of_copied`]: https://rust-lang.github.io/rust-clippy/main/index.html#cloned_instead_of_copied +[`cloned_ref_to_slice_refs`]: https://rust-lang.github.io/rust-clippy/main/index.html#cloned_ref_to_slice_refs +[`cmp_nan`]: https://rust-lang.github.io/rust-clippy/main/index.html#cmp_nan +[`cmp_null`]: https://rust-lang.github.io/rust-clippy/main/index.html#cmp_null +[`cmp_owned`]: https://rust-lang.github.io/rust-clippy/main/index.html#cmp_owned +[`coerce_container_to_any`]: https://rust-lang.github.io/rust-clippy/main/index.html#coerce_container_to_any +[`cognitive_complexity`]: https://rust-lang.github.io/rust-clippy/main/index.html#cognitive_complexity +[`collapsible_else_if`]: https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_else_if +[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_if +[`collapsible_match`]: https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_match +[`collapsible_str_replace`]: https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_str_replace +[`collection_is_never_read`]: https://rust-lang.github.io/rust-clippy/main/index.html#collection_is_never_read +[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/main/index.html#comparison_chain +[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/main/index.html#comparison_to_empty +[`confusing_method_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/main/index.html#confusing_method_to_numeric_cast +[`const_is_empty`]: https://rust-lang.github.io/rust-clippy/main/index.html#const_is_empty +[`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/main/index.html#const_static_lifetime +[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/main/index.html#copy_iterator +[`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/main/index.html#crate_in_macro_def +[`create_dir`]: https://rust-lang.github.io/rust-clippy/main/index.html#create_dir +[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#crosspointer_transmute +[`cyclomatic_complexity`]: https://rust-lang.github.io/rust-clippy/main/index.html#cyclomatic_complexity +[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/main/index.html#dbg_macro +[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/main/index.html#debug_assert_with_mut_call +[`decimal_bitwise_operands`]: https://rust-lang.github.io/rust-clippy/main/index.html#decimal_bitwise_operands +[`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/main/index.html#decimal_literal_representation +[`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/main/index.html#declare_interior_mutable_const +[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/main/index.html#default_constructed_unit_structs +[`default_instead_of_iter_empty`]: https://rust-lang.github.io/rust-clippy/main/index.html#default_instead_of_iter_empty +[`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/main/index.html#default_numeric_fallback +[`default_trait_access`]: https://rust-lang.github.io/rust-clippy/main/index.html#default_trait_access +[`default_union_representation`]: https://rust-lang.github.io/rust-clippy/main/index.html#default_union_representation +[`definition_in_module_root`]: https://rust-lang.github.io/rust-clippy/main/index.html#definition_in_module_root +[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/main/index.html#deprecated_cfg_attr +[`deprecated_clippy_cfg_attr`]: https://rust-lang.github.io/rust-clippy/main/index.html#deprecated_clippy_cfg_attr +[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/main/index.html#deprecated_semver +[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/main/index.html#deref_addrof +[`deref_by_slicing`]: https://rust-lang.github.io/rust-clippy/main/index.html#deref_by_slicing +[`derivable_impls`]: https://rust-lang.github.io/rust-clippy/main/index.html#derivable_impls +[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#derive_hash_xor_eq +[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/main/index.html#derive_ord_xor_partial_ord +[`derive_partial_eq_without_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#derive_partial_eq_without_eq +[`derived_hash_with_manual_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#derived_hash_with_manual_eq +[`disallowed_fields`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_fields +[`disallowed_macros`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_macros +[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_method +[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_methods +[`disallowed_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_names +[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_script_idents +[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_type +[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_types +[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/main/index.html#diverging_sub_expression +[`doc_broken_link`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_broken_link +[`doc_comment_double_space_linebreaks`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_comment_double_space_linebreaks +[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_include_without_cfg +[`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_lazy_continuation +[`doc_link_code`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_link_code +[`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_link_with_quotes +[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_markdown +[`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_nested_refdefs +[`doc_overindented_list_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_overindented_list_items +[`doc_paragraphs_missing_punctuation`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_paragraphs_missing_punctuation +[`doc_suspicious_footnotes`]: https://rust-lang.github.io/rust-clippy/main/index.html#doc_suspicious_footnotes +[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#double_comparisons +[`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/main/index.html#double_ended_iterator_last +[`double_must_use`]: https://rust-lang.github.io/rust-clippy/main/index.html#double_must_use +[`double_neg`]: https://rust-lang.github.io/rust-clippy/main/index.html#double_neg +[`double_parens`]: https://rust-lang.github.io/rust-clippy/main/index.html#double_parens +[`drain_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#drain_collect +[`drop_bounds`]: https://rust-lang.github.io/rust-clippy/main/index.html#drop_bounds +[`drop_copy`]: https://rust-lang.github.io/rust-clippy/main/index.html#drop_copy +[`drop_non_drop`]: https://rust-lang.github.io/rust-clippy/main/index.html#drop_non_drop +[`drop_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#drop_ref +[`duplicate_mod`]: https://rust-lang.github.io/rust-clippy/main/index.html#duplicate_mod +[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/main/index.html#duplicate_underscore_argument +[`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/main/index.html#duplicated_attributes +[`duration_suboptimal_units`]: https://rust-lang.github.io/rust-clippy/main/index.html#duration_suboptimal_units +[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/main/index.html#duration_subsec +[`eager_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#eager_transmute +[`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#elidable_lifetime_names +[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#else_if_without_else +[`empty_docs`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_docs +[`empty_drop`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_drop +[`empty_enum`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_enum +[`empty_enum_variants_with_brackets`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_enum_variants_with_brackets +[`empty_enums`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_enums +[`empty_line_after_doc_comments`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_line_after_doc_comments +[`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_line_after_outer_attr +[`empty_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_loop +[`empty_structs_with_brackets`]: https://rust-lang.github.io/rust-clippy/main/index.html#empty_structs_with_brackets +[`enum_clike_unportable_variant`]: https://rust-lang.github.io/rust-clippy/main/index.html#enum_clike_unportable_variant +[`enum_glob_use`]: https://rust-lang.github.io/rust-clippy/main/index.html#enum_glob_use +[`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#enum_variant_names +[`eq_op`]: https://rust-lang.github.io/rust-clippy/main/index.html#eq_op +[`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/main/index.html#equatable_if_let +[`erasing_op`]: https://rust-lang.github.io/rust-clippy/main/index.html#erasing_op +[`err_expect`]: https://rust-lang.github.io/rust-clippy/main/index.html#err_expect +[`error_impl_error`]: https://rust-lang.github.io/rust-clippy/main/index.html#error_impl_error +[`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/main/index.html#eval_order_dependence +[`excessive_nesting`]: https://rust-lang.github.io/rust-clippy/main/index.html#excessive_nesting +[`excessive_precision`]: https://rust-lang.github.io/rust-clippy/main/index.html#excessive_precision +[`exhaustive_enums`]: https://rust-lang.github.io/rust-clippy/main/index.html#exhaustive_enums +[`exhaustive_structs`]: https://rust-lang.github.io/rust-clippy/main/index.html#exhaustive_structs +[`exit`]: https://rust-lang.github.io/rust-clippy/main/index.html#exit +[`expect_fun_call`]: https://rust-lang.github.io/rust-clippy/main/index.html#expect_fun_call +[`expect_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#expect_used +[`expl_impl_clone_on_copy`]: https://rust-lang.github.io/rust-clippy/main/index.html#expl_impl_clone_on_copy +[`explicit_auto_deref`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_auto_deref +[`explicit_counter_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_counter_loop +[`explicit_deref_methods`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_deref_methods +[`explicit_into_iter_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_into_iter_loop +[`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_iter_loop +[`explicit_write`]: https://rust-lang.github.io/rust-clippy/main/index.html#explicit_write +[`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#extend_from_slice +[`extend_with_drain`]: https://rust-lang.github.io/rust-clippy/main/index.html#extend_with_drain +[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/main/index.html#extra_unused_lifetimes +[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/main/index.html#extra_unused_type_parameters +[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/main/index.html#fallible_impl_from +[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#field_reassign_with_default +[`field_scoped_visibility_modifiers`]: https://rust-lang.github.io/rust-clippy/main/index.html#field_scoped_visibility_modifiers +[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/main/index.html#filetype_is_file +[`filter_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#filter_map +[`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/main/index.html#filter_map_bool_then +[`filter_map_identity`]: https://rust-lang.github.io/rust-clippy/main/index.html#filter_map_identity +[`filter_map_next`]: https://rust-lang.github.io/rust-clippy/main/index.html#filter_map_next +[`filter_next`]: https://rust-lang.github.io/rust-clippy/main/index.html#filter_next +[`find_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#find_map +[`flat_map_identity`]: https://rust-lang.github.io/rust-clippy/main/index.html#flat_map_identity +[`flat_map_option`]: https://rust-lang.github.io/rust-clippy/main/index.html#flat_map_option +[`float_arithmetic`]: https://rust-lang.github.io/rust-clippy/main/index.html#float_arithmetic +[`float_cmp`]: https://rust-lang.github.io/rust-clippy/main/index.html#float_cmp +[`float_cmp_const`]: https://rust-lang.github.io/rust-clippy/main/index.html#float_cmp_const +[`float_equality_without_abs`]: https://rust-lang.github.io/rust-clippy/main/index.html#float_equality_without_abs +[`fn_address_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_address_comparisons +[`fn_null_check`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_null_check +[`fn_params_excessive_bools`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_params_excessive_bools +[`fn_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_to_numeric_cast +[`fn_to_numeric_cast_any`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_to_numeric_cast_any +[`fn_to_numeric_cast_with_truncation`]: https://rust-lang.github.io/rust-clippy/main/index.html#fn_to_numeric_cast_with_truncation +[`for_kv_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#for_kv_map +[`for_loop_over_option`]: https://rust-lang.github.io/rust-clippy/main/index.html#for_loop_over_option +[`for_loop_over_result`]: https://rust-lang.github.io/rust-clippy/main/index.html#for_loop_over_result +[`for_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/main/index.html#for_loops_over_fallibles +[`for_unbounded_range`]: https://rust-lang.github.io/rust-clippy/main/index.html#for_unbounded_range +[`forget_copy`]: https://rust-lang.github.io/rust-clippy/main/index.html#forget_copy +[`forget_non_drop`]: https://rust-lang.github.io/rust-clippy/main/index.html#forget_non_drop +[`forget_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#forget_ref +[`format_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#format_collect +[`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/main/index.html#format_in_format_args +[`format_push_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#format_push_string +[`four_forward_slashes`]: https://rust-lang.github.io/rust-clippy/main/index.html#four_forward_slashes +[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#from_iter_instead_of_collect +[`from_over_into`]: https://rust-lang.github.io/rust-clippy/main/index.html#from_over_into +[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#from_raw_with_void_ptr +[`from_str_radix_10`]: https://rust-lang.github.io/rust-clippy/main/index.html#from_str_radix_10 +[`future_not_send`]: https://rust-lang.github.io/rust-clippy/main/index.html#future_not_send +[`get_first`]: https://rust-lang.github.io/rust-clippy/main/index.html#get_first +[`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/main/index.html#get_last_with_len +[`get_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#get_unwrap +[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#host_endian_bytes +[`identity_conversion`]: https://rust-lang.github.io/rust-clippy/main/index.html#identity_conversion +[`identity_op`]: https://rust-lang.github.io/rust-clippy/main/index.html#identity_op +[`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_let_mutex +[`if_let_redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_let_redundant_pattern_matching +[`if_let_some_result`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_let_some_result +[`if_not_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_not_else +[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_same_then_else +[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/main/index.html#if_then_some_else_none +[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/main/index.html#ifs_same_cond +[`ignore_without_reason`]: https://rust-lang.github.io/rust-clippy/main/index.html#ignore_without_reason +[`ignored_unit_patterns`]: https://rust-lang.github.io/rust-clippy/main/index.html#ignored_unit_patterns +[`impl_hash_borrow_with_str_and_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#impl_hash_borrow_with_str_and_bytes +[`impl_trait_in_params`]: https://rust-lang.github.io/rust-clippy/main/index.html#impl_trait_in_params +[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/main/index.html#implicit_clone +[`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/main/index.html#implicit_hasher +[`implicit_return`]: https://rust-lang.github.io/rust-clippy/main/index.html#implicit_return +[`implicit_saturating_add`]: https://rust-lang.github.io/rust-clippy/main/index.html#implicit_saturating_add +[`implicit_saturating_sub`]: https://rust-lang.github.io/rust-clippy/main/index.html#implicit_saturating_sub +[`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/main/index.html#implied_bounds_in_impls +[`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#impossible_comparisons +[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/main/index.html#imprecise_flops +[`incompatible_msrv`]: https://rust-lang.github.io/rust-clippy/main/index.html#incompatible_msrv +[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/main/index.html#inconsistent_digit_grouping +[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/main/index.html#inconsistent_struct_constructor +[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#incorrect_clone_impl_on_copy_type +[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#incorrect_partial_ord_impl_on_ord_type +[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#index_refutable_slice +[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/main/index.html#indexing_slicing +[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/main/index.html#ineffective_bit_mask +[`ineffective_open_options`]: https://rust-lang.github.io/rust-clippy/main/index.html#ineffective_open_options +[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#inefficient_to_string +[`infallible_destructuring_match`]: https://rust-lang.github.io/rust-clippy/main/index.html#infallible_destructuring_match +[`infallible_try_from`]: https://rust-lang.github.io/rust-clippy/main/index.html#infallible_try_from +[`infinite_iter`]: https://rust-lang.github.io/rust-clippy/main/index.html#infinite_iter +[`infinite_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#infinite_loop +[`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#inherent_to_string +[`inherent_to_string_shadow_display`]: https://rust-lang.github.io/rust-clippy/main/index.html#inherent_to_string_shadow_display +[`init_numbered_fields`]: https://rust-lang.github.io/rust-clippy/main/index.html#init_numbered_fields +[`inline_always`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_always +[`inline_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_asm_x86_att_syntax +[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_asm_x86_intel_syntax +[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_fn_without_body +[`inline_modules`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_modules +[`inline_trait_bounds`]: https://rust-lang.github.io/rust-clippy/main/index.html#inline_trait_bounds +[`inspect_for_each`]: https://rust-lang.github.io/rust-clippy/main/index.html#inspect_for_each +[`int_plus_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#int_plus_one +[`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/main/index.html#integer_arithmetic +[`integer_division`]: https://rust-lang.github.io/rust-clippy/main/index.html#integer_division +[`integer_division_remainder_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#integer_division_remainder_used +[`into_iter_on_array`]: https://rust-lang.github.io/rust-clippy/main/index.html#into_iter_on_array +[`into_iter_on_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#into_iter_on_ref +[`into_iter_without_iter`]: https://rust-lang.github.io/rust-clippy/main/index.html#into_iter_without_iter +[`invalid_atomic_ordering`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_atomic_ordering +[`invalid_null_ptr_usage`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_null_ptr_usage +[`invalid_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_ref +[`invalid_regex`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_regex +[`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_upcast_comparisons +[`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/main/index.html#invalid_utf8_in_unchecked +[`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/main/index.html#inverted_saturating_sub +[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/main/index.html#invisible_characters +[`io_other_error`]: https://rust-lang.github.io/rust-clippy/main/index.html#io_other_error +[`ip_constant`]: https://rust-lang.github.io/rust-clippy/main/index.html#ip_constant +[`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/main/index.html#is_digit_ascii_radix +[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/main/index.html#items_after_statements +[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/main/index.html#items_after_test_module +[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_cloned_collect +[`iter_count`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_count +[`iter_filter_is_ok`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_filter_is_ok +[`iter_filter_is_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_filter_is_some +[`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_kv_map +[`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_next_loop +[`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_next_slice +[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_not_returning_iterator +[`iter_nth`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_nth +[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_nth_zero +[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_on_empty_collections +[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_on_single_items +[`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_out_of_bounds +[`iter_over_hash_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_over_hash_type +[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_overeager_cloned +[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_skip_next +[`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_skip_zero +[`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_with_drain +[`iter_without_into_iter`]: https://rust-lang.github.io/rust-clippy/main/index.html#iter_without_into_iter +[`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#iterator_step_by_zero +[`join_absolute_paths`]: https://rust-lang.github.io/rust-clippy/main/index.html#join_absolute_paths +[`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/main/index.html#just_underscores_and_digits +[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_const_arrays +[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_digit_groups +[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_enum_variant +[`large_futures`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_futures +[`large_include_file`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_include_file +[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_stack_arrays +[`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_stack_frames +[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/main/index.html#large_types_passed_by_value +[`legacy_numeric_constants`]: https://rust-lang.github.io/rust-clippy/main/index.html#legacy_numeric_constants +[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/main/index.html#len_without_is_empty +[`len_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#len_zero +[`let_and_return`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_and_return +[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_underscore_drop +[`let_underscore_future`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_underscore_future +[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_underscore_lock +[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_underscore_must_use +[`let_underscore_untyped`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_underscore_untyped +[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_unit_value +[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/main/index.html#let_with_type_underscore +[`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/main/index.html#lines_filter_map_ok +[`linkedlist`]: https://rust-lang.github.io/rust-clippy/main/index.html#linkedlist +[`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/main/index.html#lint_groups_priority +[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/main/index.html#literal_string_with_formatting_args +[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#little_endian_bytes +[`logic_bug`]: https://rust-lang.github.io/rust-clippy/main/index.html#logic_bug +[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#lossy_float_literal +[`macro_metavars_in_unsafe`]: https://rust-lang.github.io/rust-clippy/main/index.html#macro_metavars_in_unsafe +[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/main/index.html#macro_use_imports +[`main_recursion`]: https://rust-lang.github.io/rust-clippy/main/index.html#main_recursion +[`manual_abs_diff`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_abs_diff +[`manual_assert`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_assert +[`manual_assert_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_assert_eq +[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_async_fn +[`manual_bit_width`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_bit_width +[`manual_bits`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_bits +[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_c_str_literals +[`manual_checked_ops`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_checked_ops +[`manual_clamp`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_clamp +[`manual_clear`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_clear +[`manual_contains`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_contains +[`manual_dangling_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_dangling_ptr +[`manual_div_ceil`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_div_ceil +[`manual_filter`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_filter +[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_filter_map +[`manual_find`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_find +[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_find_map +[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_flatten +[`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_hash_one +[`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_ignore_case_cmp +[`manual_ilog2`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_ilog2 +[`manual_inspect`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_inspect +[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_instant_elapsed +[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_ascii_check +[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_finite +[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_infinite +[`manual_is_multiple_of`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_multiple_of +[`manual_is_power_of_two`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_power_of_two +[`manual_is_variant_and`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_variant_and +[`manual_isolate_lowest_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_isolate_lowest_one +[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_let_else +[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_main_separator_str +[`manual_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_map +[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_memcpy +[`manual_midpoint`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_midpoint +[`manual_next_back`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_next_back +[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_non_exhaustive +[`manual_noop_waker`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_noop_waker +[`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_ok_err +[`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_ok_or +[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_option_as_slice +[`manual_option_zip`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_option_zip +[`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_pattern_char_comparison +[`manual_pop_if`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_pop_if +[`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_range_contains +[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_range_patterns +[`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_rem_euclid +[`manual_repeat_n`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_repeat_n +[`manual_retain`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_retain +[`manual_rotate`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_rotate +[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_saturating_arithmetic +[`manual_slice_fill`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_slice_fill +[`manual_slice_size_calculation`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_slice_size_calculation +[`manual_split_once`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_split_once +[`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_str_repeat +[`manual_string_new`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_string_new +[`manual_strip`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_strip +[`manual_swap`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_swap +[`manual_take`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_take +[`manual_try_fold`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_try_fold +[`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_unwrap_or +[`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_unwrap_or_default +[`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#manual_while_let_some +[`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#many_single_char_names +[`map_all_any_identity`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_all_any_identity +[`map_clone`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_clone +[`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_collect_result_unit +[`map_entry`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_entry +[`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_err_ignore +[`map_flatten`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_flatten +[`map_identity`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_identity +[`map_or_identity`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_or_identity +[`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_unwrap_or +[`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/main/index.html#map_with_unused_argument_over_ranges +[`match_as_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_as_ref +[`match_bool`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_bool +[`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_like_matches_macro +[`match_on_vec_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_on_vec_items +[`match_overlapping_arm`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_overlapping_arm +[`match_ref_pats`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_ref_pats +[`match_result_ok`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_result_ok +[`match_same_arms`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_same_arms +[`match_single_binding`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_single_binding +[`match_str_case_mismatch`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_str_case_mismatch +[`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_wild_err_arm +[`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/main/index.html#match_wildcard_for_single_variants +[`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/main/index.html#maybe_infinite_iter +[`maybe_misused_cfg`]: https://rust-lang.github.io/rust-clippy/main/index.html#maybe_misused_cfg +[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_discriminant_non_enum +[`mem_forget`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_forget +[`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_option_with_none +[`mem_replace_option_with_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_option_with_some +[`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_with_default +[`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_with_uninit +[`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/main/index.html#min_ident_chars +[`min_max`]: https://rust-lang.github.io/rust-clippy/main/index.html#min_max +[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#misaligned_transmute +[`mismatched_bit_width_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#mismatched_bit_width_type +[`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/main/index.html#mismatched_target_os +[`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/main/index.html#mismatching_type_param_order +[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/main/index.html#misnamed_getters +[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/main/index.html#misrefactored_assign_op +[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_assert_message +[`missing_asserts_for_indexing`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_asserts_for_indexing +[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_const_for_fn +[`missing_const_for_thread_local`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_const_for_thread_local +[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_docs_in_private_items +[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_enforced_import_renames +[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_errors_doc +[`missing_fields_in_debug`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_fields_in_debug +[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_inline_in_public_items +[`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_panics_doc +[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_safety_doc +[`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_spin_loop +[`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_trait_methods +[`missing_transmute_annotations`]: https://rust-lang.github.io/rust-clippy/main/index.html#missing_transmute_annotations +[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/main/index.html#mistyped_literal_suffixes +[`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/main/index.html#mixed_attributes_style +[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/main/index.html#mixed_case_hex_literals +[`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/main/index.html#mixed_read_write_in_expression +[`mod_module_files`]: https://rust-lang.github.io/rust-clippy/main/index.html#mod_module_files +[`module_inception`]: https://rust-lang.github.io/rust-clippy/main/index.html#module_inception +[`module_name_repetitions`]: https://rust-lang.github.io/rust-clippy/main/index.html#module_name_repetitions +[`modulo_arithmetic`]: https://rust-lang.github.io/rust-clippy/main/index.html#modulo_arithmetic +[`modulo_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#modulo_one +[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/main/index.html#multi_assignments +[`multiple_bound_locations`]: https://rust-lang.github.io/rust-clippy/main/index.html#multiple_bound_locations +[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/main/index.html#multiple_crate_versions +[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#multiple_inherent_impl +[`multiple_unsafe_ops_per_block`]: https://rust-lang.github.io/rust-clippy/main/index.html#multiple_unsafe_ops_per_block +[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/main/index.html#must_use_candidate +[`must_use_unit`]: https://rust-lang.github.io/rust-clippy/main/index.html#must_use_unit +[`mut_from_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#mut_from_ref +[`mut_mut`]: https://rust-lang.github.io/rust-clippy/main/index.html#mut_mut +[`mut_mutex_lock`]: https://rust-lang.github.io/rust-clippy/main/index.html#mut_mutex_lock +[`mut_range_bound`]: https://rust-lang.github.io/rust-clippy/main/index.html#mut_range_bound +[`mutable_key_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#mutable_key_type +[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/main/index.html#mutex_atomic +[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/main/index.html#mutex_integer +[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/main/index.html#naive_bytecount +[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_arbitrary_self_type +[`needless_as_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_as_bytes +[`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_bitwise_bool +[`needless_bool`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_bool +[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_bool_assign +[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_borrow +[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_borrowed_reference +[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_borrows_for_generic_args +[`needless_character_iteration`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_character_iteration +[`needless_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_collect +[`needless_continue`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_continue +[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_doctest_main +[`needless_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_else +[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_for_each +[`needless_if`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_if +[`needless_ifs`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_ifs +[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_late_init +[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_lifetimes +[`needless_match`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_match +[`needless_maybe_sized`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_maybe_sized +[`needless_nonzero_get`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_nonzero_get +[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_option_as_deref +[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_option_take +[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_parens_on_range_literals +[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_pass_by_ref_mut +[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_pass_by_value +[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_pub_self +[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_question_mark +[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_range_loop +[`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_raw_string_hashes +[`needless_raw_strings`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_raw_strings +[`needless_return`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_return +[`needless_return_with_question_mark`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_return_with_question_mark +[`needless_splitn`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_splitn +[`needless_type_cast`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_type_cast +[`needless_update`]: https://rust-lang.github.io/rust-clippy/main/index.html#needless_update +[`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/main/index.html#neg_cmp_op_on_partial_ord +[`neg_multiply`]: https://rust-lang.github.io/rust-clippy/main/index.html#neg_multiply +[`negative_feature_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#negative_feature_names +[`never_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#never_loop +[`new_ret_no_self`]: https://rust-lang.github.io/rust-clippy/main/index.html#new_ret_no_self +[`new_without_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#new_without_default +[`new_without_default_derive`]: https://rust-lang.github.io/rust-clippy/main/index.html#new_without_default_derive +[`no_effect`]: https://rust-lang.github.io/rust-clippy/main/index.html#no_effect +[`no_effect_replace`]: https://rust-lang.github.io/rust-clippy/main/index.html#no_effect_replace +[`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/main/index.html#no_effect_underscore_binding +[`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/main/index.html#no_mangle_with_rust_abi +[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_ascii_literal +[`non_canonical_clone_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_canonical_clone_impl +[`non_canonical_partial_ord_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_canonical_partial_ord_impl +[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_minimal_cfg +[`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_octal_unix_permissions +[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_send_fields_in_send_ty +[`non_std_lazy_statics`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_std_lazy_statics +[`non_zero_suggestions`]: https://rust-lang.github.io/rust-clippy/main/index.html#non_zero_suggestions +[`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/main/index.html#nonminimal_bool +[`nonnull_unchecked_on_box_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#nonnull_unchecked_on_box_ptr +[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/main/index.html#nonsensical_open_options +[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/main/index.html#nonstandard_macro_braces +[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/main/index.html#not_unsafe_ptr_arg_deref +[`obfuscated_if_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#obfuscated_if_else +[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/main/index.html#octal_escapes +[`ok_expect`]: https://rust-lang.github.io/rust-clippy/main/index.html#ok_expect +[`only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/main/index.html#only_used_in_recursion +[`op_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#op_ref +[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_and_then_some +[`option_as_ref_cloned`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_as_ref_cloned +[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_as_ref_deref +[`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_env_unwrap +[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_expect_used +[`option_filter_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_filter_map +[`option_if_let_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_if_let_else +[`option_map_or_err_ok`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_map_or_err_ok +[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_map_or_none +[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_map_unit_fn +[`option_map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_map_unwrap_or +[`option_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_map_unwrap_or_else +[`option_option`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_option +[`option_unwrap_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_unwrap_used +[`option_zip_none`]: https://rust-lang.github.io/rust-clippy/main/index.html#option_zip_none +[`or_fun_call`]: https://rust-lang.github.io/rust-clippy/main/index.html#or_fun_call +[`or_then_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#or_then_unwrap +[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/main/index.html#out_of_bounds_indexing +[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/main/index.html#overflow_check_conditional +[`overly_complex_bool_expr`]: https://rust-lang.github.io/rust-clippy/main/index.html#overly_complex_bool_expr +[`owned_cow`]: https://rust-lang.github.io/rust-clippy/main/index.html#owned_cow +[`panic`]: https://rust-lang.github.io/rust-clippy/main/index.html#panic +[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#panic_in_result_fn +[`panic_params`]: https://rust-lang.github.io/rust-clippy/main/index.html#panic_params +[`panicking_overflow_checks`]: https://rust-lang.github.io/rust-clippy/main/index.html#panicking_overflow_checks +[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#panicking_unwrap +[`partial_pub_fields`]: https://rust-lang.github.io/rust-clippy/main/index.html#partial_pub_fields +[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#partialeq_ne_impl +[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/main/index.html#partialeq_to_none +[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/main/index.html#path_buf_push_overwrite +[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/main/index.html#path_ends_with_ext +[`pathbuf_init_then_push`]: https://rust-lang.github.io/rust-clippy/main/index.html#pathbuf_init_then_push +[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/main/index.html#pattern_type_mismatch +[`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/main/index.html#permissions_set_readonly_false +[`pointer_format`]: https://rust-lang.github.io/rust-clippy/main/index.html#pointer_format +[`pointers_in_nomem_asm_block`]: https://rust-lang.github.io/rust-clippy/main/index.html#pointers_in_nomem_asm_block +[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/main/index.html#positional_named_format_parameters +[`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/main/index.html#possible_missing_comma +[`possible_missing_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#possible_missing_else +[`precedence`]: https://rust-lang.github.io/rust-clippy/main/index.html#precedence +[`precedence_bits`]: https://rust-lang.github.io/rust-clippy/main/index.html#precedence_bits +[`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#print_in_format_impl +[`print_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#print_literal +[`print_stderr`]: https://rust-lang.github.io/rust-clippy/main/index.html#print_stderr +[`print_stdout`]: https://rust-lang.github.io/rust-clippy/main/index.html#print_stdout +[`print_with_newline`]: https://rust-lang.github.io/rust-clippy/main/index.html#print_with_newline +[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#println_empty_string +[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_arg +[`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_as_ptr +[`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_cast_constness +[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_eq +[`ptr_offset_by_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_offset_by_literal +[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/main/index.html#ptr_offset_with_cast +[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#pub_enum_variant_names +[`pub_underscore_fields`]: https://rust-lang.github.io/rust-clippy/main/index.html#pub_underscore_fields +[`pub_use`]: https://rust-lang.github.io/rust-clippy/main/index.html#pub_use +[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/main/index.html#pub_with_shorthand +[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/main/index.html#pub_without_shorthand +[`question_mark`]: https://rust-lang.github.io/rust-clippy/main/index.html#question_mark +[`question_mark_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#question_mark_used +[`range_minus_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#range_minus_one +[`range_plus_one`]: https://rust-lang.github.io/rust-clippy/main/index.html#range_plus_one +[`range_step_by_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#range_step_by_zero +[`range_zip_with_len`]: https://rust-lang.github.io/rust-clippy/main/index.html#range_zip_with_len +[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/main/index.html#rc_buffer +[`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/main/index.html#rc_clone_in_vec_init +[`rc_mutex`]: https://rust-lang.github.io/rust-clippy/main/index.html#rc_mutex +[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/main/index.html#read_line_without_trim +[`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/main/index.html#read_zero_byte_vec +[`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/main/index.html#readonly_write_lock +[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#recursive_format_impl +[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_allocation +[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_as_str +[`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_async_block +[`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_at_rest_pattern +[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_clone +[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_closure +[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_closure_call +[`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_closure_for_method_calls +[`redundant_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_comparisons +[`redundant_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_else +[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_feature_names +[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_field_names +[`redundant_guards`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_guards +[`redundant_iter_cloned`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_iter_cloned +[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_locals +[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_pattern +[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_pattern_matching +[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_pub_crate +[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_slicing +[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_static_lifetimes +[`redundant_test_prefix`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_test_prefix +[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/main/index.html#redundant_type_annotations +[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_as_ptr +[`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_binding_to_reference +[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_in_deref +[`ref_option`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_option +[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_option_ref +[`ref_patterns`]: https://rust-lang.github.io/rust-clippy/main/index.html#ref_patterns +[`regex_creation_in_loops`]: https://rust-lang.github.io/rust-clippy/main/index.html#regex_creation_in_loops +[`regex_macro`]: https://rust-lang.github.io/rust-clippy/main/index.html#regex_macro +[`renamed_function_params`]: https://rust-lang.github.io/rust-clippy/main/index.html#renamed_function_params +[`repeat_once`]: https://rust-lang.github.io/rust-clippy/main/index.html#repeat_once +[`repeat_vec_with_capacity`]: https://rust-lang.github.io/rust-clippy/main/index.html#repeat_vec_with_capacity +[`replace_box`]: https://rust-lang.github.io/rust-clippy/main/index.html#replace_box +[`replace_consts`]: https://rust-lang.github.io/rust-clippy/main/index.html#replace_consts +[`repr_packed_without_abi`]: https://rust-lang.github.io/rust-clippy/main/index.html#repr_packed_without_abi +[`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/main/index.html#reserve_after_initialization +[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/main/index.html#rest_pat_in_fully_bound_structs +[`rest_pattern_accessible_field`]: https://rust-lang.github.io/rust-clippy/main/index.html#rest_pattern_accessible_field +[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_expect_used +[`result_filter_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_filter_map +[`result_large_err`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_large_err +[`result_map_or_into_option`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_map_or_into_option +[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_map_unit_fn +[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_map_unwrap_or_else +[`result_unit_err`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_unit_err +[`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#result_unwrap_used +[`return_and_then`]: https://rust-lang.github.io/rust-clippy/main/index.html#return_and_then +[`return_self_not_must_use`]: https://rust-lang.github.io/rust-clippy/main/index.html#return_self_not_must_use +[`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#reverse_range_loop +[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/main/index.html#reversed_empty_ranges +[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/main/index.html#same_functions_in_if_condition +[`same_item_push`]: https://rust-lang.github.io/rust-clippy/main/index.html#same_item_push +[`same_length_and_capacity`]: https://rust-lang.github.io/rust-clippy/main/index.html#same_length_and_capacity +[`same_name_method`]: https://rust-lang.github.io/rust-clippy/main/index.html#same_name_method +[`search_is_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#search_is_some +[`seek_from_current`]: https://rust-lang.github.io/rust-clippy/main/index.html#seek_from_current +[`seek_to_start_instead_of_rewind`]: https://rust-lang.github.io/rust-clippy/main/index.html#seek_to_start_instead_of_rewind +[`self_assignment`]: https://rust-lang.github.io/rust-clippy/main/index.html#self_assignment +[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/main/index.html#self_named_constructors +[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/main/index.html#self_named_module_files +[`self_only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/main/index.html#self_only_used_in_recursion +[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/main/index.html#semicolon_if_nothing_returned +[`semicolon_inside_block`]: https://rust-lang.github.io/rust-clippy/main/index.html#semicolon_inside_block +[`semicolon_outside_block`]: https://rust-lang.github.io/rust-clippy/main/index.html#semicolon_outside_block +[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/main/index.html#separated_literal_suffix +[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/main/index.html#serde_api_misuse +[`set_contains_or_insert`]: https://rust-lang.github.io/rust-clippy/main/index.html#set_contains_or_insert +[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/main/index.html#shadow_reuse +[`shadow_same`]: https://rust-lang.github.io/rust-clippy/main/index.html#shadow_same +[`shadow_unrelated`]: https://rust-lang.github.io/rust-clippy/main/index.html#shadow_unrelated +[`short_circuit_statement`]: https://rust-lang.github.io/rust-clippy/main/index.html#short_circuit_statement +[`should_assert_eq`]: https://rust-lang.github.io/rust-clippy/main/index.html#should_assert_eq +[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/main/index.html#should_implement_trait +[`should_panic_without_expect`]: https://rust-lang.github.io/rust-clippy/main/index.html#should_panic_without_expect +[`significant_drop_in_scrutinee`]: https://rust-lang.github.io/rust-clippy/main/index.html#significant_drop_in_scrutinee +[`significant_drop_tightening`]: https://rust-lang.github.io/rust-clippy/main/index.html#significant_drop_tightening +[`similar_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#similar_names +[`single_call_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_call_fn +[`single_char_add_str`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_char_add_str +[`single_char_lifetime_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_char_lifetime_names +[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_char_pattern +[`single_char_push_str`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_char_push_str +[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_component_path_imports +[`single_element_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_element_loop +[`single_match`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_match +[`single_match_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_match_else +[`single_option_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_option_map +[`single_range_in_vec_init`]: https://rust-lang.github.io/rust-clippy/main/index.html#single_range_in_vec_init +[`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/main/index.html#size_of_in_element_count +[`size_of_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#size_of_ref +[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/main/index.html#skip_while_next +[`sliced_string_as_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#sliced_string_as_bytes +[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/main/index.html#slow_vector_initialization +[`some_filter`]: https://rust-lang.github.io/rust-clippy/main/index.html#some_filter +[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/main/index.html#stable_sort_primitive +[`std_instead_of_alloc`]: https://rust-lang.github.io/rust-clippy/main/index.html#std_instead_of_alloc +[`std_instead_of_core`]: https://rust-lang.github.io/rust-clippy/main/index.html#std_instead_of_core +[`str_split_at_newline`]: https://rust-lang.github.io/rust-clippy/main/index.html#str_split_at_newline +[`str_to_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#str_to_string +[`string_add`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_add +[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_add_assign +[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_extend_chars +[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_from_utf8_as_bytes +[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_lit_as_bytes +[`string_lit_chars_any`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_lit_chars_any +[`string_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_slice +[`string_to_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#string_to_string +[`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/main/index.html#strlen_on_c_strings +[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/main/index.html#struct_excessive_bools +[`struct_field_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#struct_field_names +[`stutter`]: https://rust-lang.github.io/rust-clippy/main/index.html#stutter +[`suboptimal_flops`]: https://rust-lang.github.io/rust-clippy/main/index.html#suboptimal_flops +[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_arithmetic_impl +[`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_assignment_formatting +[`suspicious_command_arg_space`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_command_arg_space +[`suspicious_doc_comments`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_doc_comments +[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_else_formatting +[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_map +[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_op_assign_impl +[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_open_options +[`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_operation_groupings +[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_splitn +[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_to_owned +[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_unary_op_formatting +[`suspicious_xor_used_as_pow`]: https://rust-lang.github.io/rust-clippy/main/index.html#suspicious_xor_used_as_pow +[`swap_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#swap_ptr_to_ref +[`swap_with_temporary`]: https://rust-lang.github.io/rust-clippy/main/index.html#swap_with_temporary +[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/main/index.html#tabs_in_doc_comments +[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/main/index.html#temporary_assignment +[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#temporary_cstring_as_ptr +[`test_attr_in_doctest`]: https://rust-lang.github.io/rust-clippy/main/index.html#test_attr_in_doctest +[`tests_outside_test_module`]: https://rust-lang.github.io/rust-clippy/main/index.html#tests_outside_test_module +[`thread_local_initializer_can_be_made_const`]: https://rust-lang.github.io/rust-clippy/main/index.html#thread_local_initializer_can_be_made_const +[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/main/index.html#to_digit_is_some +[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/main/index.html#to_string_in_display +[`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/main/index.html#to_string_in_format_args +[`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#to_string_trait_impl +[`todo`]: https://rust-lang.github.io/rust-clippy/main/index.html#todo +[`too_long_first_doc_paragraph`]: https://rust-lang.github.io/rust-clippy/main/index.html#too_long_first_doc_paragraph +[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/main/index.html#too_many_arguments +[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/main/index.html#too_many_lines +[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/main/index.html#toplevel_ref_arg +[`trailing_empty_array`]: https://rust-lang.github.io/rust-clippy/main/index.html#trailing_empty_array +[`trait_duplication_in_bounds`]: https://rust-lang.github.io/rust-clippy/main/index.html#trait_duplication_in_bounds +[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_bytes_to_str +[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_float_to_int +[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_int_to_bool +[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_int_to_char +[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_int_to_float +[`transmute_int_to_non_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_int_to_non_zero +[`transmute_null_to_fn`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_null_to_fn +[`transmute_num_to_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_num_to_bytes +[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_ptr_to_ptr +[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_ptr_to_ref +[`transmute_undefined_repr`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmute_undefined_repr +[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmutes_expressible_as_ptr_casts +[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/main/index.html#transmuting_null +[`trim_split_whitespace`]: https://rust-lang.github.io/rust-clippy/main/index.html#trim_split_whitespace +[`trivial_regex`]: https://rust-lang.github.io/rust-clippy/main/index.html#trivial_regex +[`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/main/index.html#trivially_copy_pass_by_ref +[`try_err`]: https://rust-lang.github.io/rust-clippy/main/index.html#try_err +[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/main/index.html#tuple_array_conversions +[`type_complexity`]: https://rust-lang.github.io/rust-clippy/main/index.html#type_complexity +[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/main/index.html#type_id_on_box +[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/main/index.html#type_repetition_in_bounds +[`unbuffered_bytes`]: https://rust-lang.github.io/rust-clippy/main/index.html#unbuffered_bytes +[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/main/index.html#unchecked_duration_subtraction +[`unchecked_time_subtraction`]: https://rust-lang.github.io/rust-clippy/main/index.html#unchecked_time_subtraction +[`unconditional_recursion`]: https://rust-lang.github.io/rust-clippy/main/index.html#unconditional_recursion +[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/main/index.html#undocumented_unsafe_blocks +[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/main/index.html#undropped_manually_drops +[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/main/index.html#unicode_not_nfc +[`unimplemented`]: https://rust-lang.github.io/rust-clippy/main/index.html#unimplemented +[`uninhabited_references`]: https://rust-lang.github.io/rust-clippy/main/index.html#uninhabited_references +[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/main/index.html#uninit_assumed_init +[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/main/index.html#uninit_vec +[`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/main/index.html#uninlined_format_args +[`unit_arg`]: https://rust-lang.github.io/rust-clippy/main/index.html#unit_arg +[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/main/index.html#unit_cmp +[`unit_hash`]: https://rust-lang.github.io/rust-clippy/main/index.html#unit_hash +[`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/main/index.html#unit_return_expecting_ord +[`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/main/index.html#unknown_clippy_lints +[`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_box_returns +[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_cast +[`unnecessary_clippy_cfg`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_clippy_cfg +[`unnecessary_debug_formatting`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_debug_formatting +[`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_fallible_conversions +[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_filter_map +[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_find_map +[`unnecessary_first_then_check`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_first_then_check +[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_fold +[`unnecessary_get_then_check`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_get_then_check +[`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_join +[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_lazy_evaluations +[`unnecessary_literal_bound`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_literal_bound +[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_literal_unwrap +[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_map_on_constructor +[`unnecessary_map_or`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_map_or +[`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_min_or_max +[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_mut_passed +[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_operation +[`unnecessary_option_map_or_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_option_map_or_else +[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_owned_empty_strings +[`unnecessary_rest_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_rest_pattern +[`unnecessary_result_map_or_else`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_result_map_or_else +[`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_safety_comment +[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_safety_doc +[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_self_imports +[`unnecessary_semicolon`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_semicolon +[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_sort_by +[`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_struct_initialization +[`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_to_owned +[`unnecessary_trailing_comma`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_trailing_comma +[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_unwrap +[`unnecessary_unwrap_unchecked`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_unwrap_unchecked +[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_wraps +[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#unneeded_field_pattern +[`unneeded_struct_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#unneeded_struct_pattern +[`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/main/index.html#unneeded_wildcard_pattern +[`unnested_or_patterns`]: https://rust-lang.github.io/rust-clippy/main/index.html#unnested_or_patterns +[`unreachable`]: https://rust-lang.github.io/rust-clippy/main/index.html#unreachable +[`unreadable_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#unreadable_literal +[`unsafe_derive_deserialize`]: https://rust-lang.github.io/rust-clippy/main/index.html#unsafe_derive_deserialize +[`unsafe_removed_from_name`]: https://rust-lang.github.io/rust-clippy/main/index.html#unsafe_removed_from_name +[`unsafe_vector_initialization`]: https://rust-lang.github.io/rust-clippy/main/index.html#unsafe_vector_initialization +[`unseparated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/main/index.html#unseparated_literal_suffix +[`unsound_collection_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#unsound_collection_transmute +[`unstable_as_mut_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#unstable_as_mut_slice +[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/main/index.html#unstable_as_slice +[`unused_async`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_async +[`unused_async_trait_impl`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_async_trait_impl +[`unused_collect`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_collect +[`unused_enumerate_index`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_enumerate_index +[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_format_specs +[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_io_amount +[`unused_label`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_label +[`unused_peekable`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_peekable +[`unused_result_ok`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_result_ok +[`unused_rounding`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_rounding +[`unused_self`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_self +[`unused_trait_names`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_trait_names +[`unused_unit`]: https://rust-lang.github.io/rust-clippy/main/index.html#unused_unit +[`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/main/index.html#unusual_byte_groupings +[`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_in_result +[`unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_or_default +[`unwrap_or_else_default`]: https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_or_else_default +[`unwrap_used`]: https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_used +[`upper_case_acronyms`]: https://rust-lang.github.io/rust-clippy/main/index.html#upper_case_acronyms +[`use_debug`]: https://rust-lang.github.io/rust-clippy/main/index.html#use_debug +[`use_self`]: https://rust-lang.github.io/rust-clippy/main/index.html#use_self +[`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/main/index.html#used_underscore_binding +[`used_underscore_items`]: https://rust-lang.github.io/rust-clippy/main/index.html#used_underscore_items +[`useless_asref`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_asref +[`useless_attribute`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_attribute +[`useless_borrows_in_formatting`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_borrows_in_formatting +[`useless_concat`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_concat +[`useless_conversion`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_conversion +[`useless_format`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_format +[`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_let_if_seq +[`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_nonzero_new_unchecked +[`useless_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_transmute +[`useless_vec`]: https://rust-lang.github.io/rust-clippy/main/index.html#useless_vec +[`vec_box`]: https://rust-lang.github.io/rust-clippy/main/index.html#vec_box +[`vec_init_then_push`]: https://rust-lang.github.io/rust-clippy/main/index.html#vec_init_then_push +[`vec_resize_to_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#vec_resize_to_zero +[`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/main/index.html#verbose_bit_mask +[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/main/index.html#verbose_file_reads +[`volatile_composites`]: https://rust-lang.github.io/rust-clippy/main/index.html#volatile_composites +[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/main/index.html#vtable_address_comparisons +[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/main/index.html#waker_clone_wake +[`while_float`]: https://rust-lang.github.io/rust-clippy/main/index.html#while_float +[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/main/index.html#while_immutable_condition +[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/main/index.html#while_let_loop +[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/main/index.html#while_let_on_iterator +[`wildcard_dependencies`]: https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_dependencies +[`wildcard_enum_match_arm`]: https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_enum_match_arm +[`wildcard_imports`]: https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_imports +[`wildcard_in_or_patterns`]: https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_in_or_patterns +[`with_capacity_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#with_capacity_zero +[`write_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#write_literal +[`write_with_newline`]: https://rust-lang.github.io/rust-clippy/main/index.html#write_with_newline +[`writeln_empty_string`]: https://rust-lang.github.io/rust-clippy/main/index.html#writeln_empty_string +[`wrong_pub_self_convention`]: https://rust-lang.github.io/rust-clippy/main/index.html#wrong_pub_self_convention +[`wrong_self_convention`]: https://rust-lang.github.io/rust-clippy/main/index.html#wrong_self_convention +[`wrong_transmute`]: https://rust-lang.github.io/rust-clippy/main/index.html#wrong_transmute +[`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_divided_by_zero +[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_prefixed_literal +[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_ptr +[`zero_repeat_side_effects`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_repeat_side_effects +[`zero_sized_map_values`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_sized_map_values +[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/main/index.html#zero_width_space +[`zombie_processes`]: https://rust-lang.github.io/rust-clippy/main/index.html#zombie_processes +[`zst_offset`]: https://rust-lang.github.io/rust-clippy/main/index.html#zst_offset [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index fe9a2e3b7ad58..b6a70863e7104 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.99" +version = "0.1.100" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md index 6869cc56ed956..a782f4aca6c53 100644 --- a/src/tools/clippy/book/src/lint_configuration.md +++ b/src/tools/clippy/book/src/lint_configuration.md @@ -17,7 +17,7 @@ Which crates to allow absolute paths from --- **Affected lints:** -* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths) +* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/main/index.html#absolute_paths) ## `absolute-paths-max-segments` @@ -28,7 +28,7 @@ be linted. --- **Affected lints:** -* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths) +* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/main/index.html#absolute_paths) ## `accept-comment-above-attributes` @@ -38,7 +38,7 @@ Whether to accept a safety comment to be placed above the attributes for the `un --- **Affected lints:** -* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks) +* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/main/index.html#undocumented_unsafe_blocks) ## `accept-comment-above-statement` @@ -48,7 +48,7 @@ Whether to accept a safety comment to be placed above the statement containing t --- **Affected lints:** -* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks) +* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/main/index.html#undocumented_unsafe_blocks) ## `allow-comparison-to-zero` @@ -58,7 +58,7 @@ Don't lint when comparing the result of a modulo operation to zero. --- **Affected lints:** -* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic) +* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/main/index.html#modulo_arithmetic) ## `allow-dbg-in-tests` @@ -68,7 +68,7 @@ Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` --- **Affected lints:** -* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro) +* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/main/index.html#dbg_macro) ## `allow-exact-repetitions` @@ -78,7 +78,7 @@ Whether an item should be allowed to have the same name as its containing module --- **Affected lints:** -* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions) +* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/main/index.html#module_name_repetitions) ## `allow-expect-in-consts` @@ -88,7 +88,7 @@ Whether `expect` should be allowed in code always evaluated at compile time --- **Affected lints:** -* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) +* [`expect_used`](https://rust-lang.github.io/rust-clippy/main/index.html#expect_used) ## `allow-expect-in-tests` @@ -98,7 +98,7 @@ Whether `expect` should be allowed in test functions or `#[cfg(test)]` --- **Affected lints:** -* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) +* [`expect_used`](https://rust-lang.github.io/rust-clippy/main/index.html#expect_used) ## `allow-indexing-slicing-in-tests` @@ -108,7 +108,7 @@ Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]` --- **Affected lints:** -* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) +* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/main/index.html#indexing_slicing) ## `allow-large-stack-frames-in-tests` @@ -118,7 +118,7 @@ Whether functions inside `#[cfg(test)]` modules or test functions should be chec --- **Affected lints:** -* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/main/index.html#large_stack_frames) ## `allow-mixed-uninlined-format-args` @@ -128,7 +128,7 @@ Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar) --- **Affected lints:** -* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) +* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/main/index.html#uninlined_format_args) ## `allow-one-hash-in-raw-strings` @@ -138,7 +138,7 @@ Whether to allow `r#""#` when `r""` can be used --- **Affected lints:** -* [`needless_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes) +* [`needless_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/main/index.html#needless_raw_string_hashes) ## `allow-panic-in-tests` @@ -148,7 +148,7 @@ Whether `panic` should be allowed in test functions or `#[cfg(test)]` --- **Affected lints:** -* [`panic`](https://rust-lang.github.io/rust-clippy/master/index.html#panic) +* [`panic`](https://rust-lang.github.io/rust-clippy/main/index.html#panic) ## `allow-print-in-tests` @@ -158,8 +158,8 @@ Whether print macros (ex. `println!`) should be allowed in test functions or `#[ --- **Affected lints:** -* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr) -* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout) +* [`print_stderr`](https://rust-lang.github.io/rust-clippy/main/index.html#print_stderr) +* [`print_stdout`](https://rust-lang.github.io/rust-clippy/main/index.html#print_stdout) ## `allow-private-module-inception` @@ -169,7 +169,7 @@ Whether to allow module inception if it's not public. --- **Affected lints:** -* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception) +* [`module_inception`](https://rust-lang.github.io/rust-clippy/main/index.html#module_inception) ## `allow-renamed-params-for` @@ -191,7 +191,7 @@ default configuration of Clippy. By default, any configuration will replace the --- **Affected lints:** -* [`renamed_function_params`](https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params) +* [`renamed_function_params`](https://rust-lang.github.io/rust-clippy/main/index.html#renamed_function_params) ## `allow-unwrap-in-consts` @@ -201,7 +201,7 @@ Whether `unwrap` should be allowed in code always evaluated at compile time --- **Affected lints:** -* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) +* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_used) ## `allow-unwrap-in-tests` @@ -211,7 +211,7 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` --- **Affected lints:** -* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) +* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_used) ## `allow-unwrap-types` @@ -227,8 +227,8 @@ allow-unwrap-types = [ "std::sync::LockResult" ] --- **Affected lints:** -* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) -* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) +* [`expect_used`](https://rust-lang.github.io/rust-clippy/main/index.html#expect_used) +* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/main/index.html#unwrap_used) ## `allow-useless-vec-in-tests` @@ -238,7 +238,7 @@ Whether `useless_vec` should ignore test functions or `#[cfg(test)]` --- **Affected lints:** -* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec) +* [`useless_vec`](https://rust-lang.github.io/rust-clippy/main/index.html#useless_vec) ## `allowed-dotfiles` @@ -248,7 +248,7 @@ Additional dotfiles (files or directories starting with a dot) to allow --- **Affected lints:** -* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext) +* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/main/index.html#path_ends_with_ext) ## `allowed-duplicate-crates` @@ -258,7 +258,7 @@ A list of crate names to allow duplicates of --- **Affected lints:** -* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions) +* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/main/index.html#multiple_crate_versions) ## `allowed-idents-below-min-chars` @@ -270,7 +270,7 @@ configuration of Clippy. By default, any configuration will replace the default --- **Affected lints:** -* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) +* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/main/index.html#min_ident_chars) ## `allowed-prefixes` @@ -296,7 +296,7 @@ default configuration of Clippy. By default, any configuration will replace the --- **Affected lints:** -* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions) +* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/main/index.html#module_name_repetitions) ## `allowed-scripts` @@ -306,7 +306,7 @@ The list of unicode scripts allowed to be used in the scope. --- **Affected lints:** -* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents) +* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_script_idents) ## `allowed-wildcard-imports` @@ -328,7 +328,7 @@ are already allowed by default. --- **Affected lints:** -* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports) +* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_imports) ## `arithmetic-side-effects-allowed` @@ -351,7 +351,7 @@ A type, say `SomeType`, listed in this configuration has the same behavior of --- **Affected lints:** -* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/main/index.html#arithmetic_side_effects) ## `arithmetic-side-effects-allowed-binary` @@ -374,7 +374,7 @@ arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", --- **Affected lints:** -* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/main/index.html#arithmetic_side_effects) ## `arithmetic-side-effects-allowed-unary` @@ -390,7 +390,7 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] --- **Affected lints:** -* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/main/index.html#arithmetic_side_effects) ## `array-size-threshold` @@ -400,8 +400,8 @@ The maximum allowed size for arrays on the stack --- **Affected lints:** -* [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays) -* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays) +* [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/main/index.html#large_const_arrays) +* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/main/index.html#large_stack_arrays) ## `avoid-breaking-exported-api` @@ -411,25 +411,25 @@ Suppress lints whenever the suggested change would cause breakage for other crat --- **Affected lints:** -* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection) -* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) -* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) -* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist) -* [`needless_pass_by_ref_mut`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut) -* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option) -* [`owned_cow`](https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow) -* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer) -* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex) -* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation) -* [`ref_option`](https://rust-lang.github.io/rust-clippy/master/index.html#ref_option) -* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn) -* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) -* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) -* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps) -* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self) -* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) -* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) -* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention) +* [`box_collection`](https://rust-lang.github.io/rust-clippy/main/index.html#box_collection) +* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/main/index.html#enum_variant_names) +* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/main/index.html#large_types_passed_by_value) +* [`linkedlist`](https://rust-lang.github.io/rust-clippy/main/index.html#linkedlist) +* [`needless_pass_by_ref_mut`](https://rust-lang.github.io/rust-clippy/main/index.html#needless_pass_by_ref_mut) +* [`option_option`](https://rust-lang.github.io/rust-clippy/main/index.html#option_option) +* [`owned_cow`](https://rust-lang.github.io/rust-clippy/main/index.html#owned_cow) +* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/main/index.html#rc_buffer) +* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/main/index.html#rc_mutex) +* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/main/index.html#redundant_allocation) +* [`ref_option`](https://rust-lang.github.io/rust-clippy/main/index.html#ref_option) +* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/main/index.html#single_call_fn) +* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/main/index.html#trivially_copy_pass_by_ref) +* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_box_returns) +* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_wraps) +* [`unused_self`](https://rust-lang.github.io/rust-clippy/main/index.html#unused_self) +* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/main/index.html#upper_case_acronyms) +* [`vec_box`](https://rust-lang.github.io/rust-clippy/main/index.html#vec_box) +* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/main/index.html#wrong_self_convention) ## `await-holding-invalid-types` @@ -439,7 +439,7 @@ The list of types which may not be held across an await point. --- **Affected lints:** -* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type) +* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/main/index.html#await_holding_invalid_type) ## `cargo-ignore-publish` @@ -449,7 +449,7 @@ For internal testing only, ignores the current `publish` settings in the Cargo m --- **Affected lints:** -* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata) +* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/main/index.html#cargo_common_metadata) ## `check-grouped-late-init` @@ -480,7 +480,7 @@ let (a, b) = if true { --- **Affected lints:** -* [`needless_late_init`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init) +* [`needless_late_init`](https://rust-lang.github.io/rust-clippy/main/index.html#needless_late_init) ## `check-incompatible-msrv-in-tests` @@ -490,7 +490,7 @@ Whether to check MSRV compatibility in `#[test]` and `#[cfg(test)]` code. --- **Affected lints:** -* [`incompatible_msrv`](https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv) +* [`incompatible_msrv`](https://rust-lang.github.io/rust-clippy/main/index.html#incompatible_msrv) ## `check-inconsistent-struct-field-initializers` @@ -517,7 +517,7 @@ fn main() { --- **Affected lints:** -* [`inconsistent_struct_constructor`](https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor) +* [`inconsistent_struct_constructor`](https://rust-lang.github.io/rust-clippy/main/index.html#inconsistent_struct_constructor) ## `check-private-items` @@ -527,10 +527,10 @@ Whether to also run the listed lints on private items. --- **Affected lints:** -* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc) -* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc) -* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc) -* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc) +* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_errors_doc) +* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_panics_doc) +* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_safety_doc) +* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_safety_doc) ## `cognitive-complexity-threshold` @@ -540,7 +540,7 @@ The maximum cognitive complexity a function can have --- **Affected lints:** -* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity) +* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/main/index.html#cognitive_complexity) ## `const-literal-digits-threshold` @@ -550,7 +550,7 @@ The minimum digits a const float literal must have to supress the `excessive_pre --- **Affected lints:** -* [`excessive_precision`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision) +* [`excessive_precision`](https://rust-lang.github.io/rust-clippy/main/index.html#excessive_precision) ## `disallowed-fields` @@ -567,7 +567,7 @@ The list of disallowed fields, written as fully qualified paths. --- **Affected lints:** -* [`disallowed_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_fields) +* [`disallowed_fields`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_fields) ## `disallowed-macros` @@ -584,7 +584,7 @@ The list of disallowed macros, written as fully qualified paths. --- **Affected lints:** -* [`disallowed_macros`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros) +* [`disallowed_macros`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_macros) ## `disallowed-methods` @@ -601,7 +601,7 @@ The list of disallowed methods, written as fully qualified paths. --- **Affected lints:** -* [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods) +* [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_methods) ## `disallowed-names` @@ -613,7 +613,7 @@ default configuration of Clippy. By default, any configuration will replace the --- **Affected lints:** -* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names) +* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_names) ## `disallowed-types` @@ -630,7 +630,7 @@ The list of disallowed types, written as fully qualified paths. --- **Affected lints:** -* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types) +* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/main/index.html#disallowed_types) ## `doc-valid-idents` @@ -640,11 +640,11 @@ default configuration of Clippy. By default, any configuration will replace the * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "InfiniBand", "RoCE", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "PowerPC", "PowerShell", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "SQLite", "MySQL", "PostgreSQL", "MariaDB", "MongoDB", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "InfiniBand", "RoCE", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "PowerPC", "PowerShell", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "SQLite", "MySQL", "PostgreSQL", "MariaDB", "MongoDB", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebAuthn", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` --- **Affected lints:** -* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown) +* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/main/index.html#doc_markdown) ## `enable-raw-pointer-heuristic-for-send` @@ -654,7 +654,7 @@ Whether to apply the raw pointer heuristic to determine if a type is `Send`. --- **Affected lints:** -* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty) +* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/main/index.html#non_send_fields_in_send_ty) ## `enforce-iter-loop-reborrow` @@ -680,7 +680,7 @@ for _ in &mut *rmvec {} --- **Affected lints:** -* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop) +* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/main/index.html#explicit_iter_loop) ## `enforced-import-renames` @@ -690,7 +690,7 @@ The list of imports to always rename, a fully qualified path followed by the ren --- **Affected lints:** -* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames) +* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_enforced_import_renames) ## `enum-variant-name-threshold` @@ -700,7 +700,7 @@ The minimum number of enum variants for the lints about variant names to trigger --- **Affected lints:** -* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) +* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/main/index.html#enum_variant_names) ## `enum-variant-size-threshold` @@ -710,7 +710,7 @@ The maximum size of an enum's variant to avoid box suggestion --- **Affected lints:** -* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant) +* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/main/index.html#large_enum_variant) ## `excessive-nesting-threshold` @@ -720,7 +720,7 @@ The maximum amount of nesting a block can reside in --- **Affected lints:** -* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting) +* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/main/index.html#excessive_nesting) ## `future-size-threshold` @@ -730,7 +730,7 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large --- **Affected lints:** -* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures) +* [`large_futures`](https://rust-lang.github.io/rust-clippy/main/index.html#large_futures) ## `ignore-interior-mutability` @@ -740,10 +740,10 @@ A list of paths to types that should be treated as if they do not contain interi --- **Affected lints:** -* [`borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const) -* [`declare_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const) -* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond) -* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type) +* [`borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/main/index.html#borrow_interior_mutable_const) +* [`declare_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/main/index.html#declare_interior_mutable_const) +* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/main/index.html#ifs_same_cond) +* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/main/index.html#mutable_key_type) ## `inherent-impl-lint-scope` @@ -753,7 +753,7 @@ Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` --- **Affected lints:** -* [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl) +* [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/main/index.html#multiple_inherent_impl) ## `large-error-ignored` @@ -764,7 +764,7 @@ A list of paths to types that should be ignored as overly large `Err`-variants i --- **Affected lints:** -* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err) +* [`result_large_err`](https://rust-lang.github.io/rust-clippy/main/index.html#result_large_err) ## `large-error-threshold` @@ -774,7 +774,7 @@ The maximum size of the `Err`-variant in a `Result` returned from a function --- **Affected lints:** -* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err) +* [`result_large_err`](https://rust-lang.github.io/rust-clippy/main/index.html#result_large_err) ## `lint-commented-code` @@ -785,8 +785,8 @@ that would be collapsed. --- **Affected lints:** -* [`collapsible_else_if`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if) -* [`collapsible_if`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if) +* [`collapsible_else_if`](https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_else_if) +* [`collapsible_if`](https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_if) ## `literal-representation-threshold` @@ -796,7 +796,7 @@ The lower bound for linting decimal literals --- **Affected lints:** -* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation) +* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/main/index.html#decimal_literal_representation) ## `matches-for-let-else` @@ -807,7 +807,7 @@ be filtering for common types. --- **Affected lints:** -* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) +* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_let_else) ## `max-fn-params-bools` @@ -818,7 +818,7 @@ Use `0` to lint on any function with a bool parameter. --- **Affected lints:** -* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools) +* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/main/index.html#fn_params_excessive_bools) ## `max-include-file-size` @@ -828,7 +828,7 @@ The maximum size of a file included via `include_bytes!()` or `include_str!()`, --- **Affected lints:** -* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file) +* [`large_include_file`](https://rust-lang.github.io/rust-clippy/main/index.html#large_include_file) ## `max-struct-bools` @@ -838,7 +838,7 @@ The maximum number of bool fields a struct can have --- **Affected lints:** -* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools) +* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/main/index.html#struct_excessive_bools) ## `max-suggested-slice-pattern-length` @@ -850,7 +850,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. --- **Affected lints:** -* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) +* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/main/index.html#index_refutable_slice) ## `max-trait-bounds` @@ -860,7 +860,7 @@ The maximum number of bounds a trait can have to be linted --- **Affected lints:** -* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) +* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/main/index.html#type_repetition_in_bounds) ## `min-ident-chars-lint-trait-impl` @@ -870,7 +870,7 @@ Whether to lint idents that have too few chars even when following trait declara --- **Affected lints:** -* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) +* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/main/index.html#min_ident_chars) ## `min-ident-chars-threshold` @@ -880,7 +880,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted. --- **Affected lints:** -* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) +* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/main/index.html#min_ident_chars) ## `missing-docs-allow-unused` @@ -890,7 +890,7 @@ Whether to allow fields starting with an underscore to skip documentation requir --- **Affected lints:** -* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items) +* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_docs_in_private_items) ## `missing-docs-in-crate-items` @@ -901,7 +901,7 @@ crate. For example, `pub(crate)` items. --- **Affected lints:** -* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items) +* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_docs_in_private_items) ## `module-item-order-groupings` @@ -911,7 +911,7 @@ The named groupings of different source item kinds within modules. --- **Affected lints:** -* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering) +* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering) ## `module-items-ordered-within-groupings` @@ -924,7 +924,7 @@ This option can be configured to "all", "none", or a list of specific grouping n --- **Affected lints:** -* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering) +* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering) ## `msrv` @@ -934,90 +934,90 @@ The minimum rust version that the project supports. Defaults to the `rust-versio --- **Affected lints:** -* [`allow_attributes`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes) -* [`allow_attributes_without_reason`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason) -* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range) -* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant) -* [`assigning_clones`](https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones) -* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr) -* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned) -* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions) -* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied) -* [`collapsible_match`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match) -* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace) -* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr) -* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls) -* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect) -* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next) -* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into) -* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none) -* [`implicit_saturating_sub`](https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub) -* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) -* [`inefficient_to_string`](https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string) -* [`io_other_error`](https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error) -* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map) -* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants) -* [`len_zero`](https://rust-lang.github.io/rust-clippy/master/index.html#len_zero) -* [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok) -* [`manual_abs_diff`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff) -* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) -* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals) -* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) -* [`manual_div_ceil`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil) -* [`manual_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten) -* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one) -* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) -* [`manual_is_power_of_two`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two) -* [`manual_is_variant_and`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_variant_and) -* [`manual_isolate_lowest_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_isolate_lowest_one) -* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) -* [`manual_midpoint`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint) -* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) -* [`manual_noop_waker`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_noop_waker) -* [`manual_option_as_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice) -* [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison) -* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains) -* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) -* [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n) -* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain) -* [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill) -* [`manual_slice_size_calculation`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation) -* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once) -* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat) -* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip) -* [`manual_take`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_take) -* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold) -* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) -* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or) -* [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges) -* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro) -* [`mem_replace_option_with_some`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some) -* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default) -* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn) -* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow) -* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics) -* [`nonnull_unchecked_on_box_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#nonnull_unchecked_on_box_ptr) -* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref) -* [`or_fun_call`](https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call) -* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr) -* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark) -* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names) -* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes) -* [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity) -* [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push) -* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current) -* [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some) -* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref) -* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions) -* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) -* [`unchecked_time_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction) -* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) -* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations) -* [`unnecessary_unwrap`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap) -* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns) -* [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names) -* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self) -* [`zero_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr) +* [`allow_attributes`](https://rust-lang.github.io/rust-clippy/main/index.html#allow_attributes) +* [`allow_attributes_without_reason`](https://rust-lang.github.io/rust-clippy/main/index.html#allow_attributes_without_reason) +* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/main/index.html#almost_complete_range) +* [`approx_constant`](https://rust-lang.github.io/rust-clippy/main/index.html#approx_constant) +* [`assigning_clones`](https://rust-lang.github.io/rust-clippy/main/index.html#assigning_clones) +* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/main/index.html#borrow_as_ptr) +* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/main/index.html#cast_abs_to_unsigned) +* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/main/index.html#checked_conversions) +* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/main/index.html#cloned_instead_of_copied) +* [`collapsible_match`](https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_match) +* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/main/index.html#collapsible_str_replace) +* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/main/index.html#deprecated_cfg_attr) +* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/main/index.html#derivable_impls) +* [`err_expect`](https://rust-lang.github.io/rust-clippy/main/index.html#err_expect) +* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/main/index.html#filter_map_next) +* [`from_over_into`](https://rust-lang.github.io/rust-clippy/main/index.html#from_over_into) +* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/main/index.html#if_then_some_else_none) +* [`implicit_saturating_sub`](https://rust-lang.github.io/rust-clippy/main/index.html#implicit_saturating_sub) +* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/main/index.html#index_refutable_slice) +* [`inefficient_to_string`](https://rust-lang.github.io/rust-clippy/main/index.html#inefficient_to_string) +* [`io_other_error`](https://rust-lang.github.io/rust-clippy/main/index.html#io_other_error) +* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/main/index.html#iter_kv_map) +* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/main/index.html#legacy_numeric_constants) +* [`len_zero`](https://rust-lang.github.io/rust-clippy/main/index.html#len_zero) +* [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/main/index.html#lines_filter_map_ok) +* [`manual_abs_diff`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_abs_diff) +* [`manual_bits`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_bits) +* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_c_str_literals) +* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_clamp) +* [`manual_div_ceil`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_div_ceil) +* [`manual_flatten`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_flatten) +* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_hash_one) +* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_ascii_check) +* [`manual_is_power_of_two`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_power_of_two) +* [`manual_is_variant_and`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_is_variant_and) +* [`manual_isolate_lowest_one`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_isolate_lowest_one) +* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_let_else) +* [`manual_midpoint`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_midpoint) +* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_non_exhaustive) +* [`manual_noop_waker`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_noop_waker) +* [`manual_option_as_slice`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_option_as_slice) +* [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_pattern_char_comparison) +* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_range_contains) +* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_rem_euclid) +* [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_repeat_n) +* [`manual_retain`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_retain) +* [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_slice_fill) +* [`manual_slice_size_calculation`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_slice_size_calculation) +* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_split_once) +* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_str_repeat) +* [`manual_strip`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_strip) +* [`manual_take`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_take) +* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/main/index.html#manual_try_fold) +* [`map_clone`](https://rust-lang.github.io/rust-clippy/main/index.html#map_clone) +* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/main/index.html#map_unwrap_or) +* [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/main/index.html#map_with_unused_argument_over_ranges) +* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/main/index.html#match_like_matches_macro) +* [`mem_replace_option_with_some`](https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_option_with_some) +* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/main/index.html#mem_replace_with_default) +* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/main/index.html#missing_const_for_fn) +* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/main/index.html#needless_borrow) +* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/main/index.html#non_std_lazy_statics) +* [`nonnull_unchecked_on_box_ptr`](https://rust-lang.github.io/rust-clippy/main/index.html#nonnull_unchecked_on_box_ptr) +* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/main/index.html#option_as_ref_deref) +* [`or_fun_call`](https://rust-lang.github.io/rust-clippy/main/index.html#or_fun_call) +* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/main/index.html#ptr_as_ptr) +* [`question_mark`](https://rust-lang.github.io/rust-clippy/main/index.html#question_mark) +* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/main/index.html#redundant_field_names) +* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/main/index.html#redundant_static_lifetimes) +* [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/main/index.html#repeat_vec_with_capacity) +* [`same_item_push`](https://rust-lang.github.io/rust-clippy/main/index.html#same_item_push) +* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/main/index.html#seek_from_current) +* [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/main/index.html#to_digit_is_some) +* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/main/index.html#transmute_ptr_to_ref) +* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/main/index.html#tuple_array_conversions) +* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/main/index.html#type_repetition_in_bounds) +* [`unchecked_time_subtraction`](https://rust-lang.github.io/rust-clippy/main/index.html#unchecked_time_subtraction) +* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/main/index.html#uninlined_format_args) +* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_lazy_evaluations) +* [`unnecessary_unwrap`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_unwrap) +* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/main/index.html#unnested_or_patterns) +* [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/main/index.html#unused_trait_names) +* [`use_self`](https://rust-lang.github.io/rust-clippy/main/index.html#use_self) +* [`zero_ptr`](https://rust-lang.github.io/rust-clippy/main/index.html#zero_ptr) ## `pass-by-value-size-limit` @@ -1027,7 +1027,7 @@ The minimum size (in bytes) to consider a type for passing by reference instead --- **Affected lints:** -* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) +* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/main/index.html#large_types_passed_by_value) ## `pub-underscore-fields-behavior` @@ -1038,7 +1038,7 @@ exported visibility, or whether they are marked as "pub". --- **Affected lints:** -* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields) +* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/main/index.html#pub_underscore_fields) ## `recursive-self-in-type-definitions` @@ -1048,7 +1048,7 @@ Whether the type itself in a struct or enum should be replaced with `Self` when --- **Affected lints:** -* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self) +* [`use_self`](https://rust-lang.github.io/rust-clippy/main/index.html#use_self) ## `semicolon-inside-block-ignore-singleline` @@ -1058,7 +1058,7 @@ Whether to lint only if it's multiline. --- **Affected lints:** -* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block) +* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/main/index.html#semicolon_inside_block) ## `semicolon-outside-block-ignore-multiline` @@ -1068,7 +1068,7 @@ Whether to lint only if it's singleline. --- **Affected lints:** -* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block) +* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/main/index.html#semicolon_outside_block) ## `single-char-binding-names-threshold` @@ -1078,7 +1078,7 @@ The maximum number of single char bindings a scope may have --- **Affected lints:** -* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names) +* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/main/index.html#many_single_char_names) ## `source-item-ordering` @@ -1088,7 +1088,7 @@ Which kind of elements should be ordered internally, possible values being `enum --- **Affected lints:** -* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering) +* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering) ## `stack-size-threshold` @@ -1098,7 +1098,7 @@ The maximum allowed stack size for functions in bytes --- **Affected lints:** -* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/main/index.html#large_stack_frames) ## `standard-macro-braces` @@ -1112,7 +1112,7 @@ could be used with a full path two `MacroMatcher`s have to be added one with the --- **Affected lints:** -* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces) +* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/main/index.html#nonstandard_macro_braces) ## `struct-field-name-threshold` @@ -1122,7 +1122,7 @@ The minimum number of struct fields for the lints about field names to trigger --- **Affected lints:** -* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names) +* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/main/index.html#struct_field_names) ## `suppress-restriction-lint-in-const` @@ -1136,7 +1136,7 @@ if no suggestion can be made. --- **Affected lints:** -* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) +* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/main/index.html#indexing_slicing) ## `too-large-for-stack` @@ -1146,8 +1146,8 @@ The maximum size of objects (in bytes) that will be linted. Larger objects are o --- **Affected lints:** -* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local) -* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec) +* [`boxed_local`](https://rust-lang.github.io/rust-clippy/main/index.html#boxed_local) +* [`useless_vec`](https://rust-lang.github.io/rust-clippy/main/index.html#useless_vec) ## `too-many-arguments-threshold` @@ -1157,7 +1157,7 @@ The maximum number of argument a function or method can have --- **Affected lints:** -* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments) +* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/main/index.html#too_many_arguments) ## `too-many-lines-threshold` @@ -1167,7 +1167,7 @@ The maximum number of lines a function or method can have --- **Affected lints:** -* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines) +* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/main/index.html#too_many_lines) ## `trait-assoc-item-kinds-order` @@ -1177,7 +1177,7 @@ The order of associated items in traits. --- **Affected lints:** -* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering) +* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering) ## `trait-impl-item-order` @@ -1201,7 +1201,7 @@ trait-impl-item-order = "alphabetical_or_trait_item_ordering" --- **Affected lints:** -* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering) +* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/main/index.html#arbitrary_source_item_ordering) ## `trivial-copy-size-limit` @@ -1212,7 +1212,7 @@ reference. --- **Affected lints:** -* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) +* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/main/index.html#trivially_copy_pass_by_ref) ## `type-complexity-threshold` @@ -1222,7 +1222,7 @@ The maximum complexity a type can have --- **Affected lints:** -* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity) +* [`type_complexity`](https://rust-lang.github.io/rust-clippy/main/index.html#type_complexity) ## `unnecessary-box-size` @@ -1232,7 +1232,7 @@ The byte size a `T` in `Box` can have, below which it triggers the `clippy::u --- **Affected lints:** -* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) +* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/main/index.html#unnecessary_box_returns) ## `unreadable-literal-lint-fractions` @@ -1242,7 +1242,7 @@ Should the fraction of a decimal be linted to include separators. --- **Affected lints:** -* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal) +* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/main/index.html#unreadable_literal) ## `upper-case-acronyms-aggressive` @@ -1252,7 +1252,7 @@ Enables verbose mode. Triggers if there is more than one uppercase char next to --- **Affected lints:** -* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) +* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/main/index.html#upper_case_acronyms) ## `vec-box-size-threshold` @@ -1262,7 +1262,7 @@ The size of the boxed type in bytes, where boxing in a `Vec` is allowed --- **Affected lints:** -* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) +* [`vec_box`](https://rust-lang.github.io/rust-clippy/main/index.html#vec_box) ## `verbose-bit-mask-threshold` @@ -1272,7 +1272,7 @@ The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' --- **Affected lints:** -* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask) +* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/main/index.html#verbose_bit_mask) ## `warn-on-all-wildcard-imports` @@ -1283,7 +1283,7 @@ or for `pub use` reexports. --- **Affected lints:** -* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports) +* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/main/index.html#wildcard_imports) ## `warn-unsafe-macro-metavars-in-private-macros` @@ -1293,4 +1293,4 @@ Whether to also emit warnings for unsafe blocks with metavariable expansions in --- **Affected lints:** -* [`macro_metavars_in_unsafe`](https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe) +* [`macro_metavars_in_unsafe`](https://rust-lang.github.io/rust-clippy/main/index.html#macro_metavars_in_unsafe) diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml index d81431d58434f..e230f61d558a6 100644 --- a/src/tools/clippy/clippy_config/Cargo.toml +++ b/src/tools/clippy/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.99" +version = "0.1.100" edition = "2024" publish = false diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs index 13c73e9445818..7b2a7e0010f76 100644 --- a/src/tools/clippy/clippy_config/src/conf.rs +++ b/src/tools/clippy/clippy_config/src/conf.rs @@ -37,7 +37,7 @@ static DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", - "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", + "WebAuthn", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", diff --git a/src/tools/clippy/clippy_config/src/metadata.rs b/src/tools/clippy/clippy_config/src/metadata.rs index 740ba3750948b..415a7738011fc 100644 --- a/src/tools/clippy/clippy_config/src/metadata.rs +++ b/src/tools/clippy/clippy_config/src/metadata.rs @@ -34,7 +34,7 @@ impl ConfMetadata { .format_with("\n", |doc, f| f(&doc.strip_prefix(" ").unwrap_or(doc))), self.0.default, self.0.lints.iter().format_with("\n", |name, f| f(&format_args!( - "* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})" + "* [`{name}`](https://rust-lang.github.io/rust-clippy/main/index.html#{name})" ))), ) } diff --git a/src/tools/clippy/clippy_dev/src/generate.rs b/src/tools/clippy/clippy_dev/src/generate.rs index f1c3375e1c7c1..4d86da4ada580 100644 --- a/src/tools/clippy/clippy_dev/src/generate.rs +++ b/src/tools/clippy/clippy_dev/src/generate.rs @@ -11,7 +11,7 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u // Use that command to update this file and do not edit by hand.\n\ // Manual edits will be overwritten.\n\n"; -const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html"; +const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/main/index.html"; impl LintData<'_> { #[expect(clippy::too_many_lines)] diff --git a/src/tools/clippy/clippy_dev/src/setup/intellij.rs b/src/tools/clippy/clippy_dev/src/setup/intellij.rs index c56811ee0a01e..db4f0a7c23dbe 100644 --- a/src/tools/clippy/clippy_dev/src/setup/intellij.rs +++ b/src/tools/clippy/clippy_dev/src/setup/intellij.rs @@ -155,7 +155,6 @@ fn inject_deps_into_manifest( // etc let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1); - // println!("{new_manifest}"); let mut file = File::create(manifest_path)?; file.write_all(new_manifest.as_bytes())?; diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml index 893ab32d19c1b..dc6b27bf027ff 100644 --- a/src/tools/clippy/clippy_lints/Cargo.toml +++ b/src/tools/clippy/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.99" +version = "0.1.100" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index 3502b01eddab2..290738514b69d 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -188,7 +188,7 @@ fn clone_source_borrows_from_dest(cx: &LateContext<'_>, lhs: &Expr<'_>, call_spa .find(|stmt| { !matches!(stmt.kind, mir::StatementKind::StorageDead(_) | mir::StatementKind::StorageLive(_)) }) - && let mir::StatementKind::Assign(box (borrowed, _)) = &assignment.kind + && let mir::StatementKind::Assign((borrowed, _)) = &assignment.kind && let Some(borrowers) = borrow_map.get(&borrowed.local) { borrowers.contains(source.local) diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 0c6e3a0db71b8..23d5adfb201a4 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -572,9 +572,8 @@ impl PostExpansionEarlyAttributes { } impl EarlyLintPass for PostExpansionEarlyAttributes { - fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) { + fn check_crate(&mut self, cx: &EarlyContext<'_>, _krate: &ast::Crate) { blanket_clippy_restriction_lints::check_command_line(cx); - duplicated_attributes::check(cx, &krate.attrs); } fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { @@ -630,8 +629,15 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { } mixed_attributes_style::check(cx, item.span, &item.attrs); - duplicated_attributes::check(cx, &item.attrs); } - extract_msrv_attr!(); + fn check_attributes(&mut self, cx: &EarlyContext<'_>, attrs: &[Attribute]) { + self.msrv.check_attributes(attrs); + duplicated_attributes::check(cx, attrs); + msrvs::check_attrs(cx.sess(), attrs); + } + + fn check_attributes_post(&mut self, _cx: &EarlyContext<'_>, attrs: &[Attribute]) { + self.msrv.check_attributes_post(attrs); + } } diff --git a/src/tools/clippy/clippy_lints/src/bit_width.rs b/src/tools/clippy/clippy_lints/src/bit_width.rs index 0f740327b32a0..cd08188866ead 100644 --- a/src/tools/clippy/clippy_lints/src/bit_width.rs +++ b/src/tools/clippy/clippy_lints/src/bit_width.rs @@ -98,35 +98,29 @@ impl ManualBitWidth { impl LateLintPass<'_> for ManualBitWidth { fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { - if expr.span.in_external_macro(cx.sess().source_map()) { - return; - } - - match expr.kind { - // `T::BITS - n.leading_zeros()` - ExprKind::Binary(op, left, right) - if op.node == BinOpKind::Sub - && let ExprKind::MethodCall(leading_zeros, recv, [], _) = right.kind - && leading_zeros.ident.name == sym::leading_zeros - && let ExprKind::Path(QPath::TypeRelative(hir_ty, segment)) = left.kind - && segment.ident.name == sym::BITS - && let right_ty = cx.typeck_results().expr_ty(recv) - && let Some(right_int_kind) = get_int_kind(cx, right_ty) - && let left_ty = cx.typeck_results().node_type(hir_ty.hir_id) - && let Some(left_int_kind) = get_int_kind(cx, left_ty) - && self.msrv.meets(cx, msrvs::BIT_WIDTH) - && left.span.eq_ctxt(right.span) - && !is_from_proc_macro(cx, expr) => - { - if left_int_kind == right_int_kind { - // manual implementation of bit_width - emit_manual_bit_width(cx, recv, expr, right_int_kind); - } else { - // mismatched calling types - emit_type_mismatch(cx, recv, expr, right_int_kind); - } - }, - _ => {}, + // `T::BITS - n.leading_zeros()` + if let ExprKind::Binary(op, left, right) = expr.kind + && op.node == BinOpKind::Sub + && let ExprKind::MethodCall(leading_zeros, recv, [], _) = right.kind + && leading_zeros.ident.name == sym::leading_zeros + && let ExprKind::Path(QPath::TypeRelative(hir_ty, segment)) = left.kind + && segment.ident.name == sym::BITS + && !expr.span.in_external_macro(cx.sess().source_map()) + && let right_ty = cx.typeck_results().expr_ty(recv) + && let Some(right_int_kind) = get_int_kind(cx, right_ty) + && let left_ty = cx.typeck_results().node_type(hir_ty.hir_id) + && let Some(left_int_kind) = get_int_kind(cx, left_ty) + && self.msrv.meets(cx, msrvs::BIT_WIDTH) + && left.span.eq_ctxt(right.span) + && !is_from_proc_macro(cx, expr) + { + if left_int_kind == right_int_kind { + // manual implementation of bit_width + emit_manual_bit_width(cx, recv, expr, right_int_kind); + } else { + // mismatched calling types + emit_type_mismatch(cx, recv, expr, right_int_kind); + } } } } diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs index 4de35746d6452..b3cdde3385fba 100644 --- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs +++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs @@ -1,8 +1,8 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_block_with_applicability; use clippy_utils::{contains_return, higher, is_from_proc_macro, leaks_droppable_temporary}; use rustc_errors::Applicability; -use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource}; +use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource, Node}; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; declare_clippy_lint! { @@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions { BLOCKS_IN_CONDITIONS, cond.span, BRACED_EXPR_MESSAGE, - "try", + "remove the braces", snippet_block_with_applicability(cx, ex.span, "..", Some(expr.span), &mut applicability), applicability, ); @@ -116,19 +116,35 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions { if span.from_expansion() || is_from_proc_macro(cx, cond) { return; } - // move block higher - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( + + span_lint_and_then( cx, BLOCKS_IN_CONDITIONS, expr.span.with_hi(cond.span.hi()), complex_block_message, - "try", - format!( - "let res = {}; {keyword} res", - snippet_block_with_applicability(cx, block.span, "..", Some(expr.span), &mut applicability), - ), - applicability, + |diag| { + // Only suggest fix where let binding is easy to apply i.e. parent node is a block. + // See issue #17068 + if let Node::Block(_) | Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id) { + // move block higher + let mut applicability = Applicability::MachineApplicable; + diag.span_suggestion( + expr.span.with_hi(cond.span.hi()), + "use a binding instead", + format!( + "let res = {}; {keyword} res", + snippet_block_with_applicability( + cx, + block.span, + "..", + Some(expr.span), + &mut applicability + ), + ), + applicability, + ); + } + }, ); } } diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs index 0591afaa6c585..f758fb0042301 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs @@ -184,16 +184,18 @@ fn offer_suggestion( diag: &mut Diag<'_, ()>, ) { let cast_to_snip = snippet(cx, cast_to_span, ".."); + let mut applicability = Applicability::Unspecified; + let sugg = Sugg::hir_with_context(cx, cast_expr, expr.span.ctxt(), "..", &mut applicability); let suggestion = if cast_to_snip == "_" { - format!("{}.try_into()", Sugg::hir(cx, cast_expr, "..").maybe_paren()) + format!("{}.try_into()", sugg.maybe_paren()) } else { - format!("{cast_to_snip}::try_from({})", Sugg::hir(cx, cast_expr, "..")) + format!("{cast_to_snip}::try_from({sugg})") }; diag.span_suggestion_verbose( expr.span, "... or use `try_from` and handle the error accordingly", suggestion, - Applicability::Unspecified, + applicability, ); } diff --git a/src/tools/clippy/clippy_lints/src/combined_early_pass.rs b/src/tools/clippy/clippy_lints/src/combined_early_pass.rs index 7494711c1f240..8c01237720a29 100644 --- a/src/tools/clippy/clippy_lints/src/combined_early_pass.rs +++ b/src/tools/clippy/clippy_lints/src/combined_early_pass.rs @@ -10,7 +10,7 @@ //! method disappears entirely, and the passes that do override become direct, //! inlined calls. No vtable, no per-node dynamic dispatch. //! -//! Unlike the late combine there is no `active` gate. rustc drops fully-disabled +//! Unlike the late combine fields are not optional. rustc drops fully-disabled //! late passes via `skippable_lints`, but the early pass runner has //! no such filtering, so a plain forward is equivalent and loses nothing. //! @@ -79,8 +79,8 @@ macro_rules! combined_early_lint_pass { } fn get_lints(&self) -> rustc_lint::LintVec { // Reserve at least one slot per pass up front to skip the early reallocations. - let mut lints = Vec::with_capacity([$(stringify!($field)),*].len()); - $(lints.extend(self.$field.get_lints());)* + let mut lints = Vec::with_capacity(${count($field)}); + $(lints.extend(<$fty>::lint_vec());)* lints } } diff --git a/src/tools/clippy/clippy_lints/src/combined_late_pass.rs b/src/tools/clippy/clippy_lints/src/combined_late_pass.rs index 135603fd15d08..54aec34d61790 100644 --- a/src/tools/clippy/clippy_lints/src/combined_late_pass.rs +++ b/src/tools/clippy/clippy_lints/src/combined_late_pass.rs @@ -5,26 +5,11 @@ //! concrete types and `#[inline(always)]`, unoverridden methods are DCE'd and the //! rest become direct calls, so there is no vtable or per-node dynamic dispatch. //! -//! Mirrors rustc's `declare_combined_late_lint_pass!`, but wraps each field in -//! [`Gated`] with a precomputed `active` flag (the same "lint still needs to run" -//! predicate `rustc_lint::late` uses). Disabled passes are skipped by a branch -//! rather than dropped from a `Vec`, keeping clippy's allow-by-default fast path. - -use rustc_lint::{LintPass, LintVec}; - -/// A pass paired with its precomputed "still needs to run" flag. -pub struct Gated

{ - pub(crate) active: bool, - pub(crate) pass: P, -} - -impl Gated

{ - #[inline] - pub fn new bool>(is_active: &F, pass: P) -> Self { - let active = is_active(&pass.get_lints()); - Gated { active, pass } - } -} +//! Mirrors rustc's `declare_combined_late_lint_pass!`, but wraps each field in an +//! `Option` that is set to `None` if a pass can be skipped (determined by the same +//! "lint still needs to run" predicate `rustc_lint::late` uses). Disabled passes +//! are skipped by a branch rather than dropped from a `Vec`, keeping clippy's +//! allow-by-default fast path. /// Run one field's `check_*`, if that field is active. /// @@ -36,8 +21,8 @@ impl Gated

{ #[macro_export] macro_rules! run_combined_late_lint_pass_field { ($self:ident, $field:ident, $name:ident, ($($arg:expr),* $(,)?)) => { - if $self.$field.active { - rustc_lint::LateLintPass::$name(&mut $self.$field.pass, $($arg),*); + if let Some(pass) = &mut $self.$field { + rustc_lint::LateLintPass::$name(pass, $($arg),*); } }; } @@ -61,7 +46,7 @@ macro_rules! expand_combined_late_lint_pass_methods { ) } -/// Declare the combined struct (one [`Gated`] field per pass) plus its +/// Declare the combined struct (one optional field per pass) plus its /// `LintPass`/`LateLintPass` impls. The method list comes from /// `rustc_lint::late_lint_methods!` so it can't drift from rustc's. /// @@ -75,13 +60,13 @@ macro_rules! combined_late_lint_pass { ) => { #[allow(non_snake_case)] pub struct $name<'tcx> { - $($field: $crate::combined_late_pass::Gated<$fty>,)* + $($field: Option<$fty>,)* } impl<'tcx> $name<'tcx> { pub fn new bool>($($pname: $pty,)* is_active: &F) -> Self { Self { - $($field: $crate::combined_late_pass::Gated::new(is_active, $ctor),)* + $($field: is_active(&<$fty>::lint_vec()).then(|| $ctor),)* } } } @@ -93,8 +78,8 @@ macro_rules! combined_late_lint_pass { } fn get_lints(&self) -> rustc_lint::LintVec { // Reserve at least one slot per pass up front to skip the early reallocations. - let mut lints = Vec::with_capacity([$(stringify!($field)),*].len()); - $(lints.extend(self.$field.pass.get_lints());)* + let mut lints = Vec::with_capacity(${count($field)}); + $(lints.extend(<$fty>::lint_vec());)* lints } } diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 681b36cfb3607..2258ae7659285 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -462,6 +462,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::methods::OPTION_AS_REF_DEREF_INFO, crate::methods::OPTION_FILTER_MAP_INFO, crate::methods::OPTION_MAP_OR_NONE_INFO, + crate::methods::OPTION_ZIP_NONE_INFO, crate::methods::OR_FUN_CALL_INFO, crate::methods::OR_THEN_UNWRAP_INFO, crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO, @@ -572,6 +573,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::needless_ifs::NEEDLESS_IFS_INFO, crate::needless_late_init::NEEDLESS_LATE_INIT_INFO, crate::needless_maybe_sized::NEEDLESS_MAYBE_SIZED_INFO, + crate::needless_nonzero_get::NEEDLESS_NONZERO_GET_INFO, crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO, crate::needless_pass_by_ref_mut::NEEDLESS_PASS_BY_REF_MUT_INFO, crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO, diff --git a/src/tools/clippy/clippy_lints/src/double_parens.rs b/src/tools/clippy/clippy_lints/src/double_parens.rs index 6e92707510aa1..8b49e88ff96bd 100644 --- a/src/tools/clippy/clippy_lints/src/double_parens.rs +++ b/src/tools/clippy/clippy_lints/src/double_parens.rs @@ -73,7 +73,7 @@ impl EarlyLintPass for DoubleParens { // ^^^^^^^^^ expr // ^^^ arg // ^ inner - ExprKind::Call(_, args) | ExprKind::MethodCall(box MethodCall { args, .. }) + ExprKind::Call(_, args) | ExprKind::MethodCall(MethodCall { args, .. }) if let [arg] = &**args && let ExprKind::Paren(inner) = &arg.kind && expr.span.eq_ctxt(arg.span) diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs index f5e721ad6b52a..f8e4a779da6f1 100644 --- a/src/tools/clippy/clippy_lints/src/format.rs +++ b/src/tools/clippy/clippy_lints/src/format.rs @@ -57,8 +57,11 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat { // HIR nodes inside `format!`'s own expansion (its outer block's tail, its nested // `format_args!`), which would otherwise also pass `first_node_in_macro` and cause the // lint to fire multiple times per call. - if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::format_macro) - && first_node_in_macro(cx, expr).is_some_and(|p_expn| p_expn != macro_call.expn) + // + // `first_node_in_macro` is checked first because it is cheaper. + if let Some(p_expn) = first_node_in_macro(cx, expr) + && let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::format_macro) + && p_expn != macro_call.expn && let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn) { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 1b7db66366b87..95eb581bcacb3 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -139,7 +139,7 @@ fn check_needless_must_use( attrs: &[Attribute], sig: &FnSig<'_>, ) { - if item_span.in_external_macro(cx.sess().source_map()) { + if item_span.in_external_macro(cx.sess().source_map()) || attr_span.from_expansion() { return; } if returns_unit(decl) { diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 8b0765fb6c012..2cf394fbb63bb 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -1,10 +1,12 @@ #![feature(box_patterns)] #![feature(control_flow_into_value)] +#![feature(deref_patterns)] #![feature(exact_div)] #![feature(f128)] #![feature(f16)] #![feature(iter_intersperse)] #![feature(iter_partition_in_place)] +#![feature(macro_metavar_expr)] #![feature(macro_metavar_expr_concat)] #![feature(never_type)] #![feature(rustc_private)] @@ -263,6 +265,7 @@ mod needless_for_each; mod needless_ifs; mod needless_late_init; mod needless_maybe_sized; +mod needless_nonzero_get; mod needless_parens_on_range_literals; mod needless_pass_by_ref_mut; mod needless_pass_by_value; @@ -867,6 +870,7 @@ rustc_lint::late_lint_methods!( RestWhenDestructuringStruct: rest_when_destructuring_struct::RestWhenDestructuringStruct = rest_when_destructuring_struct::RestWhenDestructuringStruct, BlockScrutinee: block_scrutinee::BlockScrutinee = block_scrutinee::BlockScrutinee, NonnullUncheckedOnBoxPtr: nonnull_unchecked_on_box_ptr::NonnullUncheckedOnBoxPtr = nonnull_unchecked_on_box_ptr::NonnullUncheckedOnBoxPtr::new(conf), + NeedlessNonzeroGet: needless_nonzero_get::NeedlessNonzeroGet = needless_nonzero_get::NeedlessNonzeroGet::new(conf), // add late passes here, used by `cargo dev new_lint` ]] ); diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 0ded5b69f56f8..d5ada16a5c9a6 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -1,9 +1,12 @@ +use std::hash::{Hash, Hasher}; +use std::{iter, mem}; + use super::NEEDLESS_RANGE_LOOP; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use clippy_utils::ty::has_iter_method; use clippy_utils::visitors::is_local_used; -use clippy_utils::{SpanlessEq, contains_name, higher, is_integer_literal, peel_hir_expr_while, sugg}; +use clippy_utils::{SpanlessEq, SpanlessHash, contains_name, higher, is_integer_literal, peel_hir_expr_while, sugg}; use rustc_ast::ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::Applicability; @@ -14,7 +17,7 @@ use rustc_lint::LateContext; use rustc_middle::middle::region; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::{Symbol, sym}; -use std::{iter, mem}; +use rustc_span::{Span, SyntaxContext}; /// Checks for looping over a range and then indexing a sequence with it. /// The iteratee must be a range literal. @@ -53,14 +56,10 @@ pub(super) fn check<'tcx>( if visitor.indexed_indirectly.is_empty() && !visitor.unnamed_indexed_indirectly && !visitor.unnamed_indexed_directly - && visitor.indexed_directly.len() == 1 + && let mut indexed_directly_iter = visitor.indexed_directly.into_iter() + && let Some(((indexed, indexed_extended), (indexed_extent, indexed_span))) = indexed_directly_iter.next() + && indexed_directly_iter.next().is_none() { - let (indexed, (indexed_extent, indexed_ty)) = visitor - .indexed_directly - .into_iter() - .next() - .expect("already checked that we have exactly 1 element"); - // ensure that the indexed variable was declared before the loop, see #601 if let Some(indexed_extent) = indexed_extent { let parent_def_id = cx.tcx.hir_get_parent_item(expr.hir_id); @@ -72,6 +71,7 @@ pub(super) fn check<'tcx>( } // don't lint if the container that is indexed does not have .iter() method + let indexed_ty = cx.typeck_results().expr_ty(indexed_extended.expr); let has_iter = has_iter_method(cx, indexed_ty); if has_iter.is_none() { return; @@ -147,44 +147,50 @@ pub(super) fn check<'tcx>( mem::swap(&mut method_1, &mut method_2); } - if visitor.nonindex { - span_lint_and_then( - cx, - NEEDLESS_RANGE_LOOP, - span, - format!("the loop variable `{}` is used to index `{indexed}`", ident.name), - |diag| { + let indexed_extended_snippet = snippet(cx, indexed_extended.expr.span, ".."); + span_lint_and_then( + cx, + NEEDLESS_RANGE_LOOP, + span, + if visitor.nonindex { + format!( + "the loop variable `{}` is used to index `{indexed_extended_snippet}`", + ident.name + ) + } else { + format!( + "the loop variable `{}` is only used to index `{indexed_extended_snippet}`", + ident.name + ) + }, + |diag| { + diag.span_note(indexed_span, "for this index operation"); + if visitor.nonindex { diag.multipart_suggestion( - "consider using an iterator and enumerate()", + "consider using an iterator and `.enumerate()`", vec![ (pat.span, format!("({}, )", ident.name)), - (span, format!("{indexed}.{method}().enumerate(){method_1}{method_2}")), + ( + span, + format!("{indexed_extended_snippet}.{method}().enumerate(){method_1}{method_2}"), + ), ], Applicability::HasPlaceholders, ); - }, - ); - } else { - let repl = if starts_at_zero && take_is_empty { - format!("&{ref_mut}{indexed}") - } else { - format!("{indexed}.{method}(){method_1}{method_2}") - }; - - span_lint_and_then( - cx, - NEEDLESS_RANGE_LOOP, - span, - format!("the loop variable `{}` is only used to index `{indexed}`", ident.name), - |diag| { + } else { + let repl = if starts_at_zero && take_is_empty { + format!("&{ref_mut}{indexed_extended_snippet}") + } else { + format!("{indexed_extended_snippet}.{method}(){method_1}{method_2}") + }; diag.multipart_suggestion( "consider using an iterator", vec![(pat.span, "".to_string()), (span, repl)], Applicability::HasPlaceholders, ); - }, - ); - } + } + }, + ); } } } @@ -236,7 +242,7 @@ struct VarVisitor<'a, 'tcx> { unnamed_indexed_indirectly: bool, /// subset of `indexed` of vars that are indexed directly: `v[i]` /// this will not contain cases like `v[calc_index(i)]` or `v[(i + 4) % N]` - indexed_directly: FxIndexMap, Ty<'tcx>)>, + indexed_directly: FxIndexMap<(Symbol, SpanlessExpr<'a, 'tcx>), (Option, Span)>, /// directly indexed literals, like `[1, 2, 3][i]` unnamed_indexed_directly: bool, /// Any names that are used outside an index operation. @@ -262,13 +268,24 @@ impl<'tcx> VarVisitor<'_, 'tcx> { index_used_directly &= matches!(idx.kind, ExprKind::Path(_)); } // Handle nested indices - let seqexpr = peel_hir_expr_while(seqexpr, |e| { - if let ExprKind::Index(e, idx, _) = e.kind { - if is_local_used(self.cx, idx, self.var) { - used_cnt += 1; - index_used_directly &= matches!(idx.kind, ExprKind::Path(_)); - } - Some(e) + // For example, in `a.b[0][i][i]`, we will have `nested_seqexpr` be `a.b[0]`, with the corresponding + // `nested_seqexpr_index_span` be the span of `a.b[0][i]`, and `seqexpr` be `a.b`. + let mut nested_seqexpr_index_span = expr.span; + let nested_seqexpr = peel_hir_expr_while(seqexpr, |e| { + if let ExprKind::Index(inner, idx, _) = e.kind + && is_local_used(self.cx, idx, self.var) + { + used_cnt += 1; + index_used_directly &= matches!(idx.kind, ExprKind::Path(_)); + nested_seqexpr_index_span = e.span; + Some(inner) + } else { + None + } + }); + let seqexpr = peel_hir_expr_while(nested_seqexpr, |e| { + if let ExprKind::Index(inner, _, _) | ExprKind::Field(inner, _) = e.kind { + Some(inner) } else { None } @@ -300,8 +317,15 @@ impl<'tcx> VarVisitor<'_, 'tcx> { .unwrap(); if index_used_directly { self.indexed_directly.insert( - seqvar.segments[0].ident.name, - (Some(extent), self.cx.typeck_results().node_type(seqexpr.hir_id)), + ( + seqvar.segments[0].ident.name, + SpanlessExpr { + cx: self.cx, + expr: nested_seqexpr, + ctxt: seqexpr.span.ctxt(), + }, + ), + (Some(extent), nested_seqexpr_index_span), ); } else { self.indexed_indirectly @@ -312,8 +336,15 @@ impl<'tcx> VarVisitor<'_, 'tcx> { Res::Def(DefKind::Static { .. } | DefKind::Const { .. }, ..) => { if index_used_directly { self.indexed_directly.insert( - seqvar.segments[0].ident.name, - (None, self.cx.typeck_results().node_type(seqexpr.hir_id)), + ( + seqvar.segments[0].ident.name, + SpanlessExpr { + cx: self.cx, + expr: nested_seqexpr, + ctxt: seqexpr.span.ctxt(), + }, + ), + (None, nested_seqexpr_index_span), ); } else { self.indexed_indirectly.insert(seqvar.segments[0].ident.name, None); @@ -425,3 +456,26 @@ impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> { self.prefer_mutable = old; } } + +struct SpanlessExpr<'cx, 'tcx> { + cx: &'cx LateContext<'tcx>, + expr: &'cx Expr<'tcx>, + ctxt: SyntaxContext, +} + +impl PartialEq for SpanlessExpr<'_, '_> { + fn eq(&self, other: &Self) -> bool { + let mut eq = SpanlessEq::new(self.cx); + eq.eq_expr(self.ctxt, self.expr, other.expr) + } +} + +impl Eq for SpanlessExpr<'_, '_> {} + +impl Hash for SpanlessExpr<'_, '_> { + fn hash(&self, state: &mut H) { + let mut hash = SpanlessHash::new(self.cx); + hash.hash_expr(self.expr); + state.write_u64(hash.finish()); + } +} diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs index 7bccc30b9e95c..87523cd0e8c81 100644 --- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs @@ -122,11 +122,7 @@ fn is_arms_disjointed(cx: &LateContext<'_>, arm1: &Arm<'_>, arm2: &Arm<'_>) -> b return false; } - if !is_enum_variant(cx, arm1.pat) || !is_enum_variant(cx, arm2.pat) { - return false; - } - - true + is_enum_variant(cx, arm1.pat) && is_enum_variant(cx, arm2.pat) } /// Returns `true` if the given pattern is a variant of an enum. diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs index 7605c7dda8820..f1c50b55f9eec 100644 --- a/src/tools/clippy/clippy_lints/src/matches/mod.rs +++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs @@ -1209,15 +1209,18 @@ impl<'tcx> LateLintPass<'tcx> for Matches { ); needless_match::check_if_let(cx, expr, &if_let); } - } else { - if expr.span.in_external_macro(cx.tcx.sess.source_map()) { - return; - } - if let Some(while_let) = higher::WhileLet::hir(expr) { - significant_drop_in_scrutinee::check_while_let(cx, expr, while_let.let_expr, while_let.if_then); - } + } else if let Some(while_let) = higher::WhileLet::hir(expr) + && !expr.span.in_external_macro(cx.tcx.sess.source_map()) + { + significant_drop_in_scrutinee::check_while_let(cx, expr, while_let.let_expr, while_let.if_then); if !from_expansion { - redundant_pattern_match::check(cx, expr); + redundant_pattern_match::check_while_let( + cx, + expr, + while_let.let_pat, + while_let.let_expr, + while_let.let_span, + ); } } } diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 037276f868e2b..787e6147d8526 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -4,7 +4,7 @@ use clippy_utils::res::{MaybeDef as _, MaybeTypeckRes as _}; use clippy_utils::sugg::{Sugg, make_unop}; use clippy_utils::ty::needs_ordered_drop; use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures}; -use clippy_utils::{get_parent_expr, higher, is_expn_of, sym}; +use clippy_utils::{get_parent_expr, is_expn_of, sym}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::attrs::lang_items::LangItem::{ @@ -18,17 +18,15 @@ use rustc_span::{Span, Symbol, kw}; use std::fmt::Write as _; use std::ops::ControlFlow; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let Some(higher::WhileLet { - let_pat, - let_expr, - let_span, - .. - }) = higher::WhileLet::hir(expr) - { - find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, kw::While, false, let_span); - find_if_let_true(cx, let_pat, let_expr, let_span); - } +pub(super) fn check_while_let<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + pat: &'tcx Pat<'_>, + scrutinee: &'tcx Expr<'_>, + let_span: Span, +) { + find_method_sugg_for_if_let(cx, expr, pat, scrutinee, kw::While, false, let_span); + find_if_let_true(cx, pat, scrutinee, let_span); } pub(super) fn check_if_let<'tcx>( diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs b/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs index f1d399e1bbd2f..58453a3c08774 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_contains.rs @@ -3,6 +3,7 @@ use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::peel_hir_pat_refs; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; +use clippy_utils::usage::local_used_in; use rustc_ast::UnOp; use rustc_errors::Applicability; use rustc_hir::def::Res; @@ -80,7 +81,7 @@ fn try_get_eligible_arg<'tcx>( } }, _ => { - if switch_to_eager_eval(cx, expr) { + if switch_to_eager_eval(cx, expr) && !local_used_in(cx, closure_arg_id, expr) { Some((get_snippet(expr, true), expr)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 6c7a8d8e143be..289e4f2e1fa06 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -94,6 +94,7 @@ mod open_options; mod option_as_ref_cloned; mod option_as_ref_deref; mod option_map_or_none; +mod option_zip_none; mod or_fun_call; mod or_then_unwrap; mod path_buf_push_overwrite; @@ -384,7 +385,7 @@ declare_clippy_lint! { /// let (chunks, remainder) = slice.as_chunks::<2>(); /// for chunk in chunks {} /// ``` - #[clippy::version = "1.93.0"] + #[clippy::version = "1.98.0"] pub CHUNKS_EXACT_TO_AS_CHUNKS, style, "using `chunks_exact` with constant when `as_chunks` is more ergonomic" @@ -2978,6 +2979,28 @@ declare_clippy_lint! { "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for calls of the form `Option::zip(_, None)` or `Option::zip(None, _)`. + /// + /// ### Why is this bad? + /// `Option::zip` with `None` always returns `None`. + /// + /// ### Example + /// ```ignore + /// let foo = Some(5); + /// foo.zip(None); + /// ``` + /// Use instead: + /// ```ignore + /// None + /// ``` + #[clippy::version = "1.99.0"] + pub OPTION_ZIP_NONE, + suspicious, + "calling `.zip(None)` on an `Option` always returns `None`" +} + declare_clippy_lint! { /// ### What it does /// Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`, @@ -4429,37 +4452,41 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Converts some constructs mapping an Enum value for equality comparison. + /// Converts some constructs mapping an enum value for equality or variant checks. /// /// ### Why is this bad? /// Calls such as `opt.map_or(false, |val| val == 5)` are needlessly long and cumbersome, /// and can be reduced to, for example, `opt == Some(5)` assuming `opt` implements `PartialEq`. /// Also, calls such as `opt.map_or(true, |val| val == 5)` can be reduced to /// `opt.is_none_or(|val| val == 5)`. + /// Calls that map the two variants of a `Result` to opposite boolean constants can be + /// reduced to `is_ok()` or `is_err()`. /// This lint offers readability and conciseness improvements. /// /// ### Example /// ```no_run - /// pub fn a(x: Option) -> (bool, bool) { + /// pub fn a(x: Option, result: Result) -> (bool, bool, bool) { /// ( /// x.map_or(false, |n| n == 5), /// x.map_or(true, |n| n > 5), + /// result.map_or_else(|_| false, |_| true), /// ) /// } /// ``` /// Use instead: /// ```no_run - /// pub fn a(x: Option) -> (bool, bool) { + /// pub fn a(x: Option, result: Result) -> (bool, bool, bool) { /// ( /// x == Some(5), /// x.is_none_or(|n| n > 5), + /// result.is_ok(), /// ) /// } /// ``` #[clippy::version = "1.84.0"] pub UNNECESSARY_MAP_OR, style, - "reduce unnecessary calls to `.map_or(bool, …)`" + "reduce unnecessary calls to `.map_or(bool, …)` and `.map_or_else(…, …)`" } declare_clippy_lint! { @@ -5018,6 +5045,7 @@ impl_lint_pass!(Methods => [ OPTION_AS_REF_DEREF, OPTION_FILTER_MAP, OPTION_MAP_OR_NONE, + OPTION_ZIP_NONE, OR_FUN_CALL, OR_THEN_UNWRAP, PATH_BUF_PUSH_OVERWRITE, @@ -5172,6 +5200,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { &self.unwrap_allowed_ids, &self.unwrap_allowed_aliases, ); + option_zip_none::check_call(cx, expr, func, args); }, ExprKind::MethodCall(..) => { self.check_methods(cx, expr); @@ -5638,6 +5667,7 @@ impl Methods { (sym::map_or_else, [def, map]) => { result_map_or_else_none::check(cx, expr, recv, def, map); unnecessary_map_or_else::check(cx, expr, recv, def, map, call_span); + unnecessary_map_or::check_map_or_else(cx, expr, recv, def, map); }, (sym::next, []) => { if let Some((name2, recv2, args2, _, _)) = method_call(recv) { @@ -5995,6 +6025,9 @@ impl Methods { unwrap_expect_used::Variant::Unwrap, ); }, + (sym::zip, [arg]) => { + option_zip_none::check_method(cx, expr, recv, arg); + }, _ => {}, } } diff --git a/src/tools/clippy/clippy_lints/src/methods/option_zip_none.rs b/src/tools/clippy/clippy_lints/src/methods/option_zip_none.rs new file mode 100644 index 0000000000000..784cac392d360 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/methods/option_zip_none.rs @@ -0,0 +1,87 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::res::{MaybeDef as _, MaybeTypeckRes as _}; +use clippy_utils::source::snippet_with_context; +use clippy_utils::{is_none_expr, sym}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; + +use super::OPTION_ZIP_NONE; + +fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) { + let recv_is_none = is_none_expr(cx, recv); + let arg_is_none = is_none_expr(cx, arg); + + if !recv_is_none && !arg_is_none { + return; + } + + span_lint_and_then( + cx, + OPTION_ZIP_NONE, + expr.span, + "calling `.zip()` on an `Option` where one side is `None` always returns `None`", + |diag| { + let mut app = Applicability::MaybeIncorrect; + let ctxt = expr.span.ctxt(); + let none_snippet = if recv_is_none { + snippet_with_context(cx, recv.span, ctxt, "_", &mut app).0 + } else { + snippet_with_context(cx, arg.span, ctxt, "_", &mut app).0 + }; + + if let ExprKind::MethodCall(_, _, _, call_span) = expr.kind { + if recv_is_none && !arg_is_none { + let arg_snip = snippet_with_context(cx, arg.span, ctxt, "_", &mut app).0; + diag.span_suggestion( + expr.span, + "if you meant to zip the contents of the `Option` with `None`, use `Option::map`", + format!("{arg_snip}.map(|n| ({none_snippet}, n))"), + app, + ); + } else if !recv_is_none && arg_is_none { + diag.span_suggestion( + call_span, + "if you meant to zip the contents of the `Option` with `None`, use `Option::map`", + format!("map(|n| (n, {none_snippet}))"), + app, + ); + } + } + }, + ); +} + +pub(super) fn check_call(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>]) { + if let [left, right] = args + && let ExprKind::Path(ref qpath) = func.kind + && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() + && cx.tcx.item_name(def_id) == sym::zip + && def_id.opt_parent(cx).opt_impl_ty(cx).is_some_and(|impl_ty| { + impl_ty + .instantiate_identity() + .skip_norm_wip() + .ty_adt_def() + .is_some_and(|adt| cx.tcx.is_diagnostic_item(sym::Option, adt.did())) + }) + { + emit_lint(cx, expr, left, right); + } +} + +pub(super) fn check_method(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) { + if cx + .ty_based_def(expr) + .opt_parent(cx) + .opt_impl_ty(cx) + .is_some_and(|impl_ty| { + impl_ty + .instantiate_identity() + .skip_norm_wip() + .ty_adt_def() + .is_some_and(|adt| cx.tcx.is_diagnostic_item(sym::Option, adt.did())) + }) + { + emit_lint(cx, expr, recv, arg); + } +} diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs index f8906bb23282d..dff23e1cce061 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs @@ -1,12 +1,13 @@ use std::borrow::Cow; +use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::{MaybeDef as _, MaybeResPath as _}; use clippy_utils::sugg::{Sugg, make_binop}; -use clippy_utils::ty::{implements_trait, is_copy}; -use clippy_utils::visitors::is_local_used; +use clippy_utils::ty::{implements_trait, is_copy, needs_ordered_drop}; +use clippy_utils::visitors::{any_temporaries_need_ordered_drop, is_local_used}; use clippy_utils::{get_parent_expr, is_from_proc_macro}; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -36,15 +37,103 @@ impl Variant { } } -pub(super) fn check<'a>( - cx: &LateContext<'a>, - expr: &Expr<'a>, - recv: &Expr<'_>, - def: &Expr<'_>, - map: &Expr<'_>, +/// Evaluates `expr` and returns its value if it is a constant boolean. +fn bool_constant(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { + let Some(Constant::Bool(value)) = ConstEvalCtxt::new(cx).eval(expr) else { + return None; + }; + Some(value) +} + +/// Returns the constant boolean produced by a one-parameter closure. +fn closure_bool_constant(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { + let ExprKind::Closure(closure) = expr.kind else { + return None; + }; + let body = cx.tcx.hir_body(closure.body); + let [_] = body.params else { + return None; + }; + bool_constant(cx, body.value) +} + +/// Checks whether a `Result::{map_or, map_or_else}` call is a variant query. +/// +/// `expr` is the complete method call, `recv` is its `Result` receiver, `def` is the default +/// argument, and `map` is the mapping closure. `check_if_bool` accounts for the eager default in +/// `map_or` and the closure default in `map_or_else`. +fn check_result_variant_query<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + def: &'tcx Expr<'tcx>, + map: &'tcx Expr<'tcx>, + check_if_bool: impl FnOnce(&LateContext<'tcx>, &'tcx Expr<'tcx>) -> Option, +) -> bool { + let ExprKind::MethodCall(path, _, _, call_span) = expr.kind else { + return false; + }; + let recv_ty = cx.typeck_results().expr_ty_adjusted(recv); + if recv_ty.opt_diag_name(cx) != Some(sym::Result) { + return false; + } + + let def_bool = check_if_bool(cx, def); + let Some((def_bool, map_bool)) = def_bool.zip(closure_bool_constant(cx, map)) else { + return false; + }; + if def_bool == map_bool || is_from_proc_macro(cx, expr) { + return false; + } + + let suggested_name = if map_bool { "is_ok" } else { "is_err" }; + let changes_drop_order = needs_ordered_drop(cx, recv_ty) || any_temporaries_need_ordered_drop(cx, recv); + let applicability = if changes_drop_order { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }; + + span_lint_and_then( + cx, + UNNECESSARY_MAP_OR, + path.ident.span, + format!("this `{}` can be simplified", path.ident.name), + |diag| { + diag.span_suggestion( + call_span, + format!("use `{suggested_name}` instead"), + format!("{suggested_name}()"), + applicability, + ); + if changes_drop_order { + diag.note("this will change drop order of the result, as well as all temporaries"); + diag.note("add `#[allow(clippy::unnecessary_map_or)]` if this is important"); + } + }, + ); + true +} + +/// Checks a `map_or` call for both `Result` variant queries and the existing `Option`/`Result` +/// simplifications. +/// +/// `expr` is the complete method call, `recv` is its receiver, `def` is the eager default, and +/// `map` is the mapping closure. `method_span` identifies `map_or` in diagnostics, while `msrv` +/// controls which replacement methods can be suggested. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + def: &'tcx Expr<'tcx>, + map: &'tcx Expr<'tcx>, method_span: Span, msrv: Msrv, ) { + if check_result_variant_query(cx, expr, recv, def, map, bool_constant) { + return; + } + let ExprKind::Lit(def_kind) = def.kind else { return; }; @@ -158,3 +247,17 @@ pub(super) fn check<'a>( }, ); } + +/// Checks a `map_or_else` call for a `Result` variant query. +/// +/// `expr` is the complete method call, `recv` is its `Result` receiver, `def` is the lazy default +/// closure, and `map` is the mapping closure. +pub(super) fn check_map_or_else<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + def: &'tcx Expr<'tcx>, + map: &'tcx Expr<'tcx>, +) { + check_result_variant_query(cx, expr, recv, def, map, closure_bool_constant); +} diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index 3c6b60355a823..ddc61b2449824 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -1,10 +1,13 @@ use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::sugg::Sugg; -use clippy_utils::{SpanlessEq, fulfill_or_allowed, get_parent_expr, in_automatically_derived, last_path_segment}; +use clippy_utils::{fulfill_or_allowed, in_automatically_derived}; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, Stmt, StmtKind}; -use rustc_lint::{LateContext, LateLintPass, LintContext as _, declare_lint_pass}; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::{BinOpKind, Expr, ExprKind, HirId, Node, QPath, Stmt, StmtKind}; +use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; +use rustc_middle::ty; +use rustc_span::{Span, Symbol}; declare_clippy_lint! { /// ### What it does @@ -124,122 +127,137 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if expr.span.in_external_macro(cx.sess().source_map()) - || expr.span.desugaring_kind().is_some() - || in_automatically_derived(cx.tcx, expr.hir_id) - { - return; - } - - used_underscore_binding(cx, expr); - used_underscore_items(cx, expr); + check_used_underscore(cx, expr); } } -fn used_underscore_items<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - let (def_id, ident) = match expr.kind { - ExprKind::Call(func, ..) => { - if let ExprKind::Path(QPath::Resolved(.., path)) = func.kind - && let Some(last_segment) = path.segments.last() - && let Res::Def(_, def_id) = last_segment.res - { - (def_id, last_segment.ident) - } else { - return; - } - }, - ExprKind::MethodCall(path, ..) => { - if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { - (def_id, path.ident) - } else { - return; - } - }, - ExprKind::Struct(QPath::Resolved(_, path), ..) => { - if let Some(last_segment) = path.segments.last() - && let Res::Def(_, def_id) = last_segment.res - { - (def_id, last_segment.ident) - } else { - return; - } - }, - _ => return, - }; +#[derive(Clone, Copy)] +enum Id<'tcx> { + /// A local binding. + Binding(HirId), + /// A resolved local definition. + LocalDef(LocalDefId), + /// An unresolved type-relative definition. + TyRel, + /// A field of an unresolved type. + FieldOf(&'tcx Expr<'tcx>), +} +impl Id<'_> { + fn from_res(res: Res) -> Option { + match res { + Res::Local(id) => Some(Self::Binding(id)), + Res::Def(_, id) => id.as_local().map(Self::LocalDef), + _ => None, + } + } - let name = ident.name.as_str(); - let definition_span = cx.tcx.def_span(def_id); - if name.starts_with('_') - && !name.starts_with("__") - && !definition_span.from_expansion() - && def_id.is_local() - && !cx.tcx.is_foreign_item(def_id) - { - span_lint_and_then( - cx, - USED_UNDERSCORE_ITEMS, - expr.span, - "used underscore-prefixed item".to_string(), - |diag| { - diag.span_note(definition_span, "item is defined here".to_string()); + fn get_local_def(self, cx: &LateContext<'_>, e: &Expr<'_>, name: Symbol) -> Option<(HirId, Span)> { + let id = match self { + Self::Binding(id) if let Node::Pat(p) = cx.tcx.hir_node(id) => return Some((id, p.span)), + Self::LocalDef(id) => id, + Self::TyRel => cx.typeck_results().type_dependent_def_id(e.hir_id)?.as_local()?, + Self::FieldOf(e) + if let ty::Adt(adt, _) = *cx.typeck_results().expr_ty_adjusted(e).kind() + && adt.did().is_local() + && let [variant] = &adt.variants().raw + && let Some(f) = variant.fields.iter().find(|&f| f.name == name) + && match *cx.tcx.type_of(f.did).instantiate_identity().skip_normalization().kind() { + ty::Adt(adt, _) => !adt.is_phantom_data(), + _ => true, + } + && let Some(id) = f.did.as_local() => + { + id }, - ); + Self::FieldOf(_) | Self::Binding(_) => return None, + }; + if cx.tcx.is_foreign_item(id) { + None + } else { + Some((cx.tcx.local_def_id_to_hir_id(id), cx.tcx.def_span(id))) + } } } -fn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - let (definition_hir_id, ident) = match expr.kind { - ExprKind::Path(ref qpath) => { - if let QPath::Resolved(None, path) = qpath - && let Res::Local(id) = path.res - && is_used(cx, expr) +fn check_used_underscore<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { + let (ident, id) = match e.kind { + ExprKind::Path(path) => match path { + QPath::Resolved(_, path) + if let Some(id) = Id::from_res(path.res) + && let [.., seg] = path.segments => { - (id, last_path_segment(qpath).ident) - } else { - return; - } + (seg.ident, id) + }, + QPath::Resolved(..) => return, + QPath::TypeRelative(_, seg) => (seg.ident, Id::TyRel), }, - ExprKind::Field(recv, ident) => { - if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def() - && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name) - && let Some(local_did) = field.did.as_local() - && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data() + ExprKind::MethodCall(path, ..) => (path.ident, Id::TyRel), + ExprKind::Struct(path, ..) => match path { + QPath::Resolved(_, path) + if let Some(id) = Id::from_res(path.res) + && let [.., seg] = path.segments => { - (cx.tcx.local_def_id_to_hir_id(local_did), ident) - } else { - return; - } + (seg.ident, id) + }, + QPath::Resolved(..) => return, + QPath::TypeRelative(_, seg) => (seg.ident, Id::TyRel), }, + ExprKind::Field(base, ident) => (ident, Id::FieldOf(base)), _ => return, }; - let name = ident.name.as_str(); - if name.starts_with('_') - && !name.starts_with("__") - && let definition_span = cx.tcx.hir_span(definition_hir_id) - && !definition_span.from_expansion() - && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id]) + if !e.span.from_expansion() + && !ident.span.from_expansion() + && ident + .name + .as_str() + .strip_prefix('_') + .is_some_and(|x| !x.starts_with('_')) + && let Some((def_hir_id, def_sp)) = id.get_local_def(cx, e, ident.name) + && !def_sp.from_expansion() + // Only lint when rustc's `unused_variables` would trigger + && (!matches!(id, Id::Binding(_)) || is_used(cx, e)) + && !in_automatically_derived(cx.tcx, e.hir_id) + && let (lint, msg, help_msg) = match id { + Id::Binding(_) | Id::FieldOf(_) => ( + USED_UNDERSCORE_BINDING, + "used underscore-prefixed binding", + "binding is defined here", + ), + Id::TyRel | Id::LocalDef(_) => ( + USED_UNDERSCORE_ITEMS, + "used underscore-prefixed item", + "item is defined here", + ), + } + && !fulfill_or_allowed(cx, lint, [def_hir_id]) { - span_lint_and_then( - cx, - USED_UNDERSCORE_BINDING, - expr.span, - "used underscore-prefixed binding".to_string(), - |diag| { - diag.span_note(definition_span, "binding is defined here".to_string()); - }, - ); + span_lint_and_then(cx, lint, e.span, msg, |diag| { + diag.span_note(def_sp, help_msg); + }); } } -/// Heuristic to see if an expression is used. Should be compatible with -/// `unused_variables`'s idea -/// of what it means for an expression to be "used". fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - get_parent_expr(cx, expr).is_none_or(|parent| match parent.kind { - ExprKind::Assign(_, rhs, _) | ExprKind::AssignOp(_, _, rhs) => { - SpanlessEq::new(cx).eq_expr(parent.span.ctxt(), rhs, expr) - }, - _ => is_used(cx, parent), - }) + let mut child = expr.hir_id; + let typeck = cx.typeck_results(); + for (id, node) in cx.tcx.hir_parent_iter(child) { + match node { + Node::Expr(e) => match e.kind { + ExprKind::Field(base, ..) if typeck.expr_adjustments(base).is_empty() => child = id, + ExprKind::Assign(lhs, ..) if child == lhs.hir_id => return false, + // Only primitive types are considered unused for compound assignment. + // Everything else uses takes a mutable borrow of the lhs. + ExprKind::AssignOp(_, lhs, _) + if child == lhs.hir_id + && let ty::Int(_) | ty::Uint(_) | ty::Float(_) = *typeck.node_type(child).kind() => + { + return false; + }, + _ => return true, + }, + _ => return true, + } + } + true } diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs index 2d836c862dde1..81a48f9a92a1a 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs @@ -59,10 +59,11 @@ fn is_thread_local_initializer( fn_kind: intravisit::FnKind<'_>, span: rustc_span::Span, ) -> Option { - let macro_def_id = span.source_callee()?.macro_def_id?; Some( - cx.tcx.is_diagnostic_item(sym::thread_local_macro, macro_def_id) - && matches!(fn_kind, intravisit::FnKind::ItemFn(..)), + matches!(fn_kind, intravisit::FnKind::ItemFn(..)) + && cx + .tcx + .is_diagnostic_item(sym::thread_local_macro, span.source_callee()?.macro_def_id?), ) } diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index e7a5dcaf2581f..6b3f38565bed3 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -42,7 +42,7 @@ declare_clippy_lint! { /// order of sub-expressions. /// /// ### Why restrict this? - /// While [the evaluation order of sub-expressions] is fully specified in Rust, + /// While [the evaluation order of sub-expressions][order] is fully specified in Rust, /// it still may be confusing to read an expression where the evaluation order /// affects its behavior. /// @@ -71,7 +71,7 @@ declare_clippy_lint! { /// let a = tmp + x; /// ``` /// - /// [order]: (https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands) + /// [order]: https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands #[clippy::version = "pre 1.29.0"] pub MIXED_READ_WRITE_IN_EXPRESSION, restriction, diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs index 7ca34f4f5c08b..30bb72b4a4aa1 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs @@ -7,7 +7,9 @@ use clippy_utils::{ }; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; +use rustc_hir::{Block, Expr, ExprKind, StmtKind}; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_span::SyntaxContext; @@ -16,6 +18,9 @@ declare_clippy_lint! { /// Checks for expressions of the form `if c { true } else { /// false }` (or vice versa) and suggests using the condition directly. /// + /// This also covers the early-return guard form, where a condition returns a + /// tuple-like based on it. + /// /// ### Why is this bad? /// Redundant code. /// @@ -42,6 +47,23 @@ declare_clippy_lint! { /// !x /// # ; /// ``` + /// + /// Or, for the early-return guard form: + /// ``` + /// # fn f(c: bool) -> Result { + /// if c { + /// return Ok(true); + /// } + /// Ok(false) + /// # } + /// ``` + /// + /// Use instead: + /// ``` + /// # fn f(c: bool) -> Result { + /// Ok(c) + /// # } + /// ``` #[clippy::version = "pre 1.29.0"] pub NEEDLESS_BOOL, complexity, @@ -197,6 +219,117 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { } } } + + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { + // Detect the early-return form: + // if c { + // return Ok(true); + // } + // Ok(false) + // and reduce it to `Ok(c)`. The optional `Ok(..)` wrapper can be any tuple-like + // constructor (or absent), as long as the guard and the trailing expression use the + // same one. Constructors are pure, so folding the condition in keeps the behavior. + if let Some(tail) = block.expr + && !tail.span.from_expansion() + && let [.., last_stmt] = block.stmts + && let StmtKind::Semi(if_expr) | StmtKind::Expr(if_expr) = last_stmt.kind + && !if_expr.span.from_expansion() + && let Some(higher::If { + cond, + then, + r#else: None, + }) = higher::If::hir(if_expr) + && let ExprKind::Ret(Some(ret)) = peel_blocks_with_stmt(then).kind + && let Some((then_func, then_val)) = fetch_bool_and_wrapper(ret) + && let Some((tail_func, tail_val)) = fetch_bool_and_wrapper(tail) + // `if c { return Ok(true) } Ok(true)` is always the same value; the condition might + // have side effects, so don't touch it. Comparing the values here is cheap, so do it + // before the constructor resolution in `wrapper_ctors_match`, which needs `qpath_res`. + && then_val != tail_val + && wrapper_ctors_match(cx, then_func, tail_func) + { + // If there is another `if _ { return ..; }` before the `if_expr`, don't lint. Replacing the last + // `if` won't decrease complexity, without refactoring the entire block. + if block.stmts.len() >= 2 + && let StmtKind::Semi(prev_if_expr) | StmtKind::Expr(prev_if_expr) = + block.stmts[block.stmts.len() - 2].kind + && let Some(higher::If { + cond: _, + then: prev_then, + r#else: None, + }) = higher::If::hir(prev_if_expr) + && let ExprKind::Ret(Some(_)) = peel_blocks_with_stmt(prev_then).kind + { + return; + } + + let span = if_expr.span.to(tail.span); + if span_contains_comment(cx, span) { + return; + } + + let mut applicability = Applicability::MachineApplicable; + let mut snip = Sugg::hir_with_context(cx, cond, span.ctxt(), "..", &mut applicability); + // `then_val` is the value returned when the condition holds, so a `false` there means + // the result is the negation of the condition. + if !then_val { + snip = !snip; + } + let sugg = match tail_func { + Some(func) => { + let func_snip = snippet_with_context(cx, func.span, span.ctxt(), "..", &mut applicability).0; + format!("{func_snip}({snip})") + }, + None => snip.to_string(), + }; + + span_lint_and_sugg( + cx, + NEEDLESS_BOOL, + span, + "this `if` guard returns a bool literal and is followed by another", + "you can reduce it to", + sugg, + applicability, + ); + } + } +} + +/// Returns the optional constructor call wrapping a bool literal (e.g. the `Ok` in `Ok(true)`) +/// along with the bool value. The constructor is returned as the unresolved callee expression; +/// resolving it to a `DefId` (via [`wrapper_ctors_match`]) needs `qpath_res`, which is +/// comparatively expensive, so callers should only do that once the cheap bool-value comparison +/// has passed. A bare bool literal yields `None`. +fn fetch_bool_and_wrapper<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(Option<&'tcx Expr<'tcx>>, bool)> { + let expr = peel_blocks(expr); + if let Some(value) = fetch_bool_expr(expr) { + return Some((None, value)); + } + if let ExprKind::Call(func, [arg]) = expr.kind + && let Some(value) = fetch_bool_expr(arg) + { + return Some((Some(func), value)); + } + None +} + +/// Checks whether two optional wrapper-constructor call expressions (as returned by +/// [`fetch_bool_and_wrapper`]) are absent on both sides, or call the same tuple-like constructor. +fn wrapper_ctors_match(cx: &LateContext<'_>, a: Option<&Expr<'_>>, b: Option<&Expr<'_>>) -> bool { + fn resolve_ctor(cx: &LateContext<'_>, func: &Expr<'_>) -> Option { + if let ExprKind::Path(qpath) = &func.kind + && let Res::Def(DefKind::Ctor(..), did) = cx.qpath_res(qpath, func.hir_id) + { + return Some(did); + } + None + } + match (a, b) { + (None, None) => true, + (Some(a), Some(b)) => resolve_ctor(cx, a).is_some_and(|a| Some(a) == resolve_ctor(cx, b)), + _ => false, + } } enum Expression { diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 1aa07f76feadb..953c6d507bffb 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -370,7 +370,7 @@ fn referent_used_exactly_once<'tcx>( && let [location] = *local_assignments(mir, local).as_slice() && let block_data = &mir.basic_blocks[location.block] && let Some(statement) = block_data.statements.get(location.statement_index) - && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind + && let StatementKind::Assign((_, Rvalue::Ref(_, _, place))) = statement.kind && !place.is_indirect_first_projection() { let body_owner_local_def_id = cx.tcx.hir_enclosing_body_owner(reference.hir_id); diff --git a/src/tools/clippy/clippy_lints/src/needless_nonzero_get.rs b/src/tools/clippy/clippy_lints/src/needless_nonzero_get.rs new file mode 100644 index 0000000000000..ee55cbebd522b --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/needless_nonzero_get.rs @@ -0,0 +1,231 @@ +use clippy_config::Conf; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::Msrv; +use clippy_utils::ty::implements_trait; +use clippy_utils::{binop_traits, is_from_proc_macro, span_contains_comment, sym}; +use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; +use rustc_hir::{AssignOpKind, BinOpKind, Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; +use rustc_middle::ty::{self, Ty}; +use rustc_span::{Span, Symbol}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for `NonZero::get` calls that are immediately followed by a method or operator + /// which `NonZero` provides itself, with the same return type. + /// + /// ### Why is this bad? + /// The `get` call adds nothing but noise, as the method could be called on the + /// `NonZero` value directly. + /// + /// ### Example + /// ```no_run + /// # use std::num::NonZero; + /// # let nz = NonZero::new(1u32).unwrap(); + /// let _ = nz.get().leading_zeros(); + /// ``` + /// Use instead: + /// ```no_run + /// # use std::num::NonZero; + /// # let nz = NonZero::new(1u32).unwrap(); + /// let _ = nz.leading_zeros(); + /// ``` + /// + /// The lint also handles division and remainder operators: + /// ```no_run + /// # use std::num::NonZero; + /// # let nz = NonZero::new(2u32).unwrap(); + /// let _ = 4 / nz.get(); + /// ``` + /// Use instead: + /// ```no_run + /// # use std::num::NonZero; + /// # let nz = NonZero::new(2u32).unwrap(); + /// let _ = 4 / nz; + /// ``` + #[clippy::version = "1.99.0"] + pub NEEDLESS_NONZERO_GET, + complexity, + "unnecessary `NonZero::get` call" +} + +impl_lint_pass!(NeedlessNonzeroGet => [NEEDLESS_NONZERO_GET]); + +pub struct NeedlessNonzeroGet { + msrv: Msrv, +} + +impl NeedlessNonzeroGet { + pub fn new(conf: &'static Conf) -> Self { + Self { msrv: conf.msrv.into() } + } +} + +impl<'tcx> LateLintPass<'tcx> for NeedlessNonzeroGet { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + match expr.kind { + // `.get().()` + ExprKind::MethodCall(method, get_call, [], _) + if let Some((recv, nz_ty, nonzero_did, get_span)) = nonzero_get(cx, get_call) + // The outer call must resolve to an inherent method. A trait method of the same + // name could resolve differently once the receiver becomes a `NonZero`. + && let Some(method_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + && cx.tcx.trait_of_assoc(method_did).is_none() + // Dropping `get` must leave the expression's type unchanged. Methods whose + // `NonZero` version returns a `NonZero` deliberately do not match. + && let ret_ty = cx.typeck_results().expr_ty(expr) + && has_matching_method(cx, nonzero_did, nz_ty, method.ident.name, ret_ty, self.msrv) => + { + emit_unnecessary_get(cx, expr, get_call, recv, get_span, method.ident.name.as_str()); + }, + + // ` / .get()` and ` % .get()` + ExprKind::Binary(op, lhs, get_call) + if matches!(op.node, BinOpKind::Div | BinOpKind::Rem) + && let Some((recv, nz_ty, _, get_span)) = nonzero_get(cx, get_call) + && let Some((trait_lang_item, _)) = binop_traits(op.node) + && let Some(trait_id) = cx.tcx.lang_items().get(trait_lang_item) + && has_nonzero_operator(cx, lhs, recv, nz_ty, trait_id, self.msrv) => + { + emit_unnecessary_get(cx, expr, get_call, recv, get_span, op.node.as_str()); + }, + + // ` /= .get()` and ` %= .get()` + ExprKind::AssignOp(op, lhs, get_call) + if matches!(op.node, AssignOpKind::DivAssign | AssignOpKind::RemAssign) + && let Some((recv, nz_ty, _, get_span)) = nonzero_get(cx, get_call) + && let Some((_, trait_lang_item)) = binop_traits(op.node.into()) + && let Some(trait_id) = cx.tcx.lang_items().get(trait_lang_item) + && has_nonzero_operator(cx, lhs, recv, nz_ty, trait_id, self.msrv) => + { + emit_unnecessary_get(cx, expr, get_call, recv, get_span, op.node.as_str()); + }, + + _ => {}, + } + } +} + +/// Returns the receiver, its `NonZero` type and definition, and the `get` identifier span when +/// `expr` is an inherent `NonZero::get()` call. +fn nonzero_get<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, +) -> Option<(&'tcx Expr<'tcx>, Ty<'tcx>, DefId, Span)> { + let ExprKind::MethodCall(get, recv, [], get_span) = expr.kind else { + return None; + }; + if get.ident.name != sym::get { + return None; + } + let get_did = cx.typeck_results().type_dependent_def_id(expr.hir_id)?; + if cx.tcx.trait_of_assoc(get_did).is_some() { + return None; + } + let nz_ty = cx.typeck_results().expr_ty_adjusted(recv); + let ty::Adt(adt, _) = nz_ty.kind() else { + return None; + }; + if !cx.tcx.is_diagnostic_item(sym::NonZero, adt.did()) { + return None; + } + + Some((recv, nz_ty, adt.did(), get_span)) +} + +fn emit_unnecessary_get<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + get_call: &Expr<'tcx>, + recv: &Expr<'tcx>, + get_span: Span, + operation: &str, +) { + // Removing `.get()` means editing the span between the receiver and the surrounding + // expression, which is only meaningful when both are written out in the same context. + if expr.span.from_expansion() + || !recv.span.eq_ctxt(expr.span) + || !get_call.span.eq_ctxt(expr.span) + || is_from_proc_macro(cx, expr) + { + return; + } + + span_lint_and_then( + cx, + NEEDLESS_NONZERO_GET, + get_span, + format!("unnecessary `get` before `{operation}`"), + |diag| { + // Covers `.get()` including the dot and any whitespace before it. + let removal_span = get_call.span.with_lo(recv.span.hi()); + let applicability = if span_contains_comment(cx, removal_span) { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }; + diag.span_suggestion_verbose(removal_span, "remove this", "", applicability); + }, + ); +} + +/// Checks whether replacing the right-hand primitive operand with its `NonZero` receiver resolves +/// to an unsigned standard-library operator implementation that is usable under `msrv`. In a +/// `const` context that means const-stable, which the `NonZero` operator implementations are not. +fn has_nonzero_operator<'tcx>( + cx: &LateContext<'tcx>, + lhs: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + nz_ty: Ty<'tcx>, + trait_id: DefId, + msrv: Msrv, +) -> bool { + let lhs_ty = cx.typeck_results().expr_ty(lhs); + let ty::Adt(_, args) = nz_ty.kind() else { + return false; + }; + let inner_ty = args.type_at(0); + + // Primitive operators forward some reference operands, whereas the `NonZero` implementations + // do not. Require the exact written operand types so the replacement is guaranteed to resolve. + lhs_ty == inner_ty + && cx.typeck_results().expr_ty(recv) == nz_ty + && matches!(lhs_ty.kind(), ty::Uint(_)) + && implements_trait(cx, lhs_ty, trait_id, &[nz_ty.into()]) + && cx.tcx.non_blanket_impls_for_ty(trait_id, lhs_ty).any(|impl_id| { + let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity().skip_norm_wip(); + trait_ref.args.type_at(1) == nz_ty && msrv.is_stable_or_const_stable(cx, impl_id) + }) +} + +/// Checks whether `nz_ty` has an inherent method `name` taking nothing but `self` and returning +/// exactly `ret_ty`, which is usable under `msrv` (const-stable when in a `const` context, stable +/// otherwise). +fn has_matching_method<'tcx>( + cx: &LateContext<'tcx>, + nonzero_did: DefId, + nz_ty: Ty<'tcx>, + name: Symbol, + ret_ty: Ty<'tcx>, + msrv: Msrv, +) -> bool { + cx.tcx.inherent_impls(nonzero_did).iter().any(|&impl_did| { + // The integer methods live in concrete `impl NonZero`-style blocks, so their + // signatures need no instantiation. Restricting to the impl matching the receiver also + // keeps signed-only methods off unsigned `NonZero`s and vice versa. + cx.tcx.type_of(impl_did).instantiate_identity().skip_norm_wip() == nz_ty + && cx + .tcx + .associated_items(impl_did) + .filter_by_name_unhygienic(name) + .any(|item| { + item.is_fn() && { + let sig = cx.tcx.fn_sig(item.def_id).instantiate_identity().skip_binder(); + sig.inputs().len() == 1 + && sig.output() == ret_ty + && msrv.is_stable_or_const_stable(cx, item.def_id) + } + }) + }) +} diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 81ffd0f48c763..0f59c7696bf54 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -403,7 +403,7 @@ impl EarlyLintPass for NonExpressiveNames { return; } - if let ItemKind::Fn(box ast::Fn { + if let ItemKind::Fn(ast::Fn { ref sig, body: Some(ref blk), .. @@ -418,7 +418,7 @@ impl EarlyLintPass for NonExpressiveNames { return; } - if let AssocItemKind::Fn(box ast::Fn { + if let AssocItemKind::Fn(ast::Fn { ref sig, body: Some(ref blk), .. diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index e7ee8535e5f5a..ea3b93c071526 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -186,11 +186,7 @@ fn ty_allowed_without_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty return true; } - if is_copy(cx, ty) && !contains_pointer_like(cx, ty) { - return true; - } - - false + is_copy(cx, ty) && !contains_pointer_like(cx, ty) } /// Heuristic to allow cases like `Vec<*const u8>` diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs index 0cb764bbe2c33..1bd954bf1421e 100644 --- a/src/tools/clippy/clippy_lints/src/operators/mod.rs +++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs @@ -1095,6 +1095,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs); misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs); modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false); + integer_division_remainder_used::check(cx, bin_op, lhs, rhs, e.span); }, ExprKind::Assign(lhs, rhs, _) => { assign_op_pattern::check(cx, e, lhs, rhs, self.msrv); diff --git a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs index 11eb17590353b..4220ed9b5f50a 100644 --- a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs @@ -34,7 +34,7 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]); impl EarlyLintPass for OptionEnvUnwrap { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind + if let ExprKind::MethodCall(MethodCall { seg, receiver, .. }) = &expr.kind && matches!(seg.ident.name, sym::expect | sym::unwrap) && is_direct_expn_of(receiver.span, sym::option_env).is_some() { diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs index 996c8d00ed15c..d696296301893 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs @@ -41,11 +41,11 @@ declare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]); impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let span = expr.span; - if !span.in_external_macro(cx.tcx.sess.source_map()) && - let Some(body_expr) = desugar_async_block(cx, expr) && + if let Some(body_expr) = desugar_async_block(cx, expr) && let Some(expr) = desugar_await(peel_blocks(body_expr)) && // The await prefix must not come from a macro as its content could change in the future. expr.span.eq_ctxt(body_expr.span) && + !span.in_external_macro(cx.tcx.sess.source_map()) && // The await prefix must implement Future, as implementing IntoFuture is not enough. let Some(future_trait) = cx.tcx.lang_items().future_trait() && implements_trait(cx, cx.typeck_results().expr_ty(expr), future_trait, &[]) && diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 1a2603640e008..6f540148b40cd 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -14,15 +14,6 @@ use rustc_middle::ty::{self, Ty}; use rustc_span::def_id::LocalDefId; use rustc_span::{BytePos, Span}; -macro_rules! unwrap_or_continue { - ($x:expr) => { - match $x { - Some(x) => x, - None => continue, - } - }; -} - declare_clippy_lint! { /// ### What it does /// Checks for a redundant `clone()` (and its relatives) which clones an owned @@ -94,8 +85,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { continue; } - let (fn_def_id, arg, arg_ty, clone_ret) = - unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind)); + let Some((fn_def_id, arg, arg_ty, clone_ret)) = is_call_with_ref_arg(cx, mir, &terminator.kind) else { + continue; + }; let fn_name = cx.tcx.get_diagnostic_name(fn_def_id); @@ -116,7 +108,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { } // `{ arg = &cloned; clone(move arg); }` or `{ arg = &cloned; to_path_buf(arg); }` - let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb)); + let Some((cloned, cannot_move_out)) = find_stmt_assigns_to(cx, mir, arg, from_borrow, bb) else { + continue; + }; let loc = mir::Location { block: bb, @@ -157,8 +151,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { continue; }; - let (local, cannot_move_out) = - unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0])); + let Some((local, cannot_move_out)) = find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0]) else { + continue; + }; let loc = mir::Location { block: bb, statement_index: mir.basic_blocks[bb].statements.len(), diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs index eafea40927fd8..25c137dec7375 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs @@ -163,10 +163,6 @@ fn get_parent_call_exprs<'tcx>( impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { - if expr.span.in_external_macro(cx.sess().source_map()) { - return; - } - if let ExprKind::Call(recv, _) = expr.kind // don't lint if the receiver is a call, too. // we do this in order to prevent linting multiple times; consider: @@ -174,6 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { // ^^ we only want to lint for this call (but we walk up the calls to consider both calls). // without this check, we'd end up linting twice. && !matches!(recv.kind, ExprKind::Call(..)) + && !expr.span.in_external_macro(cx.sess().source_map()) // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is // the same as the one the call is in. // For instance, let's assume `x!()` returns a closure: diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index de80781d64ded..273ea7506431e 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -94,13 +94,13 @@ impl EarlyLintPass for RedundantStaticLifetimes { } if !item.span.from_expansion() { - if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind { + if let ItemKind::Const(ConstItem { ty: ref var_type, .. }) = item.kind { Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime"); // Don't check associated consts because `'static` cannot be elided on those (issue // #2438) } - if let ItemKind::Static(box StaticItem { ty: ref var_type, .. }) = item.kind { + if let ItemKind::Static(StaticItem { ty: ref var_type, .. }) = item.kind { Self::visit_type(var_type, cx, "statics have by default a `'static` lifetime"); } } diff --git a/src/tools/clippy/clippy_lints/src/rest_when_destructuring_struct.rs b/src/tools/clippy/clippy_lints/src/rest_when_destructuring_struct.rs index 865bb28689e5f..89af7a520ce3e 100644 --- a/src/tools/clippy/clippy_lints/src/rest_when_destructuring_struct.rs +++ b/src/tools/clippy/clippy_lints/src/rest_when_destructuring_struct.rs @@ -91,8 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for RestWhenDestructuringStruct { && let qty = cx.typeck_results().qpath_res(&path, pat.hir_id) && let ty = cx.typeck_results().pat_ty(pat) && let ty::Adt(a, _) = ty.kind() - && let Some(vid) = qty.opt_def_id().map(|x| a.variant_index_with_id(x)) - && let Some(variant) = a.variants().get(vid) + && let variant = a.variant_of_res(qty) { let mut missing_suggestions = String::new(); let mut needs_dotdot = variant.field_list_has_applicable_non_exhaustive(); diff --git a/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs b/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs index 1041dadaf4d10..33d3e15412060 100644 --- a/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs +++ b/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs @@ -6,8 +6,8 @@ use clippy_utils::visitors::for_each_expr; use clippy_utils::{binary_expr_needs_parentheses, fn_def_id, span_contains_non_whitespace}; use core::ops::ControlFlow; use rustc_errors::Applicability; -use rustc_hir::{Block, Expr, PatKind, StmtKind}; -use rustc_lint::{LateContext, LintContext as _}; +use rustc_hir::{Block, Expr, PatKind, Stmt, StmtKind}; +use rustc_lint::{LateContext, Level, LintContext as _}; use rustc_middle::ty::GenericArgKind; use rustc_span::edition::Edition; @@ -28,7 +28,7 @@ pub(super) fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>) && !initexpr.span.in_external_macro(cx.sess().source_map()) && !retexpr.span.in_external_macro(cx.sess().source_map()) && !local.span.from_expansion() - && !span_contains_non_whitespace(cx, stmt.span.between(retexpr.span), false) + && has_lint_attrs_or_only_whitespace_between(cx, retexpr, stmt) { span_lint_hir_and_then( cx, @@ -86,3 +86,16 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) }) .is_some() } + +/// Returns true if the return expression has lint-level attributes, +/// or if there is only whitespace between `let` and return expression. +/// Non-lint attrs like `#[cfg]` should still block. +fn has_lint_attrs_or_only_whitespace_between(cx: &LateContext<'_>, retexpr: &Expr<'_>, stmt: &Stmt<'_>) -> bool { + // TODO: Turn into find_attr! when lint level attr parsing is done. + let retexpr_attrs = cx.tcx.hir_attrs(retexpr.hir_id); + + retexpr_attrs + .iter() + .any(|a| a.name().is_some_and(|name| Level::from_symbol(name).is_some())) + || !span_contains_non_whitespace(cx, stmt.span.between(retexpr.span), false) +} diff --git a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs index ffed62015ddaf..45eca1f95fb41 100644 --- a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs @@ -1,4 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::in_automatically_derived; use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::{Block, ExprKind}; @@ -39,6 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned { if !block.span.from_expansion() && let Some(expr) = block.expr && !from_attr_macro(expr.span) + && !in_automatically_derived(cx.tcx, expr.hir_id) && let t_expr = cx.typeck_results().expr_ty(expr) && t_expr.is_unit() && let mut app = Applicability::MachineApplicable diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index bd23aabeb08a3..d97a1205d4378 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -320,11 +320,11 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { ); } - if !e.span.in_external_macro(cx.sess().source_map()) - && let ExprKind::MethodCall(path, receiver, ..) = &e.kind + if let ExprKind::MethodCall(path, receiver, ..) = &e.kind && path.ident.name == sym::as_bytes && let ExprKind::Lit(lit) = &receiver.kind && let LitKind::Str(lit_content, _) = &lit.node + && !e.span.in_external_macro(cx.sess().source_map()) { let callsite = snippet(cx, receiver.span.source_callsite(), r#""foo""#); let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 3ebe96c177c6e..23c137c25f823 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -247,7 +247,13 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize // FIXME(pin_ergonomics): handle pinned patterns | Ref(_, _, Mutability::Not) // Dealt with elsewhere. - | Or(_) | Paren(_) | Deref(_) | Guard(..) => false, + | Or(_) | Paren(_) | Guard(..) => false, + // Transform `deref!(x) | ... | deref!(y)` into `deref!(x | y)`. + Deref(target) => extend_with_matching( + target, start, alternatives, + |k| matches!(k, Deref(_)), + |k| always_pat!(k, Deref(p) => *p), + ), // Transform `box x | ... | box y` into `box (x | y)`. // // The cases below until `Slice(...)` deal with *singleton* products. diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index cb61559855a02..dcd82e29a0bee 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -156,10 +156,7 @@ fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool { return false; } - if is_ok_wild_or_dotdot_pattern(cx, arm.pat) { - return true; - } - false + is_ok_wild_or_dotdot_pattern(cx, arm.pat) } fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) { diff --git a/src/tools/clippy/clippy_lints/src/unused_rounding.rs b/src/tools/clippy/clippy_lints/src/unused_rounding.rs index 887b622b50eb7..3f7055d8674ce 100644 --- a/src/tools/clippy/clippy_lints/src/unused_rounding.rs +++ b/src/tools/clippy/clippy_lints/src/unused_rounding.rs @@ -33,7 +33,7 @@ declare_clippy_lint! { declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]); fn is_useless_rounding(cx: &EarlyContext<'_>, expr: &Expr) -> Option<(Symbol, String)> { - if let ExprKind::MethodCall(box MethodCall { + if let ExprKind::MethodCall(MethodCall { seg: name_ident, receiver, .. diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml index db6108cc9861e..b829b1100d377 100644 --- a/src/tools/clippy/clippy_utils/Cargo.toml +++ b/src/tools/clippy/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.99" +version = "0.1.100" edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md index 9aa097f8863ec..55db48e273fd1 100644 --- a/src/tools/clippy/clippy_utils/README.md +++ b/src/tools/clippy/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2026-08-07 +nightly-2026-08-20 ``` diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index f3c4ae3500af7..39c0e424b6585 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -28,7 +28,7 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) { // Always use .0 because we do not generate separate lint doc pages for rust patch releases Some("stable") => concat!("rust-1.", env!("CARGO_PKG_VERSION_PATCH"), ".0"), Some("beta") => "beta", - _ => "master", + _ => "main", } )); } diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 736369ba78577..442eda329a475 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -370,9 +370,14 @@ impl<'a> VecArgs<'a> { pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option> { if let ExprKind::Call(fun, args) = expr.kind && let ExprKind::Path(ref qpath) = fun.kind - && is_expn_of(fun.span, sym::vec).is_some() && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id) + && matches!( + name, + sym::vec_from_elem | sym::box_assume_init_into_vec_unsafe | sym::vec_new + ) + // Do the cheap checks first, since `is_expn_of` walks the whole expansion chain. + && is_expn_of(fun.span, sym::vec).is_some() { return match (name, args) { (sym::vec_from_elem, [elem, size]) => { diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 19388e6cd35dd..75987ea96ce90 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1424,7 +1424,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_name(path.ident.name); }, } - // self.maybe_typeck_results.unwrap().qpath_res(p, id).hash(&mut self.s); } pub fn hash_pat_expr(&mut self, lit: &PatExpr<'_>) { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 9e69df1640e5e..8b47c79aa6da2 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1,4 +1,5 @@ #![feature(box_patterns)] +#![feature(deref_patterns)] #![feature(macro_metavar_expr)] #![feature(rustc_private)] #![feature(unwrap_infallible)] @@ -134,12 +135,12 @@ macro_rules! extract_msrv_attr { () => { fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes(sess, attrs); + self.msrv.check_attributes(attrs); } fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes_post(sess, attrs); + self.msrv.check_attributes_post(attrs); } }; } diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index 40c553d1c9e69..56fcaa637cb88 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -183,7 +183,7 @@ pub fn local_assignments(mir: &Body<'_>, local: Local) -> Vec { fn is_local_assignment(mir: &Body<'_>, local: Local, location: Location) -> bool { match mir.stmt_at(location) { Either::Left(statement) => { - if let StatementKind::Assign(box (place, _)) = statement.kind { + if let StatementKind::Assign((place, _)) = statement.kind { place.as_local() == Some(local) } else { false diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index dae6661c5ee1a..7ed28d1846ca5 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -157,7 +157,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) { match rvalue { Use(op, _) | Repeat(op, _) | Cast(_, op, _) | UnaryOp(_, op) => visit_op(op), Aggregate(_, ops) => ops.iter().for_each(visit_op), - BinaryOp(_, box (lhs, rhs)) => { + BinaryOp(_, (lhs, rhs)) => { visit_op(lhs); visit_op(rhs); }, diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 48819d53da771..4f4d8f3990d2e 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -1,11 +1,12 @@ -use crate::sym; +use crate::{is_in_const_context, sym}; use rustc_ast::Attribute; use rustc_ast::attr::AttributeExt; use rustc_attr_parsing::parse_version; use rustc_data_structures::smallvec::SmallVec; use rustc_hir::attrs::RustcVersion; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::{HirId, StabilityLevel, StableSince}; +use rustc_hir::{Constness, HirId, StabilityLevel, StableSince}; use rustc_lint::LateContext; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -137,7 +138,7 @@ impl Msrv { fn for_attrs(self, tcx: TyCtxt<'_>, node: HirId) -> Option { once(node) .chain(tcx.hir_parent_id_iter(node)) - .find_map(|id| parse_attrs(tcx.sess, tcx.hir_attrs(id))) + .find_map(|id| parse_attrs(tcx.hir_attrs(id))) .or(self.0) } @@ -157,8 +158,46 @@ impl Msrv { } pub fn is_stable(self, cx: &LateContext<'_>, def_id: DefId) -> bool { - cx.tcx.lookup_stability(def_id).is_none_or(|stability| { - if let StabilityLevel::Stable { since, .. } = stability.level { + self.stability_met(cx, cx.tcx.lookup_stability(def_id).map(|stability| stability.level)) + } + + /// Checks whether `def_id` is `const` and const-stable since a version met by the MSRV. + /// + /// `def_id` must identify a function-like definition or an impl. + /// + /// Nothing in the crate being linted carries a const-stability attribute, so `const` fns and + /// impls defined there are treated as meeting any MSRV, mirroring + /// [`is_stable`](Self::is_stable). + pub fn is_const_stable(self, cx: &LateContext<'_>, def_id: DefId) -> bool { + let constness = match cx.tcx.def_kind(def_id) { + // The constness of a trait impl is not encoded in crate metadata, where `constness` + // would decode as its default of `Const`. It is only available from the impl header. + DefKind::Impl { of_trait: true } => cx.tcx.impl_trait_header(def_id).constness, + _ => cx.tcx.constness(def_id), + }; + + matches!(constness, Constness::Const { .. }) + && self.stability_met( + cx, + cx.tcx.lookup_const_stability(def_id).map(|stability| stability.level), + ) + } + + /// Checks the stability relevant to where we are: const-stability inside a `const` context, + /// regular stability everywhere else. + /// + /// Like [`is_in_const_context`], this requires the `LateContext` to have an enclosing body. + pub fn is_stable_or_const_stable(self, cx: &LateContext<'_>, def_id: DefId) -> bool { + if is_in_const_context(cx) { + self.is_const_stable(cx, def_id) + } else { + self.is_stable(cx, def_id) + } + } + + fn stability_met(self, cx: &LateContext<'_>, level: Option) -> bool { + level.is_none_or(|level| { + if let StabilityLevel::Stable { since, .. } = level { let version = match since { StableSince::Version(version) => version, StableSince::Current => RustcVersion::CURRENT, @@ -201,24 +240,34 @@ impl MsrvStack { self.current().is_none_or(|msrv| msrv >= required) } - pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { - if let Some(version) = parse_attrs(sess, attrs) { + pub fn check_attributes(&mut self, attrs: &[Attribute]) { + if let Some(version) = parse_attrs(attrs) { SEEN_MSRV_ATTR.store(true, Ordering::Relaxed); self.stack.push(version); } } - pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { - if parse_attrs(sess, attrs).is_some() { + pub fn check_attributes_post(&mut self, attrs: &[Attribute]) { + if parse_attrs(attrs).is_some() { self.stack.pop(); } } } -fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option { +fn parse_attrs(attrs: &[impl AttributeExt]) -> Option { + let msrv_attr = attrs.iter().find(|attr| attr.path_matches(&[sym::clippy, sym::msrv]))?; + + let msrv = msrv_attr.value_str()?; + + parse_version(msrv) +} + +pub fn check_attrs(sess: &Session, attrs: &[impl AttributeExt]) { let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym::msrv])); - let msrv_attr = msrv_attrs.next()?; + let Some(msrv_attr) = msrv_attrs.next() else { + return; + }; if let Some(duplicate) = msrv_attrs.next_back() { sess.dcx() @@ -229,14 +278,11 @@ fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option Vec { path.set_extension("d"); fs::read_to_string(path).unwrap() }; - let mut crates = BTreeMap::<&str, &str>::new(); + // Map `crate_name` -> (`hash`, [`path1`, `path2`, ...]). Important for `rlib`s, as cargo now + // defaults to `-Zembed-metadata=no`, so the `rlib` only contains a metadata stub. + let mut crates = BTreeMap::<&str, (&str, Vec<&str>)>::new(); for line in current_exe_depinfo.lines() { // each dependency is expected to have a Makefile rule like `/path/to/crate-hash.rlib:` let parse_name_path = || { @@ -61,20 +63,25 @@ fn internal_extern_flags() -> Vec { } let path_str = line.strip_suffix(':')?; let path = Path::new(path_str); - if !matches!(path.extension()?.to_str()?, "rlib" | "so" | "dylib" | "dll") { + if !matches!(path.extension()?.to_str()?, "rlib" | "so" | "dylib" | "dll" | "rmeta") { return None; } - let (name, _hash) = path.file_stem()?.to_str()?.rsplit_once('-')?; + let (name, hash) = path.file_stem()?.to_str()?.rsplit_once('-')?; // the "lib" prefix is not present for dll files let name = name.strip_prefix("lib").unwrap_or(name); - Some((name, path_str)) + Some((name, hash, path_str)) }; - if let Some((name, path)) = parse_name_path() + if let Some((name, hash, path)) = parse_name_path() && INTERNAL_TEST_DEPENDENCIES.contains(&name) { - // A dependency may be listed twice if it is available in sysroot, - // and the sysroot dependencies are listed first. - crates.insert(name, path); + // A dependency may be listed twice (identified by the hash) if it is available in sysroot, + // and the sysroot dependencies are listed first. So only keep the last dependency. + let (old_hash, items) = crates.entry(name).or_insert((hash, Vec::new())); + if *old_hash != hash { + *old_hash = hash; + items.clear(); + } + items.push(path); } } let not_found: Vec<&str> = INTERNAL_TEST_DEPENDENCIES @@ -93,7 +100,7 @@ fn internal_extern_flags() -> Vec { let mut args: Vec = crates .into_iter() - .map(|(name, path)| format!("--extern={name}={path}")) + .flat_map(|(name, (_, paths))| paths.into_iter().map(move |path| format!("--extern={name}={path}"))) .collect(); if deps_path.ends_with("deps") { diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs index ddee6e5566fa6..c3256827ba237 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs @@ -1,4 +1,4 @@ -#![feature(proc_macro_hygiene, proc_macro_quote, box_patterns)] +#![feature(proc_macro_hygiene, proc_macro_quote, deref_patterns)] #![allow(clippy::uninlined_format_args, clippy::useless_conversion)] extern crate proc_macro; @@ -10,8 +10,8 @@ use quote::{quote, quote_spanned}; use syn::spanned::Spanned; use syn::token::Star; use syn::{ - FnArg, ImplItem, ItemFn, ItemImpl, ItemStruct, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, TraitItem, - Type, Visibility, parse_macro_input, parse_quote, + Attribute, FnArg, ImplItem, Item, ItemFn, ItemImpl, ItemStruct, ItemTrait, Lifetime, Pat, PatIdent, PatType, + Signature, TraitItem, Type, Visibility, parse_macro_input, parse_quote, }; #[proc_macro_attribute] @@ -42,6 +42,57 @@ pub fn fake_async_trait(_args: TokenStream, input: TokenStream) -> TokenStream { TokenStream::from(quote!(#item)) } +fn add_must_use_attr(attrs: &mut Vec) { + attrs.push(parse_quote!(#[must_use])); +} + +fn desugar_async(attrs: &mut Vec, sig: &mut Signature) { + sig.asyncness = None; + add_must_use_attr(attrs); +} + +#[proc_macro_attribute] +pub fn add_must_use(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut item = parse_macro_input!(input as Item); + + match &mut item { + Item::Fn(item) => add_must_use_attr(&mut item.attrs), + Item::Struct(item) => add_must_use_attr(&mut item.attrs), + Item::Union(item) => add_must_use_attr(&mut item.attrs), + Item::Enum(item) => add_must_use_attr(&mut item.attrs), + Item::Trait(item) => add_must_use_attr(&mut item.attrs), + _ => {}, + } + + TokenStream::from(quote!(#item)) +} + +#[proc_macro_attribute] +pub fn add_must_use_to_async(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut item = parse_macro_input!(input as Item); + + match &mut item { + Item::Fn(item) => desugar_async(&mut item.attrs, &mut item.sig), + Item::Trait(item) => { + for trait_item in &mut item.items { + if let TraitItem::Fn(method) = trait_item { + desugar_async(&mut method.attrs, &mut method.sig); + } + } + }, + Item::Impl(item) => { + for impl_item in &mut item.items { + if let ImplItem::Fn(method) = impl_item { + desugar_async(&mut method.attrs, &mut method.sig); + } + } + }, + _ => {}, + } + + TokenStream::from(quote!(#item)) +} + #[proc_macro_attribute] pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStream { fn make_name(count: usize) -> String { @@ -67,7 +118,7 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea for inner in &mut item.items { if let ImplItem::Fn(method) = inner && let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig) - && let box Type::Reference(reference) = &mut pat_type.ty + && let Type::Reference(reference) = &mut pat_type.ty { // Target only unnamed lifetimes let name = match &reference.lifetime { diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr index c8745628dd977..a01501e87dc68 100644 --- a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr @@ -10,7 +10,7 @@ LL | | } { | = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` -help: try +help: use a binding instead | LL ~ let res = { LL + @@ -23,13 +23,13 @@ error: omit braces around single expression condition --> tests/ui/blocks_in_conditions.rs:36:8 | LL | if { true } { 6 } else { 10 } - | ^^^^^^^^ help: try: `true` + | ^^^^^^^^ help: remove the braces: `true` error: omit braces around single expression condition --> tests/ui/blocks_in_conditions.rs:136:15 | LL | match { Foo.foo() } { - | ^^^^^^^^^^^^^ help: try: `Foo.foo()` + | ^^^^^^^^^^^^^ help: remove the braces: `Foo.foo()` error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions_2021.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions_2021.stderr index 497ee9d679dde..23ded8924333d 100644 --- a/src/tools/clippy/tests/ui/blocks_in_conditions_2021.stderr +++ b/src/tools/clippy/tests/ui/blocks_in_conditions_2021.stderr @@ -10,7 +10,7 @@ LL | | } { | = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` -help: try +help: use a binding instead | LL ~ let res = { LL + diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.rs b/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.rs new file mode 100644 index 0000000000000..e800dd0a49539 --- /dev/null +++ b/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.rs @@ -0,0 +1,25 @@ +fn issue_17068() { + fn nop() {} + + match Some(()) { + Some(()) => match { + //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + nop(); + 42 + } { + 42 => nop(), + _ => nop(), + }, + None => nop(), + } + + let _x = if { + //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + let v = 1; + v == 1 + } { + 1 + } else { + 2 + }; +} diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.stderr new file mode 100644 index 0000000000000..fadeedbe6007f --- /dev/null +++ b/src/tools/clippy/tests/ui/blocks_in_conditions_unfixable.stderr @@ -0,0 +1,27 @@ +error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + --> tests/ui/blocks_in_conditions_unfixable.rs:5:21 + | +LL | ... Some(()) => match { + | ___________________^ +LL | | ... +LL | | ... nop(); +LL | | ... 42 +LL | | ... } { + | |_______^ + | + = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` + +error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + --> tests/ui/blocks_in_conditions_unfixable.rs:16:14 + | +LL | let _x = if { + | ______________^ +LL | | +LL | | let v = 1; +LL | | v == 1 +LL | | } { + | |_____^ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs index 6ee003664117d..bf239f13e1e89 100644 --- a/src/tools/clippy/tests/ui/cast.rs +++ b/src/tools/clippy/tests/ui/cast.rs @@ -592,3 +592,13 @@ fn issue16045() { Ok(()) } } + +fn issue_17501() { + macro_rules! cast_from_macro { + () => { + 5_i64 + }; + } + let _ = cast_from_macro!() as i32; + //~^ cast_possible_truncation +} diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr index 14b84b1ff1ef2..6b44ff344392e 100644 --- a/src/tools/clippy/tests/ui/cast.stderr +++ b/src/tools/clippy/tests/ui/cast.stderr @@ -770,5 +770,18 @@ error: casting `u8` to `i8` may wrap around the value LL | _ = val? as i8; | ^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `val?.cast_signed()` -error: aborting due to 95 previous errors +error: casting `i64` to `i32` may truncate the value + --> tests/ui/cast.rs:602:13 + | +LL | let _ = cast_from_macro!() as i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL - let _ = cast_from_macro!() as i32; +LL + let _ = i32::try_from(cast_from_macro!()); + | + +error: aborting due to 96 previous errors diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index 0fc156f2c19e0..bc68acf366dd1 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -82,7 +82,7 @@ fn test_units() { /// OCaml /// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry /// OpenType -/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport +/// WebAuthn WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport /// TensorFlow /// TrueType /// iOS macOS FreeBSD NetBSD OpenBSD NixOS diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index cfb8b67afc012..f13e5e882d85b 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -82,7 +82,7 @@ fn test_units() { /// OCaml /// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry /// OpenType -/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport +/// WebAuthn WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport /// TensorFlow /// TrueType /// iOS macOS FreeBSD NetBSD OpenBSD NixOS diff --git a/src/tools/clippy/tests/ui/double_must_use_proc_macro.rs b/src/tools/clippy/tests/ui/double_must_use_proc_macro.rs new file mode 100644 index 0000000000000..b8c68318f16b7 --- /dev/null +++ b/src/tools/clippy/tests/ui/double_must_use_proc_macro.rs @@ -0,0 +1,87 @@ +//@aux-build:proc_macro_attr.rs +//@no-rustfix +#![warn(clippy::double_must_use, clippy::must_use_unit)] +#![allow(dead_code)] + +extern crate proc_macro_attr; + +use proc_macro_attr::{add_must_use, add_must_use_to_async, dummy}; + +#[add_must_use_to_async] +async fn function() -> Result<(), ()> { + Ok(()) +} + +#[add_must_use_to_async] +async fn unit_function() {} + +#[add_must_use_to_async] +trait AsyncTrait { + async fn method(&self) -> Result<(), ()>; +} + +struct Struct; + +#[add_must_use_to_async] +impl Struct { + async fn method(&self) -> Result<(), ()> { + Ok(()) + } +} + +#[add_must_use] +struct MustUseStruct; + +#[add_must_use] +union MustUseUnion { + field: u32, +} + +#[add_must_use] +enum MustUseEnum { + Variant, +} + +#[add_must_use] +trait MustUseTrait {} + +impl MustUseTrait for u32 {} + +#[add_must_use] +fn macro_must_use() -> Result<(), ()> { + Ok(()) +} + +#[must_use] +fn returns_must_use_struct() -> MustUseStruct { + //~^ double_must_use + MustUseStruct +} + +#[must_use] +fn returns_must_use_union() -> MustUseUnion { + //~^ double_must_use + MustUseUnion { field: 0 } +} + +#[must_use] +fn returns_must_use_enum() -> MustUseEnum { + //~^ double_must_use + MustUseEnum::Variant +} + +#[must_use] +fn returns_must_use_trait() -> impl MustUseTrait { + //~^ double_must_use + 0u32 +} + +#[dummy] +#[must_use] +#[inline] +fn user_must_use() -> Result<(), ()> { + //~^ double_must_use + Ok(()) +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/double_must_use_proc_macro.stderr b/src/tools/clippy/tests/ui/double_must_use_proc_macro.stderr new file mode 100644 index 0000000000000..e89b14d966b45 --- /dev/null +++ b/src/tools/clippy/tests/ui/double_must_use_proc_macro.stderr @@ -0,0 +1,62 @@ +error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]` + --> tests/ui/double_must_use_proc_macro.rs:56:1 + | +LL | #[must_use] + | ----------- help: remove the attribute +LL | fn returns_must_use_struct() -> MustUseStruct { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: alternatively, you may add an explicit reason to the `must_use` attribute + = note: `-D clippy::double-must-use` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` + +error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]` + --> tests/ui/double_must_use_proc_macro.rs:62:1 + | +LL | #[must_use] + | ----------- help: remove the attribute +LL | fn returns_must_use_union() -> MustUseUnion { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: alternatively, you may add an explicit reason to the `must_use` attribute + +error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]` + --> tests/ui/double_must_use_proc_macro.rs:68:1 + | +LL | #[must_use] + | ----------- help: remove the attribute +LL | fn returns_must_use_enum() -> MustUseEnum { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: alternatively, you may add an explicit reason to the `must_use` attribute + +error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]` + --> tests/ui/double_must_use_proc_macro.rs:74:1 + | +LL | #[must_use] + | ----------- help: remove the attribute +LL | fn returns_must_use_trait() -> impl MustUseTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the return type is implementer of `MustUseTrait` + --> tests/ui/double_must_use_proc_macro.rs:74:32 + | +LL | fn returns_must_use_trait() -> impl MustUseTrait { + | ^^^^^^^^^^^^^^^^^ + = note: alternatively, you may add an explicit reason to the `must_use` attribute + +error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]` + --> tests/ui/double_must_use_proc_macro.rs:82:1 + | +LL | fn user_must_use() -> Result<(), ()> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove `must_use` + --> tests/ui/double_must_use_proc_macro.rs:80:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ + = note: alternatively, you may add an explicit reason to the `must_use` attribute + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/integer_division_remainder_used.rs b/src/tools/clippy/tests/ui/integer_division_remainder_used.rs index 2c57c23904ec1..f8d303b04bfc8 100644 --- a/src/tools/clippy/tests/ui/integer_division_remainder_used.rs +++ b/src/tools/clippy/tests/ui/integer_division_remainder_used.rs @@ -38,6 +38,13 @@ fn main() { let i = a / &4; //~^ integer_division_remainder_used + // should trigger on DivAssign and RemAssign + let mut j = 10; + j /= 2; + //~^ integer_division_remainder_used + j %= 3; + //~^ integer_division_remainder_used + // should not trigger on custom Div and Rem let w = CustomOps(3); let x = CustomOps(4); diff --git a/src/tools/clippy/tests/ui/integer_division_remainder_used.stderr b/src/tools/clippy/tests/ui/integer_division_remainder_used.stderr index 3fda04619aab8..84fa20020adc1 100644 --- a/src/tools/clippy/tests/ui/integer_division_remainder_used.stderr +++ b/src/tools/clippy/tests/ui/integer_division_remainder_used.stderr @@ -55,5 +55,17 @@ error: use of `/` has been disallowed in this context LL | let i = a / &4; | ^^^^^^ -error: aborting due to 9 previous errors +error: use of `/` has been disallowed in this context + --> tests/ui/integer_division_remainder_used.rs:43:5 + | +LL | j /= 2; + | ^^^^^^ + +error: use of `%` has been disallowed in this context + --> tests/ui/integer_division_remainder_used.rs:45:5 + | +LL | j %= 3; + | ^^^^^^ + +error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed index ed9843c3e13d3..c904d882d9472 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed @@ -278,6 +278,24 @@ fn has_comment() -> Vec { v } +mod issue16451 { + + fn expect_on_return_expr() -> std::collections::BTreeMap<(), ()> { + let stuff = std::collections::BTreeMap::new(); + + // TODO: Fill `stuff` + + #[expect(clippy::let_and_return)] + stuff + } + + fn cfg_on_return_expr() -> i32 { + let x = 5; + #[cfg(debug_assertions)] + x + } +} + fn wrongly_unmangled_macros() -> i32 { let x = 1; macro_rules! plus_one { diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr b/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr index 8312b6711a6ac..c91b355c42d08 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr @@ -149,7 +149,7 @@ LL ~ ({ true } || { false } && { 2 <= 3 }) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:290:5 + --> tests/ui/let_and_return.rs:308:5 | LL | let y = plus_one!(x); | --------------------- unnecessary `let` binding diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed index 964d4b9f98d89..e931e1ec7ff22 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed @@ -278,6 +278,24 @@ fn has_comment() -> Vec { v } +mod issue16451 { + + fn expect_on_return_expr() -> std::collections::BTreeMap<(), ()> { + let stuff = std::collections::BTreeMap::new(); + + // TODO: Fill `stuff` + + #[expect(clippy::let_and_return)] + stuff + } + + fn cfg_on_return_expr() -> i32 { + let x = 5; + #[cfg(debug_assertions)] + x + } +} + fn wrongly_unmangled_macros() -> i32 { let x = 1; macro_rules! plus_one { diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr b/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr index 98ded31b1954f..7407e504b7c54 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr @@ -225,7 +225,7 @@ LL + }? | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:290:5 + --> tests/ui/let_and_return.rs:308:5 | LL | let y = plus_one!(x); | --------------------- unnecessary `let` binding diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs index e7239e90cb3a6..f7cf1c7d0439b 100644 --- a/src/tools/clippy/tests/ui/let_and_return.rs +++ b/src/tools/clippy/tests/ui/let_and_return.rs @@ -278,6 +278,24 @@ fn has_comment() -> Vec { v } +mod issue16451 { + + fn expect_on_return_expr() -> std::collections::BTreeMap<(), ()> { + let stuff = std::collections::BTreeMap::new(); + + // TODO: Fill `stuff` + + #[expect(clippy::let_and_return)] + stuff + } + + fn cfg_on_return_expr() -> i32 { + let x = 5; + #[cfg(debug_assertions)] + x + } +} + fn wrongly_unmangled_macros() -> i32 { let x = 1; macro_rules! plus_one { diff --git a/src/tools/clippy/tests/ui/manual_contains.fixed b/src/tools/clippy/tests/ui/manual_contains.fixed index 340b439f6c40a..41b0f10a0598b 100644 --- a/src/tools/clippy/tests/ui/manual_contains.fixed +++ b/src/tools/clippy/tests/ui/manual_contains.fixed @@ -50,6 +50,15 @@ fn should_lint() { let values = &vec[..]; let _ = values.contains(&(4 + 1)); //~^ manual_contains + + // Eager bitwise expressions still lint when they do not mention the element. + let mask = 0x0f_u8; + let other = 0x03_u8; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.contains(&(mask & other)); + //~^ manual_contains + let _ = values.contains(&(mask | other)); + //~^ manual_contains } fn should_not_lint() { @@ -85,6 +94,14 @@ fn should_not_lint() { }; let _ = values.iter().any(|&v| v == count()); let _ = values.iter().any(|&v| v == v * 2); + + // Don't fire when both sides use the slice element. #17563 + let mask = 0x0f_u8; + let values: &[u8] = &[1, 2, 3]; + let _ = values.iter().any(|&i| i & mask == i); + let _ = values.iter().any(|&i| i == i & mask); + let _ = values.iter().any(|&i| i == !i); + let _ = values.iter().any(|i| *i == *i & mask); } fn foo(values: &[u8]) -> bool { diff --git a/src/tools/clippy/tests/ui/manual_contains.rs b/src/tools/clippy/tests/ui/manual_contains.rs index 75c701f170b41..0609651765be3 100644 --- a/src/tools/clippy/tests/ui/manual_contains.rs +++ b/src/tools/clippy/tests/ui/manual_contains.rs @@ -50,6 +50,15 @@ fn should_lint() { let values = &vec[..]; let _ = values.iter().any(|&v| v == 4 + 1); //~^ manual_contains + + // Eager bitwise expressions still lint when they do not mention the element. + let mask = 0x0f_u8; + let other = 0x03_u8; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| v == mask & other); + //~^ manual_contains + let _ = values.iter().any(|&v| mask | other == v); + //~^ manual_contains } fn should_not_lint() { @@ -85,6 +94,14 @@ fn should_not_lint() { }; let _ = values.iter().any(|&v| v == count()); let _ = values.iter().any(|&v| v == v * 2); + + // Don't fire when both sides use the slice element. #17563 + let mask = 0x0f_u8; + let values: &[u8] = &[1, 2, 3]; + let _ = values.iter().any(|&i| i & mask == i); + let _ = values.iter().any(|&i| i == i & mask); + let _ = values.iter().any(|&i| i == !i); + let _ = values.iter().any(|i| *i == *i & mask); } fn foo(values: &[u8]) -> bool { diff --git a/src/tools/clippy/tests/ui/manual_contains.stderr b/src/tools/clippy/tests/ui/manual_contains.stderr index e6e2dea560c60..2ccb3ed35600c 100644 --- a/src/tools/clippy/tests/ui/manual_contains.stderr +++ b/src/tools/clippy/tests/ui/manual_contains.stderr @@ -62,16 +62,28 @@ LL | let _ = values.iter().any(|&v| v == 4 + 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&(4 + 1))` error: using `contains()` instead of `iter().any()` is more efficient - --> tests/ui/manual_contains.rs:91:5 + --> tests/ui/manual_contains.rs:58:13 + | +LL | let _ = values.iter().any(|&v| v == mask & other); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&(mask & other))` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:60:13 + | +LL | let _ = values.iter().any(|&v| mask | other == v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&(mask | other))` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:108:5 | LL | values.iter().any(|&v| v == 10) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)` error: using `contains()` instead of `iter().any()` is more efficient - --> tests/ui/manual_contains.rs:96:5 + --> tests/ui/manual_contains.rs:113:5 | LL | values.iter().any(|&v| v == 10) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)` -error: aborting due to 12 previous errors +error: aborting due to 14 previous errors diff --git a/src/tools/clippy/tests/ui/manual_option_zip.fixed b/src/tools/clippy/tests/ui/manual_option_zip.fixed index 8b821f8737cbb..799fdb8d61bc6 100644 --- a/src/tools/clippy/tests/ui/manual_option_zip.fixed +++ b/src/tools/clippy/tests/ui/manual_option_zip.fixed @@ -1,5 +1,6 @@ #![warn(clippy::manual_option_zip)] #![expect(clippy::bind_instead_of_map)] +#![allow(clippy::option_zip_none)] fn main() {} diff --git a/src/tools/clippy/tests/ui/manual_option_zip.rs b/src/tools/clippy/tests/ui/manual_option_zip.rs index 5d059a98ee12c..76b3ccb7555df 100644 --- a/src/tools/clippy/tests/ui/manual_option_zip.rs +++ b/src/tools/clippy/tests/ui/manual_option_zip.rs @@ -1,5 +1,6 @@ #![warn(clippy::manual_option_zip)] #![expect(clippy::bind_instead_of_map)] +#![allow(clippy::option_zip_none)] fn main() {} diff --git a/src/tools/clippy/tests/ui/manual_option_zip.stderr b/src/tools/clippy/tests/ui/manual_option_zip.stderr index 55175660b7a26..758f016868706 100644 --- a/src/tools/clippy/tests/ui/manual_option_zip.stderr +++ b/src/tools/clippy/tests/ui/manual_option_zip.stderr @@ -1,5 +1,5 @@ error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:10:13 + --> tests/ui/manual_option_zip.rs:11:13 | LL | let _ = a.and_then(|a| b.map(|b| (a, b))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `a.zip(b)` @@ -8,37 +8,37 @@ LL | let _ = a.and_then(|a| b.map(|b| (a, b))); = help: to override `-D warnings` add `#[allow(clippy::manual_option_zip)]` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:16:13 + --> tests/ui/manual_option_zip.rs:17:13 | LL | let _ = a.and_then(|a| b.map(|b| (a, b))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `a.zip(b)` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:21:13 + --> tests/ui/manual_option_zip.rs:22:13 | LL | let _ = None::.and_then(|a| b.map(|b| (a, b))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `None::.zip(b)` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:27:13 + --> tests/ui/manual_option_zip.rs:28:13 | LL | let _ = a.and_then(|a| b.map(|b| (b, a))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.zip(a)` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:34:13 + --> tests/ui/manual_option_zip.rs:35:13 | LL | let _ = a.and_then(|a| { b.map(|b| (a, b)) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `a.zip(b)` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:37:13 + --> tests/ui/manual_option_zip.rs:38:13 | LL | let _ = a.and_then(|a| b.map(|b| { (a, b) })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `a.zip(b)` error: manual implementation of `Option::zip` - --> tests/ui/manual_option_zip.rs:40:13 + --> tests/ui/manual_option_zip.rs:41:13 | LL | let _ = a.and_then(|a| { b.map(|b| { (a, b) }) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `a.zip(b)` diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs index c8409d78ed77c..64a28d38747e4 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs @@ -1,5 +1,3 @@ -//@compile-flags: -Zdeduplicate-diagnostics=yes - #![feature(custom_inner_attributes)] #![clippy::msrv = "invalid.version"] //~^ ERROR: `invalid.version` is not a valid Rust version diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr index dbc276ed89df3..8fff1a70da35b 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr @@ -1,35 +1,35 @@ error: `invalid.version` is not a valid Rust version - --> tests/ui/min_rust_version_invalid_attr.rs:4:1 + --> tests/ui/min_rust_version_invalid_attr.rs:2:1 | LL | #![clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `invalid.version` is not a valid Rust version - --> tests/ui/min_rust_version_invalid_attr.rs:9:1 + --> tests/ui/min_rust_version_invalid_attr.rs:7:1 | LL | #[clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `clippy::msrv` is defined multiple times - --> tests/ui/min_rust_version_invalid_attr.rs:16:5 + --> tests/ui/min_rust_version_invalid_attr.rs:14:5 | LL | #![clippy::msrv = "1.10.1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> tests/ui/min_rust_version_invalid_attr.rs:14:5 + --> tests/ui/min_rust_version_invalid_attr.rs:12:5 | LL | #![clippy::msrv = "1.40"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `clippy::msrv` is defined multiple times - --> tests/ui/min_rust_version_invalid_attr.rs:21:9 + --> tests/ui/min_rust_version_invalid_attr.rs:19:9 | LL | #![clippy::msrv = "1.0.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> tests/ui/min_rust_version_invalid_attr.rs:20:9 + --> tests/ui/min_rust_version_invalid_attr.rs:18:9 | LL | #![clippy::msrv = "1.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/needless_bool/early_return.fixed b/src/tools/clippy/tests/ui/needless_bool/early_return.fixed new file mode 100644 index 0000000000000..2ca2aed982029 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool/early_return.fixed @@ -0,0 +1,102 @@ +#![warn(clippy::needless_bool)] +#![allow(dead_code, unused, clippy::needless_return)] + +// The motivating case from uutils/coreutils#12689: a guard returning a wrapped bool +// followed by a trailing wrapped bool literal. +fn is_sparse(blocks: u64, size: u64) -> Result { + Ok(blocks < size / 512) + //~^^^^ needless_bool +} + +fn bare(x: bool) -> bool { + x + //~^^^^ needless_bool +} + +fn bare_negated(x: bool) -> bool { + !x + //~^^^^ needless_bool +} + +fn option_wrapped(x: bool) -> Option { + Some(!x) + //~^^^^ needless_bool +} + +fn complex_condition(a: i32, b: i32) -> Result { + Ok(!(a < b && b > 0)) + //~^^^^ needless_bool +} + +fn multi_if_complex_previous_if(x: bool, y: bool) -> Result { + if y { + let z = x && y; + if z { + return Ok(x); + } + return Ok(true); + } + Ok(x) + //~^^^^ needless_bool +} + +// Do NOT lint: the two values are equal, and the condition might have side effects. +fn same_value(x: bool) -> Result { + if x { + return Ok(true); + } + Ok(true) +} + +// Do NOT lint: mismatched wrappers. +fn mismatched_wrappers(x: bool) -> Result { + if x { + return Err(()); + } + Ok(false) +} + +// Do NOT lint: the guard body has a side effect besides the return. +fn side_effect(x: bool) -> Result { + if x { + println!("hi"); + return Ok(true); + } + Ok(false) +} + +// Do NOT lint: not a constructor, just a function call (could have side effects). +fn make(b: bool) -> bool { + b +} +fn not_a_ctor(x: bool) -> bool { + if x { + return make(true); + } + make(false) +} + +// Do NOT lint: multiple if statements chained one after another. +fn multi_if(x: bool, y: bool) -> Result { + if y { + return Ok(true); + } + if x { + return Ok(true); + } + Ok(false) +} + +// Do NOT lint: multiple if statements chained one after another, even if they have different return +// values. +fn multi_if_different_values(x: bool, y: bool) -> bool { + if y { + return false; + } + if x { + return true; + } + false +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_bool/early_return.rs b/src/tools/clippy/tests/ui/needless_bool/early_return.rs new file mode 100644 index 0000000000000..f1451f7fe415a --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool/early_return.rs @@ -0,0 +1,120 @@ +#![warn(clippy::needless_bool)] +#![allow(dead_code, unused, clippy::needless_return)] + +// The motivating case from uutils/coreutils#12689: a guard returning a wrapped bool +// followed by a trailing wrapped bool literal. +fn is_sparse(blocks: u64, size: u64) -> Result { + if blocks < size / 512 { + return Ok(true); + } + Ok(false) + //~^^^^ needless_bool +} + +fn bare(x: bool) -> bool { + if x { + return true; + } + false + //~^^^^ needless_bool +} + +fn bare_negated(x: bool) -> bool { + if x { + return false; + } + true + //~^^^^ needless_bool +} + +fn option_wrapped(x: bool) -> Option { + if x { + return Some(false); + } + Some(true) + //~^^^^ needless_bool +} + +fn complex_condition(a: i32, b: i32) -> Result { + if a < b && b > 0 { + return Ok(false); + } + Ok(true) + //~^^^^ needless_bool +} + +fn multi_if_complex_previous_if(x: bool, y: bool) -> Result { + if y { + let z = x && y; + if z { + return Ok(x); + } + return Ok(true); + } + if x { + return Ok(true); + } + Ok(false) + //~^^^^ needless_bool +} + +// Do NOT lint: the two values are equal, and the condition might have side effects. +fn same_value(x: bool) -> Result { + if x { + return Ok(true); + } + Ok(true) +} + +// Do NOT lint: mismatched wrappers. +fn mismatched_wrappers(x: bool) -> Result { + if x { + return Err(()); + } + Ok(false) +} + +// Do NOT lint: the guard body has a side effect besides the return. +fn side_effect(x: bool) -> Result { + if x { + println!("hi"); + return Ok(true); + } + Ok(false) +} + +// Do NOT lint: not a constructor, just a function call (could have side effects). +fn make(b: bool) -> bool { + b +} +fn not_a_ctor(x: bool) -> bool { + if x { + return make(true); + } + make(false) +} + +// Do NOT lint: multiple if statements chained one after another. +fn multi_if(x: bool, y: bool) -> Result { + if y { + return Ok(true); + } + if x { + return Ok(true); + } + Ok(false) +} + +// Do NOT lint: multiple if statements chained one after another, even if they have different return +// values. +fn multi_if_different_values(x: bool, y: bool) -> bool { + if y { + return false; + } + if x { + return true; + } + false +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_bool/early_return.stderr b/src/tools/clippy/tests/ui/needless_bool/early_return.stderr new file mode 100644 index 0000000000000..488e41e993516 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_bool/early_return.stderr @@ -0,0 +1,59 @@ +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:7:5 + | +LL | / if blocks < size / 512 { +LL | | return Ok(true); +LL | | } +LL | | Ok(false) + | |_____________^ help: you can reduce it to: `Ok(blocks < size / 512)` + | + = note: `-D clippy::needless-bool` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` + +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:15:5 + | +LL | / if x { +LL | | return true; +LL | | } +LL | | false + | |_________^ help: you can reduce it to: `x` + +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:23:5 + | +LL | / if x { +LL | | return false; +LL | | } +LL | | true + | |________^ help: you can reduce it to: `!x` + +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:31:5 + | +LL | / if x { +LL | | return Some(false); +LL | | } +LL | | Some(true) + | |______________^ help: you can reduce it to: `Some(!x)` + +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:39:5 + | +LL | / if a < b && b > 0 { +LL | | return Ok(false); +LL | | } +LL | | Ok(true) + | |____________^ help: you can reduce it to: `Ok(!(a < b && b > 0))` + +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/needless_bool/early_return.rs:54:5 + | +LL | / if x { +LL | | return Ok(true); +LL | | } +LL | | Ok(false) + | |_____________^ help: you can reduce it to: `Ok(x)` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/needless_nonzero_get.fixed b/src/tools/clippy/tests/ui/needless_nonzero_get.fixed new file mode 100644 index 0000000000000..4e64b735178d2 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_nonzero_get.fixed @@ -0,0 +1,257 @@ +//@aux-build:proc_macros.rs + +#![warn(clippy::needless_nonzero_get)] +// the `msrv` functions below deliberately use items newer than their MSRV +#![allow(clippy::incompatible_msrv)] + +extern crate proc_macros; + +use proc_macros::with_span; +use std::num::{NonZero, NonZeroI32, NonZeroU32}; + +fn unsigned(nz: NonZero) { + let _ = nz.leading_zeros(); + //~^ needless_nonzero_get + let _ = nz.trailing_zeros(); + //~^ needless_nonzero_get + let _ = nz.is_power_of_two(); + //~^ needless_nonzero_get + let _ = nz.ilog2(); + //~^ needless_nonzero_get + let _ = nz.ilog10(); + //~^ needless_nonzero_get +} + +fn signed(nz: NonZero) { + let _ = nz.leading_zeros(); + //~^ needless_nonzero_get + let _ = nz.trailing_zeros(); + //~^ needless_nonzero_get + let _ = nz.is_positive(); + //~^ needless_nonzero_get + let _ = nz.is_negative(); + //~^ needless_nonzero_get +} + +fn unsigned_widths(a: NonZero, b: NonZero, c: NonZero, d: NonZero, e: NonZero) { + let _ = a.leading_zeros(); + //~^ needless_nonzero_get + let _ = b.trailing_zeros(); + //~^ needless_nonzero_get + let _ = c.ilog2(); + //~^ needless_nonzero_get + let _ = d.is_power_of_two(); + //~^ needless_nonzero_get + let _ = e.ilog10(); + //~^ needless_nonzero_get +} + +fn signed_widths(f: NonZero, g: NonZero, h: NonZero, i: NonZero, j: NonZero) { + let _ = f.is_negative(); + //~^ needless_nonzero_get + let _ = g.is_positive(); + //~^ needless_nonzero_get + let _ = h.leading_zeros(); + //~^ needless_nonzero_get + let _ = i.trailing_zeros(); + //~^ needless_nonzero_get + let _ = j.leading_zeros(); + //~^ needless_nonzero_get +} + +fn aliases_and_receivers(a: NonZeroU32, b: NonZeroI32, r: &NonZero) { + let _ = a.ilog2(); + //~^ needless_nonzero_get + let _ = b.is_positive(); + //~^ needless_nonzero_get + let _ = r.leading_zeros(); + //~^ needless_nonzero_get + + // more complex receiver expressions + let _ = NonZero::new(5u32).unwrap().leading_zeros(); + //~^ needless_nonzero_get + let _ = (a).trailing_zeros(); + //~^ needless_nonzero_get + + // multi-line chain + let _ = a + //~^ needless_nonzero_get + .leading_zeros(); +} + +fn operators(mut value: u32, other: u32, nz: NonZero) { + let _ = other / nz; + //~^ needless_nonzero_get + let _ = other % nz; + //~^ needless_nonzero_get + value /= nz; + //~^ needless_nonzero_get + value %= nz; + //~^ needless_nonzero_get +} + +// The `NonZero` operator implementations carry `#[rustc_const_unstable(feature = "const_ops")]`, +// so they are not usable in a `const` context even though `Div`/`Rem` themselves are stable. +const fn const_operators(mut value: u32, nz: NonZero) -> u32 { + value /= nz.get(); + value / nz.get() +} + +// `NonZero::leading_zeros` is const-stable since 1.53.0, so the `get` can go even in a `const fn`. +const fn const_methods(nz: NonZero) -> u32 { + nz.leading_zeros() + //~^ needless_nonzero_get +} + +fn no_lint(nz: NonZero, signed: NonZero, plain: u32) { + // `NonZero`'s version returns `NonZero` rather than `u32`, so the `get` would only move + // rather than disappear + let _ = nz.get().bit_width(); + let _ = nz.get().count_ones(); + let _ = nz.get().isqrt(); + let _ = nz.get().checked_add(1); + let _ = nz.get().saturating_mul(2); + let _ = signed.get().abs(); + let _ = signed.get().cast_unsigned(); + let _ = signed.get().unsigned_abs(); + let _ = signed.get().wrapping_neg(); + let _ = signed.get().overflowing_neg(); + + // `highest_one`/`lowest_one` return `Option` on integers but `u32` on `NonZero` + let _ = nz.get().highest_one(); + let _ = nz.get().lowest_one(); + + // no `NonZero` equivalent at all + let _ = nz.get().to_string(); + let _ = nz.get().count_zeros(); + + // `i32::ilog2` exists but `NonZero::ilog2` does not, so the impls must not cross over + let _ = signed.get().ilog2(); + + // The `NonZero` division and remainder implementations are unsigned-only. + let signed_value = signed.get(); + let _ = signed_value / signed.get(); + let _ = signed_value % signed.get(); + + // Primitive operators forward references, but the `NonZero` operators do not. + let value_ref = &plain; + let _ = value_ref / nz.get(); + let _ = value_ref % nz.get(); + + let nz_ref = &nz; + let _ = plain / nz_ref.get(); + let _ = plain % nz_ref.get(); + + // not a `NonZero` receiver + let _ = plain.leading_zeros(); + + // `get` is not immediately followed by the method + let x = nz.get(); + let _ = x.leading_zeros(); + + // takes arguments + let _ = nz.get().rotate_left(2); + + // a shadowing trait method must not be rewritten + let _ = nz.get().shadowed(); +} + +trait Shadowed { + fn shadowed(self) -> u32; +} + +impl Shadowed for u32 { + fn shadowed(self) -> u32 { + self + } +} + +impl Shadowed for NonZero { + fn shadowed(self) -> u32 { + 0 + } +} + +// `NonZero::leading_zeros` was stabilized in 1.53.0 +#[clippy::msrv = "1.52"] +fn below_msrv(nz: NonZero) { + let _ = nz.get().leading_zeros(); +} + +#[clippy::msrv = "1.53"] +fn meets_msrv(nz: NonZero) { + let _ = nz.leading_zeros(); + //~^ needless_nonzero_get +} + +// `NonZero::ilog2` was stabilized in 1.67.0, later than `leading_zeros` +#[clippy::msrv = "1.66"] +fn below_ilog2_msrv(nz: NonZero) { + let _ = nz.get().ilog2(); + let _ = nz.leading_zeros(); + //~^ needless_nonzero_get +} + +// `Div>` and `Rem>` were stabilized in 1.51.0 +#[clippy::msrv = "1.50"] +fn below_nonzero_div_msrv(value: u32, nz: NonZero) { + let _ = value / nz.get(); + let _ = value % nz.get(); +} + +#[clippy::msrv = "1.51"] +fn meets_nonzero_div_msrv(value: u32, nz: NonZero) { + let _ = value / nz; + //~^ needless_nonzero_get + let _ = value % nz; + //~^ needless_nonzero_get +} + +// `DivAssign>` and `RemAssign>` were stabilized in 1.79.0 +#[clippy::msrv = "1.78"] +fn below_nonzero_div_assign_msrv(mut value: u32, nz: NonZero) { + value /= nz.get(); + value %= nz.get(); +} + +#[clippy::msrv = "1.79"] +fn meets_nonzero_div_assign_msrv(mut value: u32, nz: NonZero) { + value /= nz; + //~^ needless_nonzero_get + value %= nz; + //~^ needless_nonzero_get +} + +// The whole expression is written in the macro, so the suggestion would point at code the caller +// cannot edit. +macro_rules! leading_zeros_of_five { + () => {{ + let nz = NonZero::new(5u32).unwrap(); + nz.get().leading_zeros() + }}; +} + +// Only the receiver comes from the macro, so the removal span would start in the expansion and end +// at the call site. +macro_rules! five { + () => { + NonZero::new(5u32).unwrap() + }; +} + +// Only `.get()` comes from the macro: the receiver is a macro argument and keeps its call site +// span. +macro_rules! get_of { + ($nz:expr) => { + $nz.get() + }; +} + +fn from_macros(nz: NonZero) { + let _ = leading_zeros_of_five!(); + let _ = five!().get().leading_zeros(); + let _ = get_of!(nz).leading_zeros(); + let _ = with_span!(span nz.get().leading_zeros()); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_nonzero_get.rs b/src/tools/clippy/tests/ui/needless_nonzero_get.rs new file mode 100644 index 0000000000000..4c7108af04dda --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_nonzero_get.rs @@ -0,0 +1,258 @@ +//@aux-build:proc_macros.rs + +#![warn(clippy::needless_nonzero_get)] +// the `msrv` functions below deliberately use items newer than their MSRV +#![allow(clippy::incompatible_msrv)] + +extern crate proc_macros; + +use proc_macros::with_span; +use std::num::{NonZero, NonZeroI32, NonZeroU32}; + +fn unsigned(nz: NonZero) { + let _ = nz.get().leading_zeros(); + //~^ needless_nonzero_get + let _ = nz.get().trailing_zeros(); + //~^ needless_nonzero_get + let _ = nz.get().is_power_of_two(); + //~^ needless_nonzero_get + let _ = nz.get().ilog2(); + //~^ needless_nonzero_get + let _ = nz.get().ilog10(); + //~^ needless_nonzero_get +} + +fn signed(nz: NonZero) { + let _ = nz.get().leading_zeros(); + //~^ needless_nonzero_get + let _ = nz.get().trailing_zeros(); + //~^ needless_nonzero_get + let _ = nz.get().is_positive(); + //~^ needless_nonzero_get + let _ = nz.get().is_negative(); + //~^ needless_nonzero_get +} + +fn unsigned_widths(a: NonZero, b: NonZero, c: NonZero, d: NonZero, e: NonZero) { + let _ = a.get().leading_zeros(); + //~^ needless_nonzero_get + let _ = b.get().trailing_zeros(); + //~^ needless_nonzero_get + let _ = c.get().ilog2(); + //~^ needless_nonzero_get + let _ = d.get().is_power_of_two(); + //~^ needless_nonzero_get + let _ = e.get().ilog10(); + //~^ needless_nonzero_get +} + +fn signed_widths(f: NonZero, g: NonZero, h: NonZero, i: NonZero, j: NonZero) { + let _ = f.get().is_negative(); + //~^ needless_nonzero_get + let _ = g.get().is_positive(); + //~^ needless_nonzero_get + let _ = h.get().leading_zeros(); + //~^ needless_nonzero_get + let _ = i.get().trailing_zeros(); + //~^ needless_nonzero_get + let _ = j.get().leading_zeros(); + //~^ needless_nonzero_get +} + +fn aliases_and_receivers(a: NonZeroU32, b: NonZeroI32, r: &NonZero) { + let _ = a.get().ilog2(); + //~^ needless_nonzero_get + let _ = b.get().is_positive(); + //~^ needless_nonzero_get + let _ = r.get().leading_zeros(); + //~^ needless_nonzero_get + + // more complex receiver expressions + let _ = NonZero::new(5u32).unwrap().get().leading_zeros(); + //~^ needless_nonzero_get + let _ = (a).get().trailing_zeros(); + //~^ needless_nonzero_get + + // multi-line chain + let _ = a + .get() + //~^ needless_nonzero_get + .leading_zeros(); +} + +fn operators(mut value: u32, other: u32, nz: NonZero) { + let _ = other / nz.get(); + //~^ needless_nonzero_get + let _ = other % nz.get(); + //~^ needless_nonzero_get + value /= nz.get(); + //~^ needless_nonzero_get + value %= nz.get(); + //~^ needless_nonzero_get +} + +// The `NonZero` operator implementations carry `#[rustc_const_unstable(feature = "const_ops")]`, +// so they are not usable in a `const` context even though `Div`/`Rem` themselves are stable. +const fn const_operators(mut value: u32, nz: NonZero) -> u32 { + value /= nz.get(); + value / nz.get() +} + +// `NonZero::leading_zeros` is const-stable since 1.53.0, so the `get` can go even in a `const fn`. +const fn const_methods(nz: NonZero) -> u32 { + nz.get().leading_zeros() + //~^ needless_nonzero_get +} + +fn no_lint(nz: NonZero, signed: NonZero, plain: u32) { + // `NonZero`'s version returns `NonZero` rather than `u32`, so the `get` would only move + // rather than disappear + let _ = nz.get().bit_width(); + let _ = nz.get().count_ones(); + let _ = nz.get().isqrt(); + let _ = nz.get().checked_add(1); + let _ = nz.get().saturating_mul(2); + let _ = signed.get().abs(); + let _ = signed.get().cast_unsigned(); + let _ = signed.get().unsigned_abs(); + let _ = signed.get().wrapping_neg(); + let _ = signed.get().overflowing_neg(); + + // `highest_one`/`lowest_one` return `Option` on integers but `u32` on `NonZero` + let _ = nz.get().highest_one(); + let _ = nz.get().lowest_one(); + + // no `NonZero` equivalent at all + let _ = nz.get().to_string(); + let _ = nz.get().count_zeros(); + + // `i32::ilog2` exists but `NonZero::ilog2` does not, so the impls must not cross over + let _ = signed.get().ilog2(); + + // The `NonZero` division and remainder implementations are unsigned-only. + let signed_value = signed.get(); + let _ = signed_value / signed.get(); + let _ = signed_value % signed.get(); + + // Primitive operators forward references, but the `NonZero` operators do not. + let value_ref = &plain; + let _ = value_ref / nz.get(); + let _ = value_ref % nz.get(); + + let nz_ref = &nz; + let _ = plain / nz_ref.get(); + let _ = plain % nz_ref.get(); + + // not a `NonZero` receiver + let _ = plain.leading_zeros(); + + // `get` is not immediately followed by the method + let x = nz.get(); + let _ = x.leading_zeros(); + + // takes arguments + let _ = nz.get().rotate_left(2); + + // a shadowing trait method must not be rewritten + let _ = nz.get().shadowed(); +} + +trait Shadowed { + fn shadowed(self) -> u32; +} + +impl Shadowed for u32 { + fn shadowed(self) -> u32 { + self + } +} + +impl Shadowed for NonZero { + fn shadowed(self) -> u32 { + 0 + } +} + +// `NonZero::leading_zeros` was stabilized in 1.53.0 +#[clippy::msrv = "1.52"] +fn below_msrv(nz: NonZero) { + let _ = nz.get().leading_zeros(); +} + +#[clippy::msrv = "1.53"] +fn meets_msrv(nz: NonZero) { + let _ = nz.get().leading_zeros(); + //~^ needless_nonzero_get +} + +// `NonZero::ilog2` was stabilized in 1.67.0, later than `leading_zeros` +#[clippy::msrv = "1.66"] +fn below_ilog2_msrv(nz: NonZero) { + let _ = nz.get().ilog2(); + let _ = nz.get().leading_zeros(); + //~^ needless_nonzero_get +} + +// `Div>` and `Rem>` were stabilized in 1.51.0 +#[clippy::msrv = "1.50"] +fn below_nonzero_div_msrv(value: u32, nz: NonZero) { + let _ = value / nz.get(); + let _ = value % nz.get(); +} + +#[clippy::msrv = "1.51"] +fn meets_nonzero_div_msrv(value: u32, nz: NonZero) { + let _ = value / nz.get(); + //~^ needless_nonzero_get + let _ = value % nz.get(); + //~^ needless_nonzero_get +} + +// `DivAssign>` and `RemAssign>` were stabilized in 1.79.0 +#[clippy::msrv = "1.78"] +fn below_nonzero_div_assign_msrv(mut value: u32, nz: NonZero) { + value /= nz.get(); + value %= nz.get(); +} + +#[clippy::msrv = "1.79"] +fn meets_nonzero_div_assign_msrv(mut value: u32, nz: NonZero) { + value /= nz.get(); + //~^ needless_nonzero_get + value %= nz.get(); + //~^ needless_nonzero_get +} + +// The whole expression is written in the macro, so the suggestion would point at code the caller +// cannot edit. +macro_rules! leading_zeros_of_five { + () => {{ + let nz = NonZero::new(5u32).unwrap(); + nz.get().leading_zeros() + }}; +} + +// Only the receiver comes from the macro, so the removal span would start in the expansion and end +// at the call site. +macro_rules! five { + () => { + NonZero::new(5u32).unwrap() + }; +} + +// Only `.get()` comes from the macro: the receiver is a macro argument and keeps its call site +// span. +macro_rules! get_of { + ($nz:expr) => { + $nz.get() + }; +} + +fn from_macros(nz: NonZero) { + let _ = leading_zeros_of_five!(); + let _ = five!().get().leading_zeros(); + let _ = get_of!(nz).leading_zeros(); + let _ = with_span!(span nz.get().leading_zeros()); +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_nonzero_get.stderr b/src/tools/clippy/tests/ui/needless_nonzero_get.stderr new file mode 100644 index 0000000000000..1b7ea10e09543 --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_nonzero_get.stderr @@ -0,0 +1,437 @@ +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:13:16 + | +LL | let _ = nz.get().leading_zeros(); + | ^^^^^ + | + = note: `-D clippy::needless-nonzero-get` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_nonzero_get)]` +help: remove this + | +LL - let _ = nz.get().leading_zeros(); +LL + let _ = nz.leading_zeros(); + | + +error: unnecessary `get` before `trailing_zeros` + --> tests/ui/needless_nonzero_get.rs:15:16 + | +LL | let _ = nz.get().trailing_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().trailing_zeros(); +LL + let _ = nz.trailing_zeros(); + | + +error: unnecessary `get` before `is_power_of_two` + --> tests/ui/needless_nonzero_get.rs:17:16 + | +LL | let _ = nz.get().is_power_of_two(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().is_power_of_two(); +LL + let _ = nz.is_power_of_two(); + | + +error: unnecessary `get` before `ilog2` + --> tests/ui/needless_nonzero_get.rs:19:16 + | +LL | let _ = nz.get().ilog2(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().ilog2(); +LL + let _ = nz.ilog2(); + | + +error: unnecessary `get` before `ilog10` + --> tests/ui/needless_nonzero_get.rs:21:16 + | +LL | let _ = nz.get().ilog10(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().ilog10(); +LL + let _ = nz.ilog10(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:26:16 + | +LL | let _ = nz.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().leading_zeros(); +LL + let _ = nz.leading_zeros(); + | + +error: unnecessary `get` before `trailing_zeros` + --> tests/ui/needless_nonzero_get.rs:28:16 + | +LL | let _ = nz.get().trailing_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().trailing_zeros(); +LL + let _ = nz.trailing_zeros(); + | + +error: unnecessary `get` before `is_positive` + --> tests/ui/needless_nonzero_get.rs:30:16 + | +LL | let _ = nz.get().is_positive(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().is_positive(); +LL + let _ = nz.is_positive(); + | + +error: unnecessary `get` before `is_negative` + --> tests/ui/needless_nonzero_get.rs:32:16 + | +LL | let _ = nz.get().is_negative(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().is_negative(); +LL + let _ = nz.is_negative(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:37:15 + | +LL | let _ = a.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = a.get().leading_zeros(); +LL + let _ = a.leading_zeros(); + | + +error: unnecessary `get` before `trailing_zeros` + --> tests/ui/needless_nonzero_get.rs:39:15 + | +LL | let _ = b.get().trailing_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = b.get().trailing_zeros(); +LL + let _ = b.trailing_zeros(); + | + +error: unnecessary `get` before `ilog2` + --> tests/ui/needless_nonzero_get.rs:41:15 + | +LL | let _ = c.get().ilog2(); + | ^^^^^ + | +help: remove this + | +LL - let _ = c.get().ilog2(); +LL + let _ = c.ilog2(); + | + +error: unnecessary `get` before `is_power_of_two` + --> tests/ui/needless_nonzero_get.rs:43:15 + | +LL | let _ = d.get().is_power_of_two(); + | ^^^^^ + | +help: remove this + | +LL - let _ = d.get().is_power_of_two(); +LL + let _ = d.is_power_of_two(); + | + +error: unnecessary `get` before `ilog10` + --> tests/ui/needless_nonzero_get.rs:45:15 + | +LL | let _ = e.get().ilog10(); + | ^^^^^ + | +help: remove this + | +LL - let _ = e.get().ilog10(); +LL + let _ = e.ilog10(); + | + +error: unnecessary `get` before `is_negative` + --> tests/ui/needless_nonzero_get.rs:50:15 + | +LL | let _ = f.get().is_negative(); + | ^^^^^ + | +help: remove this + | +LL - let _ = f.get().is_negative(); +LL + let _ = f.is_negative(); + | + +error: unnecessary `get` before `is_positive` + --> tests/ui/needless_nonzero_get.rs:52:15 + | +LL | let _ = g.get().is_positive(); + | ^^^^^ + | +help: remove this + | +LL - let _ = g.get().is_positive(); +LL + let _ = g.is_positive(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:54:15 + | +LL | let _ = h.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = h.get().leading_zeros(); +LL + let _ = h.leading_zeros(); + | + +error: unnecessary `get` before `trailing_zeros` + --> tests/ui/needless_nonzero_get.rs:56:15 + | +LL | let _ = i.get().trailing_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = i.get().trailing_zeros(); +LL + let _ = i.trailing_zeros(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:58:15 + | +LL | let _ = j.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = j.get().leading_zeros(); +LL + let _ = j.leading_zeros(); + | + +error: unnecessary `get` before `ilog2` + --> tests/ui/needless_nonzero_get.rs:63:15 + | +LL | let _ = a.get().ilog2(); + | ^^^^^ + | +help: remove this + | +LL - let _ = a.get().ilog2(); +LL + let _ = a.ilog2(); + | + +error: unnecessary `get` before `is_positive` + --> tests/ui/needless_nonzero_get.rs:65:15 + | +LL | let _ = b.get().is_positive(); + | ^^^^^ + | +help: remove this + | +LL - let _ = b.get().is_positive(); +LL + let _ = b.is_positive(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:67:15 + | +LL | let _ = r.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = r.get().leading_zeros(); +LL + let _ = r.leading_zeros(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:71:41 + | +LL | let _ = NonZero::new(5u32).unwrap().get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = NonZero::new(5u32).unwrap().get().leading_zeros(); +LL + let _ = NonZero::new(5u32).unwrap().leading_zeros(); + | + +error: unnecessary `get` before `trailing_zeros` + --> tests/ui/needless_nonzero_get.rs:73:17 + | +LL | let _ = (a).get().trailing_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = (a).get().trailing_zeros(); +LL + let _ = (a).trailing_zeros(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:78:10 + | +LL | .get() + | ^^^^^ + | +help: remove this + | +LL - let _ = a +LL - .get() +LL + let _ = a + | + +error: unnecessary `get` before `/` + --> tests/ui/needless_nonzero_get.rs:84:24 + | +LL | let _ = other / nz.get(); + | ^^^^^ + | +help: remove this + | +LL - let _ = other / nz.get(); +LL + let _ = other / nz; + | + +error: unnecessary `get` before `%` + --> tests/ui/needless_nonzero_get.rs:86:24 + | +LL | let _ = other % nz.get(); + | ^^^^^ + | +help: remove this + | +LL - let _ = other % nz.get(); +LL + let _ = other % nz; + | + +error: unnecessary `get` before `/=` + --> tests/ui/needless_nonzero_get.rs:88:17 + | +LL | value /= nz.get(); + | ^^^^^ + | +help: remove this + | +LL - value /= nz.get(); +LL + value /= nz; + | + +error: unnecessary `get` before `%=` + --> tests/ui/needless_nonzero_get.rs:90:17 + | +LL | value %= nz.get(); + | ^^^^^ + | +help: remove this + | +LL - value %= nz.get(); +LL + value %= nz; + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:103:8 + | +LL | nz.get().leading_zeros() + | ^^^^^ + | +help: remove this + | +LL - nz.get().leading_zeros() +LL + nz.leading_zeros() + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:184:16 + | +LL | let _ = nz.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().leading_zeros(); +LL + let _ = nz.leading_zeros(); + | + +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get.rs:192:16 + | +LL | let _ = nz.get().leading_zeros(); + | ^^^^^ + | +help: remove this + | +LL - let _ = nz.get().leading_zeros(); +LL + let _ = nz.leading_zeros(); + | + +error: unnecessary `get` before `/` + --> tests/ui/needless_nonzero_get.rs:205:24 + | +LL | let _ = value / nz.get(); + | ^^^^^ + | +help: remove this + | +LL - let _ = value / nz.get(); +LL + let _ = value / nz; + | + +error: unnecessary `get` before `%` + --> tests/ui/needless_nonzero_get.rs:207:24 + | +LL | let _ = value % nz.get(); + | ^^^^^ + | +help: remove this + | +LL - let _ = value % nz.get(); +LL + let _ = value % nz; + | + +error: unnecessary `get` before `/=` + --> tests/ui/needless_nonzero_get.rs:220:17 + | +LL | value /= nz.get(); + | ^^^^^ + | +help: remove this + | +LL - value /= nz.get(); +LL + value /= nz; + | + +error: unnecessary `get` before `%=` + --> tests/ui/needless_nonzero_get.rs:222:17 + | +LL | value %= nz.get(); + | ^^^^^ + | +help: remove this + | +LL - value %= nz.get(); +LL + value %= nz; + | + +error: aborting due to 36 previous errors + diff --git a/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.rs b/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.rs new file mode 100644 index 0000000000000..211cc57ef177e --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.rs @@ -0,0 +1,26 @@ +//@no-rustfix: the suggestion would remove the comment before `.get()` + +#![warn(clippy::needless_nonzero_get)] + +use std::num::NonZero; + +fn main() { + let nz = NonZero::new(1u32).unwrap(); + let mut value = 10u32; + + // This comment must not be removed by an automatic fix. + let _ = nz /* keep this comment */ + .get() + //~^ needless_nonzero_get + .leading_zeros(); + + // The operator suggestions share the same removal span, so they must preserve comments too. + let _ = value + / nz /* keep this comment */ + .get(); + //~^ needless_nonzero_get + + value %= nz /* keep this comment */ + .get(); + //~^ needless_nonzero_get +} diff --git a/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.stderr b/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.stderr new file mode 100644 index 0000000000000..100dce7181a3b --- /dev/null +++ b/src/tools/clippy/tests/ui/needless_nonzero_get_unfixable.stderr @@ -0,0 +1,43 @@ +error: unnecessary `get` before `leading_zeros` + --> tests/ui/needless_nonzero_get_unfixable.rs:13:10 + | +LL | .get() + | ^^^^^ + | + = note: `-D clippy::needless-nonzero-get` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_nonzero_get)]` +help: remove this + | +LL - let _ = nz /* keep this comment */ +LL - .get() +LL + let _ = nz + | + +error: unnecessary `get` before `/` + --> tests/ui/needless_nonzero_get_unfixable.rs:20:14 + | +LL | .get(); + | ^^^^^ + | +help: remove this + | +LL - / nz /* keep this comment */ +LL - .get(); +LL + / nz; + | + +error: unnecessary `get` before `%=` + --> tests/ui/needless_nonzero_get_unfixable.rs:24:10 + | +LL | .get(); + | ^^^^^ + | +help: remove this + | +LL - value %= nz /* keep this comment */ +LL - .get(); +LL + value %= nz; + | + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/needless_range_loop.rs b/src/tools/clippy/tests/ui/needless_range_loop.rs index dcb7026266048..7ad61ce90c721 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop.rs +++ b/src/tools/clippy/tests/ui/needless_range_loop.rs @@ -237,3 +237,43 @@ fn issue_15068() { let _ = a[0][i]; } } + +fn issue16631() { + let mut matrix: Vec> = Vec::new(); + for i in 0..=2 { + //~^ needless_range_loop + matrix[i][i] = true; + } + + let values = [[0; 4]; 4]; + let col = 2; + for i in 0..4 { + //~^ needless_range_loop + let _ = values[i][col]; + } + + let mut colors = [[0; 3]; 4]; + for i in 0..3 { + colors[2][i] = ((u16::from(colors[0][i]) * 2 + u16::from(colors[1][i]) + 1) / 3) as u8; + colors[3][i] = ((u16::from(colors[0][i]) + u16::from(colors[1][i]) * 2 + 1) / 3) as u8; + } + + let mut colors = [[0; 3]; 4]; + let i = 0; + for j in 0..3 { + colors[i][j] = colors[0][j]; + } + + let mut colors = [[0; 3]; 4]; + for j in 0..3 { + //~^ needless_range_loop + let _ = colors[0][j]; + } + + struct Wrapper(T); + let mut wrapper = Wrapper([0; 3]); + for i in 0..3 { + //~^ needless_range_loop + let _ = wrapper.0[i]; + } +} diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr index ab9693bb46d6b..755e9b8657b3a 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop.stderr +++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr @@ -4,6 +4,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:14:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ = note: `-D clippy::needless-range-loop` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator @@ -18,6 +23,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:25:17 + | +LL | let _ = vec[i]; + | ^^^^^^ help: consider using an iterator | LL - for i in 0..vec.len() { @@ -30,6 +40,11 @@ error: the loop variable `j` is only used to index `STATIC` LL | for j in 0..4 { | ^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:32:26 + | +LL | println!("{:?}", STATIC[j]); + | ^^^^^^^^^ help: consider using an iterator | LL - for j in 0..4 { @@ -42,6 +57,11 @@ error: the loop variable `j` is only used to index `CONST` LL | for j in 0..4 { | ^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:38:26 + | +LL | println!("{:?}", CONST[j]); + | ^^^^^^^^ help: consider using an iterator | LL - for j in 0..4 { @@ -54,7 +74,12 @@ error: the loop variable `i` is used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator and enumerate() +note: for this index operation + --> tests/ui/needless_range_loop.rs:44:27 + | +LL | println!("{} {}", vec[i], i); + | ^^^^^^ +help: consider using an iterator and `.enumerate()` | LL - for i in 0..vec.len() { LL + for (i, ) in vec.iter().enumerate() { @@ -66,6 +91,11 @@ error: the loop variable `i` is only used to index `vec2` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:54:24 + | +LL | println!("{}", vec2[i]); + | ^^^^^^^ help: consider using an iterator | LL - for i in 0..vec.len() { @@ -78,6 +108,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:60:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 5..vec.len() { @@ -90,6 +125,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:66:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 0..MAX_LEN { @@ -102,6 +142,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 0..=MAX_LEN { | ^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:72:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 0..=MAX_LEN { @@ -114,6 +159,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 5..10 { | ^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:78:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 5..10 { @@ -126,6 +176,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in 5..=10 { | ^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:84:24 + | +LL | println!("{}", vec[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 5..=10 { @@ -138,7 +193,12 @@ error: the loop variable `i` is used to index `vec` LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator and enumerate() +note: for this index operation + --> tests/ui/needless_range_loop.rs:90:27 + | +LL | println!("{} {}", vec[i], i); + | ^^^^^^ +help: consider using an iterator and `.enumerate()` | LL - for i in 5..vec.len() { LL + for (i, ) in vec.iter().enumerate().skip(5) { @@ -150,7 +210,12 @@ error: the loop variable `i` is used to index `vec` LL | for i in 5..10 { | ^^^^^ | -help: consider using an iterator and enumerate() +note: for this index operation + --> tests/ui/needless_range_loop.rs:96:27 + | +LL | println!("{} {}", vec[i], i); + | ^^^^^^ +help: consider using an iterator and `.enumerate()` | LL - for i in 5..10 { LL + for (i, ) in vec.iter().enumerate().take(10).skip(5) { @@ -162,7 +227,12 @@ error: the loop variable `i` is used to index `vec` LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ | -help: consider using an iterator and enumerate() +note: for this index operation + --> tests/ui/needless_range_loop.rs:103:9 + | +LL | vec[i] = Some(1).unwrap_or_else(|| panic!("error on {}", i)); + | ^^^^^^ +help: consider using an iterator and `.enumerate()` | LL - for i in 0..vec.len() { LL + for (i, ) in vec.iter_mut().enumerate() { @@ -174,23 +244,101 @@ error: the loop variable `i` is used to index `a` LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ | -help: consider using an iterator and enumerate() +note: for this index operation + --> tests/ui/needless_range_loop.rs:232:17 + | +LL | let _ = a[i][i]; + | ^^^^ +help: consider using an iterator and `.enumerate()` | LL - for i in 0..MAX_LEN { LL + for (i, ) in a.iter().enumerate().take(MAX_LEN) { | -error: the loop variable `i` is only used to index `a` +error: the loop variable `i` is only used to index `a[0]` --> tests/ui/needless_range_loop.rs:235:14 | LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop.rs:237:17 + | +LL | let _ = a[0][i]; + | ^^^^^^^ help: consider using an iterator | LL - for i in 0..MAX_LEN { -LL + for in a.iter().take(MAX_LEN) { +LL + for in a[0].iter().take(MAX_LEN) { + | + +error: the loop variable `i` is used to index `matrix` + --> tests/ui/needless_range_loop.rs:243:14 + | +LL | for i in 0..=2 { + | ^^^^^ + | +note: for this index operation + --> tests/ui/needless_range_loop.rs:245:9 + | +LL | matrix[i][i] = true; + | ^^^^^^^^^ +help: consider using an iterator and `.enumerate()` + | +LL - for i in 0..=2 { +LL + for (i, ) in matrix.iter_mut().enumerate().take(2 + 1) { + | + +error: the loop variable `i` is only used to index `values` + --> tests/ui/needless_range_loop.rs:250:14 + | +LL | for i in 0..4 { + | ^^^^ + | +note: for this index operation + --> tests/ui/needless_range_loop.rs:252:17 + | +LL | let _ = values[i][col]; + | ^^^^^^^^^ +help: consider using an iterator + | +LL - for i in 0..4 { +LL + for in &values { + | + +error: the loop variable `j` is only used to index `colors[0]` + --> tests/ui/needless_range_loop.rs:268:14 + | +LL | for j in 0..3 { + | ^^^^ + | +note: for this index operation + --> tests/ui/needless_range_loop.rs:270:17 + | +LL | let _ = colors[0][j]; + | ^^^^^^^^^^^^ +help: consider using an iterator + | +LL - for j in 0..3 { +LL + for in &colors[0] { + | + +error: the loop variable `i` is only used to index `wrapper.0` + --> tests/ui/needless_range_loop.rs:275:14 + | +LL | for i in 0..3 { + | ^^^^ + | +note: for this index operation + --> tests/ui/needless_range_loop.rs:277:17 + | +LL | let _ = wrapper.0[i]; + | ^^^^^^^^^^^^ +help: consider using an iterator + | +LL - for i in 0..3 { +LL + for in &wrapper.0 { | -error: aborting due to 16 previous errors +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/needless_range_loop2.stderr b/src/tools/clippy/tests/ui/needless_range_loop2.stderr index cb979b3f3c243..36d2f443ef526 100644 --- a/src/tools/clippy/tests/ui/needless_range_loop2.stderr +++ b/src/tools/clippy/tests/ui/needless_range_loop2.stderr @@ -4,6 +4,11 @@ error: the loop variable `i` is only used to index `ns` LL | for i in 3..10 { | ^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:14:24 + | +LL | println!("{}", ns[i]); + | ^^^^^ = note: `-D clippy::needless-range-loop` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator @@ -18,6 +23,11 @@ error: the loop variable `i` is only used to index `ms` LL | for i in 0..ms.len() { | ^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:37:9 + | +LL | ms[i] *= 2; + | ^^^^^ help: consider using an iterator | LL - for i in 0..ms.len() { @@ -30,6 +40,11 @@ error: the loop variable `i` is only used to index `ms` LL | for i in 0..ms.len() { | ^^^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:45:22 + | +LL | let x = &mut ms[i]; + | ^^^^^ help: consider using an iterator | LL - for i in 0..ms.len() { @@ -42,6 +57,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in x..x + 4 { | ^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:71:9 + | +LL | vec[i] += 1; + | ^^^^^^ help: consider using an iterator | LL - for i in x..x + 4 { @@ -54,6 +74,11 @@ error: the loop variable `i` is only used to index `vec` LL | for i in x..=x + 4 { | ^^^^^^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:80:9 + | +LL | vec[i] += 1; + | ^^^^^^ help: consider using an iterator | LL - for i in x..=x + 4 { @@ -66,6 +91,11 @@ error: the loop variable `i` is only used to index `arr` LL | for i in 0..3 { | ^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:88:24 + | +LL | println!("{}", arr[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 0..3 { @@ -78,6 +108,11 @@ error: the loop variable `i` is only used to index `arr` LL | for i in 0..2 { | ^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:94:24 + | +LL | println!("{}", arr[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 0..2 { @@ -90,6 +125,11 @@ error: the loop variable `i` is only used to index `arr` LL | for i in 1..3 { | ^^^^ | +note: for this index operation + --> tests/ui/needless_range_loop2.rs:100:24 + | +LL | println!("{}", arr[i]); + | ^^^^^^ help: consider using an iterator | LL - for i in 1..3 { diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.fixed b/src/tools/clippy/tests/ui/non_zero_suggestions.fixed index b714a6cf6ede7..75209018f1275 100644 --- a/src/tools/clippy/tests/ui/non_zero_suggestions.fixed +++ b/src/tools/clippy/tests/ui/non_zero_suggestions.fixed @@ -1,4 +1,6 @@ #![warn(clippy::non_zero_suggestions)] +#![allow(clippy::needless_nonzero_get)] + use std::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize}; fn main() { diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.rs b/src/tools/clippy/tests/ui/non_zero_suggestions.rs index 0e4cd3cc36528..6b24ffb60fc6a 100644 --- a/src/tools/clippy/tests/ui/non_zero_suggestions.rs +++ b/src/tools/clippy/tests/ui/non_zero_suggestions.rs @@ -1,4 +1,6 @@ #![warn(clippy::non_zero_suggestions)] +#![allow(clippy::needless_nonzero_get)] + use std::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize}; fn main() { diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.stderr b/src/tools/clippy/tests/ui/non_zero_suggestions.stderr index 4b5a8a3fc6ff7..8138a13044228 100644 --- a/src/tools/clippy/tests/ui/non_zero_suggestions.stderr +++ b/src/tools/clippy/tests/ui/non_zero_suggestions.stderr @@ -1,5 +1,5 @@ error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:9:18 + --> tests/ui/non_zero_suggestions.rs:11:18 | LL | let r1 = x / u64::from(y.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` @@ -8,31 +8,31 @@ LL | let r1 = x / u64::from(y.get()); = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:12:18 + --> tests/ui/non_zero_suggestions.rs:14:18 | LL | let r2 = x % u64::from(y.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU32::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:18:18 + --> tests/ui/non_zero_suggestions.rs:20:18 | LL | let r3 = a / u32::from(b.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU32::from(b)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:21:13 + --> tests/ui/non_zero_suggestions.rs:23:13 | LL | let x = u64::from(NonZeroU32::new(5).unwrap().get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:58:9 + --> tests/ui/non_zero_suggestions.rs:60:9 | LL | x / u64::from(y.get()) | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:68:22 + --> tests/ui/non_zero_suggestions.rs:70:22 | LL | self.value / u64::from(divisor.get()) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)` diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs index 85e74d74d7b9b..0ce41d3ac5dcb 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool.rs +++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs @@ -66,6 +66,7 @@ fn issue3847(a: u32, b: u32) -> bool { return false; } true + //~^^^^ needless_bool } fn issue4548() { diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr index 5197f105da448..dd8348c3cbf63 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr +++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr @@ -159,8 +159,20 @@ LL - let _ = a != b && !(a != b && c == d); LL + let _ = a != b && c != d; | +error: this `if` guard returns a bool literal and is followed by another + --> tests/ui/nonminimal_bool.rs:65:5 + | +LL | / if a < THRESHOLD && b >= THRESHOLD || a >= THRESHOLD && b < THRESHOLD { +LL | | return false; +LL | | } +LL | | true + | |________^ help: you can reduce it to: `!(a < THRESHOLD && b >= THRESHOLD || a >= THRESHOLD && b < THRESHOLD)` + | + = note: `-D clippy::needless-bool` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` + error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:89:8 + --> tests/ui/nonminimal_bool.rs:90:8 | LL | if matches!(true, true) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -172,37 +184,37 @@ LL + if matches!(true, true) { | error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:171:8 | LL | if !(12 == a) {} | ^^^^^^^^^^ help: try: `(12 != a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:172:8 + --> tests/ui/nonminimal_bool.rs:173:8 | LL | if !(a == 12) {} | ^^^^^^^^^^ help: try: `(a != 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:174:8 + --> tests/ui/nonminimal_bool.rs:175:8 | LL | if !(12 != a) {} | ^^^^^^^^^^ help: try: `(12 == a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:176:8 + --> tests/ui/nonminimal_bool.rs:177:8 | LL | if !(a != 12) {} | ^^^^^^^^^^ help: try: `(a == 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:181:8 + --> tests/ui/nonminimal_bool.rs:182:8 | LL | if !b == true {} | ^^^^^^^^^^ help: try: `b != true` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:181:8 + --> tests/ui/nonminimal_bool.rs:182:8 | LL | if !b == true {} | ^^^^^^^^^^ help: try: `!b` @@ -211,55 +223,55 @@ LL | if !b == true {} = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:184:8 + --> tests/ui/nonminimal_bool.rs:185:8 | LL | if !b != true {} | ^^^^^^^^^^ help: try: `b == true` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:184:8 + --> tests/ui/nonminimal_bool.rs:185:8 | LL | if !b != true {} | ^^^^^^^^^^ help: try: `b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:187:8 + --> tests/ui/nonminimal_bool.rs:188:8 | LL | if true == !b {} | ^^^^^^^^^^ help: try: `true != b` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:187:8 + --> tests/ui/nonminimal_bool.rs:188:8 | LL | if true == !b {} | ^^^^^^^^^^ help: try: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:190:8 + --> tests/ui/nonminimal_bool.rs:191:8 | LL | if true != !b {} | ^^^^^^^^^^ help: try: `true == b` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:190:8 + --> tests/ui/nonminimal_bool.rs:191:8 | LL | if true != !b {} | ^^^^^^^^^^ help: try: `b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:193:8 + --> tests/ui/nonminimal_bool.rs:194:8 | LL | if !b == !c {} | ^^^^^^^^ help: try: `b == c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:195:8 + --> tests/ui/nonminimal_bool.rs:196:8 | LL | if !b != !c {} | ^^^^^^^^ help: try: `b != c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:211:8 + --> tests/ui/nonminimal_bool.rs:212:8 | LL | if !(a < 2.0 && !b) { | ^^^^^^^^^^^^^^^^ @@ -271,7 +283,7 @@ LL + if a >= 2.0 || b { | error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:230:12 + --> tests/ui/nonminimal_bool.rs:231:12 | LL | if !(matches!(ty, TyKind::Ref(_, _, _)) && !is_mutable(&expr)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -283,16 +295,16 @@ LL + if !matches!(ty, TyKind::Ref(_, _, _)) || is_mutable(&expr) { | error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:250:8 + --> tests/ui/nonminimal_bool.rs:251:8 | LL | if !S != true {} | ^^^^^^^^^^ help: try: `S == true` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:250:8 + --> tests/ui/nonminimal_bool.rs:251:8 | LL | if !S != true {} | ^^^^^^^^^^ help: try: `!!S` -error: aborting due to 31 previous errors +error: aborting due to 32 previous errors diff --git a/src/tools/clippy/tests/ui/option_zip_none.fixed b/src/tools/clippy/tests/ui/option_zip_none.fixed new file mode 100644 index 0000000000000..0e002c90113aa --- /dev/null +++ b/src/tools/clippy/tests/ui/option_zip_none.fixed @@ -0,0 +1,78 @@ +#![warn(clippy::option_zip_none)] +#![allow(clippy::needless_borrow)] +mod edge_case { + trait MyZip { + fn zip(self, other: Option<()>) -> &'static str; + } + + impl MyZip for &Option { + fn zip(self, _other: Option<()>) -> &'static str { + "not Option::zip" + } + } + + pub fn test_custom_trait() { + let opt = Some(1); + let _ = (&opt).zip(None::<()>); + } + + enum MyOption { + Some(i32), + None, + } + + impl MyOption { + fn zip(self, _other: Option<()>) -> &'static str { + "not Option::zip" + } + } + + pub fn test_custom_enum() { + let opt = MyOption::Some(1); + let _ = opt.zip(None::<()>); + } +} + +fn main() { + let opt = Some(5); + + let _ = opt.map(|n| (n, None::<()>)); + //~^ option_zip_none + + let _ = opt.zip(Some(42)); + + let iter = vec![1, 2, 3].into_iter(); + let _ = iter.zip(std::iter::empty::()); + + let standard_opt = Some(1); + let _ = (&standard_opt).map(|n| (n, None::<()>)); + //~^ option_zip_none + + let _ = Some(1).map(|n| (None::, n)); + //~^ option_zip_none + + let _ = Some(1).map(|n| (n, None::<()>)); + //~^ option_zip_none + + macro_rules! macro_none { + () => { + None::<()> + }; + } + let opt = Some(1); + let _ = opt.map(|n| (n, macro_none!())); + //~^ option_zip_none + + macro_rules! macro_zip { + ($opt:expr) => { + $opt.zip(None::<()>) + }; + } + let _ = macro_zip!(Some(1)); + macro_rules! macro_zip_arg { + ($opt:expr, $arg:expr) => { + $opt.zip($arg) + }; + } + let _ = macro_zip_arg!(Some(1), None::<()>); +} diff --git a/src/tools/clippy/tests/ui/option_zip_none.rs b/src/tools/clippy/tests/ui/option_zip_none.rs new file mode 100644 index 0000000000000..0e2c9efcb6cb1 --- /dev/null +++ b/src/tools/clippy/tests/ui/option_zip_none.rs @@ -0,0 +1,78 @@ +#![warn(clippy::option_zip_none)] +#![allow(clippy::needless_borrow)] +mod edge_case { + trait MyZip { + fn zip(self, other: Option<()>) -> &'static str; + } + + impl MyZip for &Option { + fn zip(self, _other: Option<()>) -> &'static str { + "not Option::zip" + } + } + + pub fn test_custom_trait() { + let opt = Some(1); + let _ = (&opt).zip(None::<()>); + } + + enum MyOption { + Some(i32), + None, + } + + impl MyOption { + fn zip(self, _other: Option<()>) -> &'static str { + "not Option::zip" + } + } + + pub fn test_custom_enum() { + let opt = MyOption::Some(1); + let _ = opt.zip(None::<()>); + } +} + +fn main() { + let opt = Some(5); + + let _ = opt.zip(None::<()>); + //~^ option_zip_none + + let _ = opt.zip(Some(42)); + + let iter = vec![1, 2, 3].into_iter(); + let _ = iter.zip(std::iter::empty::()); + + let standard_opt = Some(1); + let _ = (&standard_opt).zip(None::<()>); + //~^ option_zip_none + + let _ = None::.zip(Some(1)); + //~^ option_zip_none + + let _ = Some(1).zip(None::<()>); + //~^ option_zip_none + + macro_rules! macro_none { + () => { + None::<()> + }; + } + let opt = Some(1); + let _ = opt.zip(macro_none!()); + //~^ option_zip_none + + macro_rules! macro_zip { + ($opt:expr) => { + $opt.zip(None::<()>) + }; + } + let _ = macro_zip!(Some(1)); + macro_rules! macro_zip_arg { + ($opt:expr, $arg:expr) => { + $opt.zip($arg) + }; + } + let _ = macro_zip_arg!(Some(1), None::<()>); +} diff --git a/src/tools/clippy/tests/ui/option_zip_none.stderr b/src/tools/clippy/tests/ui/option_zip_none.stderr new file mode 100644 index 0000000000000..0f5f53c6469f1 --- /dev/null +++ b/src/tools/clippy/tests/ui/option_zip_none.stderr @@ -0,0 +1,64 @@ +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none.rs:39:13 + | +LL | let _ = opt.zip(None::<()>); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::option-zip-none` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::option_zip_none)]` +help: if you meant to zip the contents of the `Option` with `None`, use `Option::map` + | +LL - let _ = opt.zip(None::<()>); +LL + let _ = opt.map(|n| (n, None::<()>)); + | + +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none.rs:48:13 + | +LL | let _ = (&standard_opt).zip(None::<()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if you meant to zip the contents of the `Option` with `None`, use `Option::map` + | +LL - let _ = (&standard_opt).zip(None::<()>); +LL + let _ = (&standard_opt).map(|n| (n, None::<()>)); + | + +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none.rs:51:13 + | +LL | let _ = None::.zip(Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if you meant to zip the contents of the `Option` with `None`, use `Option::map` + | +LL - let _ = None::.zip(Some(1)); +LL + let _ = Some(1).map(|n| (None::, n)); + | + +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none.rs:54:13 + | +LL | let _ = Some(1).zip(None::<()>); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if you meant to zip the contents of the `Option` with `None`, use `Option::map` + | +LL - let _ = Some(1).zip(None::<()>); +LL + let _ = Some(1).map(|n| (n, None::<()>)); + | + +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none.rs:63:13 + | +LL | let _ = opt.zip(macro_none!()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: if you meant to zip the contents of the `Option` with `None`, use `Option::map` + | +LL - let _ = opt.zip(macro_none!()); +LL + let _ = opt.map(|n| (n, macro_none!())); + | + +error: aborting due to 5 previous errors + diff --git a/src/tools/clippy/tests/ui/option_zip_none_unfixable.rs b/src/tools/clippy/tests/ui/option_zip_none_unfixable.rs new file mode 100644 index 0000000000000..e893f3b1ccf4a --- /dev/null +++ b/src/tools/clippy/tests/ui/option_zip_none_unfixable.rs @@ -0,0 +1,9 @@ +//@no-rustfix +#![warn(clippy::option_zip_none)] + +fn main() { + let _: Option<(i32, ())> = Option::zip(Some(1), None::<()>); + //~^ option_zip_none + let _: Option<((), i32)> = Option::zip(None::<()>, Some(1)); + //~^ option_zip_none +} diff --git a/src/tools/clippy/tests/ui/option_zip_none_unfixable.stderr b/src/tools/clippy/tests/ui/option_zip_none_unfixable.stderr new file mode 100644 index 0000000000000..64a4ed5138d93 --- /dev/null +++ b/src/tools/clippy/tests/ui/option_zip_none_unfixable.stderr @@ -0,0 +1,17 @@ +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none_unfixable.rs:5:32 + | +LL | let _: Option<(i32, ())> = Option::zip(Some(1), None::<()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::option-zip-none` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::option_zip_none)]` + +error: calling `.zip()` on an `Option` where one side is `None` always returns `None` + --> tests/ui/option_zip_none_unfixable.rs:7:32 + | +LL | let _: Option<((), i32)> = Option::zip(None::<()>, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed index bbb81fea529bd..a46d3bb92a335 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed @@ -160,3 +160,6 @@ mod issue12123 { async fn main() {} } } + +#[derive(Debug, Clone)] +struct DerivedStruct(i32); diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs index d962f2ef6c411..de68d6c168098 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs @@ -160,3 +160,6 @@ mod issue12123 { async fn main() {} } } + +#[derive(Debug, Clone)] +struct DerivedStruct(i32); diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.fixed new file mode 100644 index 0000000000000..2f93f608c5233 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.fixed @@ -0,0 +1,51 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::unnecessary_map_or)] + +#[macro_use] +extern crate proc_macros; + +const TRUE: bool = true; +const FALSE: bool = false; + +fn main() { + let result = Ok::(1); + + let _ = result.is_ok(); + //~^ unnecessary_map_or + let _ = result.is_err(); + //~^ unnecessary_map_or + let _ = result.is_ok(); + //~^ unnecessary_map_or + let _ = result.is_ok(); + //~^ unnecessary_map_or + + let _ = result.is_ok(); + //~^ unnecessary_map_or + let _ = result.is_err(); + //~^ unnecessary_map_or + let _ = result.is_ok(); + //~^ unnecessary_map_or + let _ = result.is_ok(); + //~^ unnecessary_map_or + + // Calls in a closure body may have side effects. The lint does not inspect the callee body. + let _ = result.map_or_else( + |_| { + std::hint::black_box(()); + false + }, + |_| true, + ); + let _ = result.map_or_else(|error| error > 0, |_| true); + let _ = result.map_or_else(|_| false, |value| value > 0); + + external! { + let _ = Ok::(1).map_or(false, |_| true); + let _ = Ok::(1).map_or_else(|_| false, |_| true); + } + + with_span! { + let _ = Ok::(1).map_or(false, |_| true); + let _ = Ok::(1).map_or_else(|_| false, |_| true); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.rs b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.rs new file mode 100644 index 0000000000000..3fe4181bdac4e --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.rs @@ -0,0 +1,51 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::unnecessary_map_or)] + +#[macro_use] +extern crate proc_macros; + +const TRUE: bool = true; +const FALSE: bool = false; + +fn main() { + let result = Ok::(1); + + let _ = result.map_or(false, |_| true); + //~^ unnecessary_map_or + let _ = result.map_or(true, |_| false); + //~^ unnecessary_map_or + let _ = result.map_or(false, |_: i32| true); + //~^ unnecessary_map_or + let _ = result.map_or(!true, |_| TRUE); + //~^ unnecessary_map_or + + let _ = result.map_or_else(|_| false, |_| true); + //~^ unnecessary_map_or + let _ = result.map_or_else(|_| true, |_| false); + //~^ unnecessary_map_or + let _ = result.map_or_else(|_: i32| false, |_: i32| true); + //~^ unnecessary_map_or + let _ = result.map_or_else(|_| FALSE, |_| !false); + //~^ unnecessary_map_or + + // Calls in a closure body may have side effects. The lint does not inspect the callee body. + let _ = result.map_or_else( + |_| { + std::hint::black_box(()); + false + }, + |_| true, + ); + let _ = result.map_or_else(|error| error > 0, |_| true); + let _ = result.map_or_else(|_| false, |value| value > 0); + + external! { + let _ = Ok::(1).map_or(false, |_| true); + let _ = Ok::(1).map_or_else(|_| false, |_| true); + } + + with_span! { + let _ = Ok::(1).map_or(false, |_| true); + let _ = Ok::(1).map_or_else(|_| false, |_| true); + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.stderr new file mode 100644 index 0000000000000..e0d6c9bde2a60 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool.stderr @@ -0,0 +1,69 @@ +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:13:20 + | +LL | let _ = result.map_or(false, |_| true); + | ^^^^^^----------------- + | | + | help: use `is_ok` instead: `is_ok()` + | + = note: `-D clippy::unnecessary-map-or` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:15:20 + | +LL | let _ = result.map_or(true, |_| false); + | ^^^^^^----------------- + | | + | help: use `is_err` instead: `is_err()` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:17:20 + | +LL | let _ = result.map_or(false, |_: i32| true); + | ^^^^^^---------------------- + | | + | help: use `is_ok` instead: `is_ok()` + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:19:20 + | +LL | let _ = result.map_or(!true, |_| TRUE); + | ^^^^^^----------------- + | | + | help: use `is_ok` instead: `is_ok()` + +error: this `map_or_else` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:22:20 + | +LL | let _ = result.map_or_else(|_| false, |_| true); + | ^^^^^^^^^^^--------------------- + | | + | help: use `is_ok` instead: `is_ok()` + +error: this `map_or_else` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:24:20 + | +LL | let _ = result.map_or_else(|_| true, |_| false); + | ^^^^^^^^^^^--------------------- + | | + | help: use `is_err` instead: `is_err()` + +error: this `map_or_else` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:26:20 + | +LL | let _ = result.map_or_else(|_: i32| false, |_: i32| true); + | ^^^^^^^^^^^------------------------------- + | | + | help: use `is_ok` instead: `is_ok()` + +error: this `map_or_else` can be simplified + --> tests/ui/unnecessary_map_or_result_bool.rs:28:20 + | +LL | let _ = result.map_or_else(|_| FALSE, |_| !false); + | ^^^^^^^^^^^----------------------- + | | + | help: use `is_ok` instead: `is_ok()` + +error: aborting due to 8 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.rs new file mode 100644 index 0000000000000..f17632129f6ca --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.rs @@ -0,0 +1,14 @@ +//@no-rustfix: `is_ok` and `is_err` can change significant drop order +#![warn(clippy::unnecessary_map_or)] + +fn main() { + let mutex = std::sync::Mutex::new(()); + + let result = Ok::<_, ()>(mutex.lock().unwrap()); + let _ = result.map_or(false, |_| true); + //~^ unnecessary_map_or + + let result = Err::<(), _>(mutex.lock().unwrap()); + let _ = result.map_or_else(|_| true, |_| false); + //~^ unnecessary_map_or +} diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.stderr new file mode 100644 index 0000000000000..f642845bcfa07 --- /dev/null +++ b/src/tools/clippy/tests/ui/unnecessary_map_or_result_bool_unfixable.stderr @@ -0,0 +1,26 @@ +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or_result_bool_unfixable.rs:8:20 + | +LL | let _ = result.map_or(false, |_| true); + | ^^^^^^----------------- + | | + | help: use `is_ok` instead: `is_ok()` + | + = note: this will change drop order of the result, as well as all temporaries + = note: add `#[allow(clippy::unnecessary_map_or)]` if this is important + = note: `-D clippy::unnecessary-map-or` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]` + +error: this `map_or_else` can be simplified + --> tests/ui/unnecessary_map_or_result_bool_unfixable.rs:12:20 + | +LL | let _ = result.map_or_else(|_| true, |_| false); + | ^^^^^^^^^^^--------------------- + | | + | help: use `is_err` instead: `is_err()` + | + = note: this will change drop order of the result, as well as all temporaries + = note: add `#[allow(clippy::unnecessary_map_or)]` if this is important + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.fixed b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.fixed index 830f868226678..016bc8b3d741d 100644 --- a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.fixed @@ -32,6 +32,10 @@ mod m { } } +type Variant = VariantKind; + +struct VariantKind; + fn main() { let s = S { a: 1, b: 2, c: 3 }; @@ -87,4 +91,14 @@ fn main() { let Sm { .. } = Sm::default(); let Sm { a: _, b: _, .. } = Sm::default(); + + let variant = Variant {}; + + let Variant { } = variant; + //~^ unnecessary_rest_pattern + + match variant { + Variant { } => {}, + //~^ unnecessary_rest_pattern + } } diff --git a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.rs b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.rs index 51ed4b1e18042..d8b3f9623603a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.rs +++ b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.rs @@ -32,6 +32,10 @@ mod m { } } +type Variant = VariantKind; + +struct VariantKind; + fn main() { let s = S { a: 1, b: 2, c: 3 }; @@ -87,4 +91,14 @@ fn main() { let Sm { .. } = Sm::default(); let Sm { a: _, b: _, .. } = Sm::default(); + + let variant = Variant {}; + + let Variant { .. } = variant; + //~^ unnecessary_rest_pattern + + match variant { + Variant { .. } => {}, + //~^ unnecessary_rest_pattern + } } diff --git a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.stderr b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.stderr index 2c8e66f9d1034..346d8895e4c2d 100644 --- a/src/tools/clippy/tests/ui/unnecessary_rest_pattern.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_rest_pattern.stderr @@ -1,5 +1,5 @@ error: unnecessary rest pattern (`..`) - --> tests/ui/unnecessary_rest_pattern.rs:38:9 + --> tests/ui/unnecessary_rest_pattern.rs:42:9 | LL | let S { a, b, c, .. } = s; | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let S { a, b, c, } = s; | error: unnecessary rest pattern (`..`) - --> tests/ui/unnecessary_rest_pattern.rs:45:9 + --> tests/ui/unnecessary_rest_pattern.rs:49:9 | LL | E::B { b1, b2, .. } => (), | ^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + E::B { b1, b2, } => (), | error: unnecessary rest pattern (`..`) - --> tests/ui/unnecessary_rest_pattern.rs:47:9 + --> tests/ui/unnecessary_rest_pattern.rs:51:9 | LL | E::C { .. } => (), | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + E::C { } => (), | error: unnecessary rest pattern (`..`) - --> tests/ui/unnecessary_rest_pattern.rs:80:9 + --> tests/ui/unnecessary_rest_pattern.rs:84:9 | LL | let LocalNonExhaustive { field: _, .. } = ne; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,5 +48,29 @@ LL - let LocalNonExhaustive { field: _, .. } = ne; LL + let LocalNonExhaustive { field: _, } = ne; | -error: aborting due to 4 previous errors +error: unnecessary rest pattern (`..`) + --> tests/ui/unnecessary_rest_pattern.rs:97:9 + | +LL | let Variant { .. } = variant; + | ^^^^^^^^^^^^^^ + | +help: consider removing the unnecessary rest pattern (`..`) + | +LL - let Variant { .. } = variant; +LL + let Variant { } = variant; + | + +error: unnecessary rest pattern (`..`) + --> tests/ui/unnecessary_rest_pattern.rs:101:9 + | +LL | Variant { .. } => {}, + | ^^^^^^^^^^^^^^ + | +help: consider removing the unnecessary rest pattern (`..`) + | +LL - Variant { .. } => {}, +LL + Variant { } => {}, + | + +error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed index f96088bd39a6d..a191cbb391a26 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed @@ -1,4 +1,4 @@ -#![feature(box_patterns)] +#![feature(deref_patterns)] #![warn(clippy::unnested_or_patterns)] #![allow(clippy::manual_range_patterns)] #![expect(irrefutable_let_patterns)] @@ -12,9 +12,9 @@ fn main() { // Should be ignored by this lint, as nesting requires more characters. if let &0 | &2 = &0 {} - if let box (0 | 2) = Box::new(0) {} + if let deref!(0 | 2) = Box::new(0) {} //~^ unnested_or_patterns - if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + if let deref!(0 | 1 | 2 | 3 | 4) = Box::new(0) {} //~^ unnested_or_patterns const C0: Option = Some(1); if let Some(1 | 2) | C0 = None {} diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs index 6f4ef615e9d16..8e1418f1b2168 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs @@ -1,4 +1,4 @@ -#![feature(box_patterns)] +#![feature(deref_patterns)] #![warn(clippy::unnested_or_patterns)] #![allow(clippy::manual_range_patterns)] #![expect(irrefutable_let_patterns)] @@ -12,9 +12,9 @@ fn main() { // Should be ignored by this lint, as nesting requires more characters. if let &0 | &2 = &0 {} - if let box 0 | box 2 = Box::new(0) {} + if let deref!(0) | deref!(2) = Box::new(0) {} //~^ unnested_or_patterns - if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} + if let deref!(0 | 1) | deref!(2 | 3) | deref!(4) = Box::new(0) {} //~^ unnested_or_patterns const C0: Option = Some(1); if let Some(1) | C0 | Some(2) = None {} diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr index 7298eabaa03e6..2e2ce28a6a225 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr @@ -1,27 +1,27 @@ error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:15:12 | -LL | if let box 0 | box 2 = Box::new(0) {} - | ^^^^^^^^^^^^^ +LL | if let deref!(0) | deref!(2) = Box::new(0) {} + | ^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::unnested-or-patterns` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]` help: nest the patterns | -LL - if let box 0 | box 2 = Box::new(0) {} -LL + if let box (0 | 2) = Box::new(0) {} +LL - if let deref!(0) | deref!(2) = Box::new(0) {} +LL + if let deref!(0 | 2) = Box::new(0) {} | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:17:12 | -LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | if let deref!(0 | 1) | deref!(2 | 3) | deref!(4) = Box::new(0) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: nest the patterns | -LL - if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} -LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} +LL - if let deref!(0 | 1) | deref!(2 | 3) | deref!(4) = Box::new(0) {} +LL + if let deref!(0 | 1 | 2 | 3 | 4) = Box::new(0) {} | error: unnested or-patterns diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed index d9625e78c246d..0e75a66690e93 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed @@ -1,4 +1,4 @@ -#![feature(box_patterns)] +#![feature(deref_patterns)] #![warn(clippy::unnested_or_patterns)] #![allow(clippy::manual_range_patterns)] @@ -15,8 +15,8 @@ fn main() { //~^ unnested_or_patterns if let 0 | 1 | 2 = 0 {} //~^ unnested_or_patterns - if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + if let deref!(0 | 1 | 2 | 3 | 4) = Box::new(0) {} //~^ unnested_or_patterns - if let box (box (0 | 2 | 4)) = Box::new(Box::new(0)) {} + if let deref!(deref!(0 | 2 | 4)) = Box::new(Box::new(0)) {} //~^ unnested_or_patterns } diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs index d5215966fcb13..353060f1bf26d 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs @@ -1,4 +1,4 @@ -#![feature(box_patterns)] +#![feature(deref_patterns)] #![warn(clippy::unnested_or_patterns)] #![allow(clippy::manual_range_patterns)] @@ -15,8 +15,8 @@ fn main() { //~^ unnested_or_patterns if let 0 | (1 | 2) = 0 {} //~^ unnested_or_patterns - if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} + if let deref!(0 | 1) | (deref!(2) | deref!(3 | 4)) = Box::new(0) {} //~^ unnested_or_patterns - if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} + if let deref!(deref!(0)) | deref!(deref!(2) | deref!(4)) = Box::new(Box::new(0)) {} //~^ unnested_or_patterns } diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr index 776589e294ba5..e1cd2b36b11e1 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr @@ -75,25 +75,25 @@ LL + if let 0 | 1 | 2 = 0 {} error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:18:12 | -LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | if let deref!(0 | 1) | (deref!(2) | deref!(3 | 4)) = Box::new(0) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: nest the patterns | -LL - if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} -LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} +LL - if let deref!(0 | 1) | (deref!(2) | deref!(3 | 4)) = Box::new(0) {} +LL + if let deref!(0 | 1 | 2 | 3 | 4) = Box::new(0) {} | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:20:12 | -LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | if let deref!(deref!(0)) | deref!(deref!(2) | deref!(4)) = Box::new(Box::new(0)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: nest the patterns | -LL - if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} -LL + if let box (box (0 | 2 | 4)) = Box::new(Box::new(0)) {} +LL - if let deref!(deref!(0)) | deref!(deref!(2) | deref!(4)) = Box::new(Box::new(0)) {} +LL + if let deref!(deref!(0 | 2 | 4)) = Box::new(Box::new(0)) {} | error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs index b2a8fdcc0ce77..1c9f9e034e394 100644 --- a/src/tools/clippy/tests/ui/used_underscore_binding.rs +++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs @@ -1,153 +1,150 @@ -//@aux-build:proc_macro_derive.rs -#![feature(rustc_private)] -#![warn(clippy::used_underscore_binding)] -#![expect(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)] - -#[macro_use] -extern crate proc_macro_derive; - -// This should not trigger the lint. There's underscore binding inside the external derive that -// would trigger the `used_underscore_binding` lint. -#[derive(DeriveSomething)] -struct Baz; - -macro_rules! test_macro { - () => {{ - let _foo = 42; - _foo + 1 - }}; -} - -/// Tests that we lint if we use a binding with a single leading underscore -fn prefix_underscore(_foo: u32) -> u32 { - _foo + 1 - //~^ used_underscore_binding -} - -/// Tests that we lint if we use a `_`-variable defined outside within a macro expansion -fn in_macro_or_desugar(_foo: u32) { - println!("{}", _foo); - //~^ used_underscore_binding - assert_eq!(_foo, _foo); - //~^ used_underscore_binding - //~| used_underscore_binding - - test_macro!() + 1; -} - -// Struct for testing use of fields prefixed with an underscore -struct StructFieldTest { - _underscore_field: u32, -} - -/// Tests that we lint the use of a struct field which is prefixed with an underscore -fn in_struct_field() { - let mut s = StructFieldTest { _underscore_field: 0 }; - s._underscore_field += 1; - //~^ used_underscore_binding -} - -/// Tests that we do not lint if the struct field is used in code created with derive. -#[derive(Clone, Debug)] -pub struct UnderscoreInStruct { - _foo: u32, -} - -/// Tests that we do not lint if the underscore is not a prefix -fn non_prefix_underscore(some_foo: u32) -> u32 { - some_foo + 1 -} - -/// Tests that we do not lint if we do not use the binding (simple case) -fn unused_underscore_simple(_foo: u32) -> u32 { - 1 -} - -/// Tests that we do not lint if we do not use the binding (complex case). This checks for -/// compatibility with the built-in `unused_variables` lint. -fn unused_underscore_complex(mut _foo: u32) -> u32 { - _foo += 1; - _foo = 2; - 1 -} - -/// Test that we do not lint for multiple underscores -fn multiple_underscores(__foo: u32) -> u32 { - __foo + 1 -} - -// Non-variable bindings with preceding underscore -fn _fn_test() {} -struct _StructTest; -enum _EnumTest { - _Empty, - _Value(_StructTest), -} - -/// Tests that we do not lint for non-variable bindings -fn non_variables() { - _fn_test(); - let _s = _StructTest; - let _e = match _EnumTest::_Value(_StructTest) { - _EnumTest::_Empty => 0, - _EnumTest::_Value(_st) => 1, - }; - let f = _fn_test; - f(); -} - -// Tests that we do not lint if the binding comes from await desugaring, -// but we do lint the awaited expression. See issue 5360. -async fn await_desugaring() { - async fn foo() {} - fn uses_i(_i: i32) {} +//@aux-build:proc_macros.rs - foo().await; - ({ - let _i = 5; - uses_i(_i); - //~^ used_underscore_binding - foo() - }) - .await -} - -struct PhantomField { - _marker: std::marker::PhantomData, -} - -impl std::fmt::Debug for PhantomField { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("PhantomField").field("_marker", &self._marker).finish() - } -} +#![warn(clippy::used_underscore_binding)] +#![expect(clippy::explicit_auto_deref, clippy::no_effect)] -struct AllowedField { - #[allow(clippy::used_underscore_binding)] - _allowed: usize, -} +extern crate proc_macros; -struct ExpectedField { - #[expect(clippy::used_underscore_binding)] - _expected: usize, -} - -fn lint_levels(allowed: AllowedField, expected: ExpectedField) { - let _ = allowed._allowed; - let _ = expected._expected; -} +use core::marker::PhantomData; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { - let foo = 0u32; - // tests of unused_underscore lint - let _ = prefix_underscore(foo); - in_macro_or_desugar(foo); - in_struct_field(); - // possible false positives - let _ = non_prefix_underscore(foo); - let _ = unused_underscore_simple(foo); - let _ = unused_underscore_complex(foo); - let _ = multiple_underscores(foo); - non_variables(); - await_desugaring(); + // Declaration only. + { + let _a = 0; + } + // Check various reads. + { + let _a = 0; + let _b = &0; + let _c = (0, &0); + let _d = String::new(); + + _a; //~ used_underscore_binding + *_b; //~ used_underscore_binding + _c.0; //~ used_underscore_binding + *_c.1; //~ used_underscore_binding + _d.is_empty(); //~ used_underscore_binding + } + // Check that we match rustc on what a use is. + { + let mut _a = 0; + let mut _b = (0, 0); + let mut c = 0; + let mut _c = &mut c; + let mut d = (0, 0); + let _d = &mut d; + + _a = 0; + _b.0 = 0; + _c = &mut c; + *_c = 0; //~ used_underscore_binding + _d.0 = 0; //~ used_underscore_binding + (*_d).0 = 0; //~ used_underscore_binding + } + // Check field access. + { + struct X<'a> { + _x: &'a mut (u32, u32), + }; + + let mut a = (0, 0); + let mut b = (0, 0); + let mut c = X { _x: &mut a }; + + c._x; //~ used_underscore_binding + c._x = &mut b; //~ used_underscore_binding + *c._x; //~ used_underscore_binding + *c._x = (0, 0); //~ used_underscore_binding + (*c._x).0 = 0; //~ used_underscore_binding + c._x.0 = 0; //~ used_underscore_binding + } + // Await desugaring contains a used underscore binding. + { + async fn f1() {} + async fn f2() { + f1().await; + { + let _a = 0; + _a; //~ used_underscore_binding + f1() + } + .await; + } + } + // Ignore phantom fields + { + struct X { + _marker: PhantomData, + } + let a = X { _marker: PhantomData }; + a._marker; + } + // Ignore multiple underscores + { + struct X { + __x: u32, + } + let __a = 0; + let b = X { __x: 0 }; + __a; + b.__x; + } + // Check compound assignment + { + let mut _a = 0; + let mut _b = (0, 0); + let mut _c = 0.0; + let mut _d = String::new(); + + _a += 0; + _b.0 -= 0; + _b.1 |= 0; + _c *= 1.0; + _d += ""; //~ used_underscore_binding + } + // Expect on the binding + { + struct X { + #[expect(clippy::used_underscore_binding)] + _x: u32, + } + #[expect(clippy::used_underscore_binding)] + let _a = 0; + let b = X { _x: 0 }; + + _a; + b._x; + } + // Check macros + { + struct X { + _x: u32, + }; + + let _a = 0; + let _b = (0, 0); + let mut _c = 0; + let mut _d = (0, 0); + let e = X { _x: 0 }; + let mut f = X { _x: 0 }; + + inline!({ + $(@expr _a); //~ used_underscore_binding + $(@expr _b.0); //~ used_underscore_binding + $(@expr _c) = 0; + $(@expr _d.0) = 0; + $(@expr e._x); //~ used_underscore_binding + $(@expr f._x) = 0; //~ used_underscore_binding + }); + external!({ + $_a; //~ used_underscore_binding + $(_b.0); //~ used_underscore_binding + $_c = 0; + $(_d.0) = 0; + $(e._x); //~ used_underscore_binding + $(f._x) = 0; //~ used_underscore_binding + }); + } } diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.stderr b/src/tools/clippy/tests/ui/used_underscore_binding.stderr index 7d94d79f9b3b5..8675f5fe49850 100644 --- a/src/tools/clippy/tests/ui/used_underscore_binding.stderr +++ b/src/tools/clippy/tests/ui/used_underscore_binding.stderr @@ -1,76 +1,292 @@ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:23:5 + --> tests/ui/used_underscore_binding.rs:24:9 | -LL | _foo + 1 - | ^^^^ +LL | _a; + | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:22:22 + --> tests/ui/used_underscore_binding.rs:19:13 | -LL | fn prefix_underscore(_foo: u32) -> u32 { - | ^^^^ +LL | let _a = 0; + | ^^ = note: `-D clippy::used-underscore-binding` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]` error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:29:20 + --> tests/ui/used_underscore_binding.rs:25:10 + | +LL | *_b; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:20:13 + | +LL | let _b = &0; + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:26:9 + | +LL | _c.0; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:21:13 + | +LL | let _c = (0, &0); + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:27:10 + | +LL | *_c.1; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:21:13 + | +LL | let _c = (0, &0); + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:28:9 + | +LL | _d.is_empty(); + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:22:13 + | +LL | let _d = String::new(); + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:42:10 + | +LL | *_c = 0; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:35:13 + | +LL | let mut _c = &mut c; + | ^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:43:9 + | +LL | _d.0 = 0; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:37:13 + | +LL | let _d = &mut d; + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:44:11 + | +LL | (*_d).0 = 0; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:37:13 + | +LL | let _d = &mut d; + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:56:9 + | +LL | c._x; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:49:13 + | +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:57:9 + | +LL | c._x = &mut b; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:49:13 + | +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:58:10 + | +LL | *c._x; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:49:13 + | +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:59:10 + | +LL | *c._x = (0, 0); + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:49:13 + | +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:60:11 + | +LL | (*c._x).0 = 0; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:49:13 + | +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:61:9 | -LL | println!("{}", _foo); - | ^^^^ +LL | c._x.0 = 0; + | ^^^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:28:24 + --> tests/ui/used_underscore_binding.rs:49:13 | -LL | fn in_macro_or_desugar(_foo: u32) { - | ^^^^ +LL | _x: &'a mut (u32, u32), + | ^^^^^^^^^^^^^^^^^^^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:31:16 + --> tests/ui/used_underscore_binding.rs:70:17 | -LL | assert_eq!(_foo, _foo); - | ^^^^ +LL | _a; + | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:28:24 + --> tests/ui/used_underscore_binding.rs:69:21 | -LL | fn in_macro_or_desugar(_foo: u32) { - | ^^^^ +LL | let _a = 0; + | ^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:31:22 + --> tests/ui/used_underscore_binding.rs:105:9 | -LL | assert_eq!(_foo, _foo); - | ^^^^ +LL | _d += ""; + | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:28:24 + --> tests/ui/used_underscore_binding.rs:99:13 | -LL | fn in_macro_or_desugar(_foo: u32) { - | ^^^^ +LL | let mut _d = String::new(); + | ^^^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:46:5 + --> tests/ui/used_underscore_binding.rs:134:21 | -LL | s._underscore_field += 1; - | ^^^^^^^^^^^^^^^^^^^ +LL | $(@expr _a); + | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:40:5 + --> tests/ui/used_underscore_binding.rs:126:13 | -LL | _underscore_field: u32, - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | let _a = 0; + | ^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:108:16 + --> tests/ui/used_underscore_binding.rs:135:21 | -LL | uses_i(_i); - | ^^ +LL | $(@expr _b.0); + | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:107:13 + --> tests/ui/used_underscore_binding.rs:127:13 | -LL | let _i = 5; +LL | let _b = (0, 0); | ^^ -error: aborting due to 6 previous errors +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:138:21 + | +LL | $(@expr e._x); + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:123:13 + | +LL | _x: u32, + | ^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:139:21 + | +LL | $(@expr f._x) = 0; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:123:13 + | +LL | _x: u32, + | ^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:142:14 + | +LL | $_a; + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:126:13 + | +LL | let _a = 0; + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:143:15 + | +LL | $(_b.0); + | ^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:127:13 + | +LL | let _b = (0, 0); + | ^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:146:15 + | +LL | $(e._x); + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:123:13 + | +LL | _x: u32, + | ^^^^^^^ + +error: used underscore-prefixed binding + --> tests/ui/used_underscore_binding.rs:147:15 + | +LL | $(f._x) = 0; + | ^^^^ + | +note: binding is defined here + --> tests/ui/used_underscore_binding.rs:123:13 + | +LL | _x: u32, + | ^^^^^^^ + +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/used_underscore_items.rs b/src/tools/clippy/tests/ui/used_underscore_items.rs index 08660eefc3226..f459c32466508 100644 --- a/src/tools/clippy/tests/ui/used_underscore_items.rs +++ b/src/tools/clippy/tests/ui/used_underscore_items.rs @@ -1,81 +1,149 @@ //@aux-build:external_item.rs +//@aux-build:proc_macros.rs + #![warn(clippy::used_underscore_items)] +#![allow(clippy::no_effect)] extern crate external_item; +extern crate proc_macros; -// should not lint macro -macro_rules! macro_wrap_func { - () => { - fn _marco_foo() {} - }; -} +use proc_macros::{external, inline_macros}; -macro_wrap_func!(); +#[inline_macros] +fn main() { + { + fn _f() {} + const _C: u32 = 0; + static _S: u32 = 0; + struct _X; + enum Z { + _A, + } -struct _FooStruct {} + struct X; + impl X { + fn _m(self) {} + } -impl _FooStruct { - fn _method_call(self) {} -} + _f; //~ used_underscore_items + _f(); //~ used_underscore_items + _C; //~ used_underscore_items + _S; //~ used_underscore_items + _X; //~ used_underscore_items + _X {}; //~ used_underscore_items + Z::_A; //~ used_underscore_items + X::_m; //~ used_underscore_items + X._m(); //~ used_underscore_items + } + // Non-underscore names. + { + fn f1() {} + const C1: u32 = 0; + static S1: u32 = 0; + struct X1; + enum Z1 { + A1, + } -fn _foo1() {} + struct X; + impl X { + fn m1(self) {} + } -fn _foo2() -> i32 { - 0 -} + f1; + f1(); + C1; + S1; + X1; + X1 {}; + Z1::A1; + X::m1; + X.m1(); + } + // Don't lint external items. The names may not be changeable. + { + let x = external_item::_ExternalStruct {}; + x._foo(); + external_item::_external_foo(); + } + // Don't lint foreign functions. The names may not be changeable. + { + unsafe extern "C" { + pub fn _exit(code: i32) -> !; + } + unsafe { _exit(1) } + } + // Don't lint in macros. + { + fn _f() {} + const _C: u32 = 0; + static _S: u32 = 0; + struct _X; + enum Z { + _A, + } -mod a { - pub mod b { - pub mod c { - pub fn _foo3() {} + inline! { + _f(); + _C; + _S; + _X; + _X; + Z::_A; + } + } + // Make sure expect works on the item. + { + #[expect(clippy::used_underscore_items)] + fn _f() {} + #[expect(clippy::used_underscore_items)] + const _C: u32 = 0; + #[expect(clippy::used_underscore_items)] + static _S: u32 = 0; + #[expect(clippy::used_underscore_items)] + struct _X; + enum Z { + #[expect(clippy::used_underscore_items)] + _A, + } - pub struct _FooStruct2 {} + struct X; + impl X { + #[expect(clippy::used_underscore_items)] + fn _m(self) {} + } - impl _FooStruct2 { - pub fn _method_call(self) {} + _f; + _f(); + _C; + _S; + _X; + _X {}; + Z::_A; + X::_m; + X._m(); + } + // Ignore anything automatically derived. + { + struct S; + #[automatically_derived] + impl S { + fn f() { + fn _f() {} + const _C: u32 = 0; + static _S: u32 = 0; + struct _X; + enum Z { + _A, + } + + _f(); + _C; + _S; + _X; + _X {}; + Z::_A; } } } } - -fn main() { - _foo1(); - //~^ used_underscore_items - let _ = _foo2(); - //~^ used_underscore_items - a::b::c::_foo3(); - //~^ used_underscore_items - let _ = &_FooStruct {}; - //~^ used_underscore_items - let _ = _FooStruct {}; - //~^ used_underscore_items - - let foo_struct = _FooStruct {}; - //~^ used_underscore_items - foo_struct._method_call(); - //~^ used_underscore_items - - let foo_struct2 = a::b::c::_FooStruct2 {}; - //~^ used_underscore_items - foo_struct2._method_call(); - //~^ used_underscore_items -} - -// should not lint external crate. -// user cannot control how others name their items -fn external_item_call() { - let foo_struct3 = external_item::_ExternalStruct {}; - foo_struct3._foo(); - - external_item::_external_foo(); -} - -// should not lint foreign functions. -// issue #14156 -unsafe extern "C" { - pub fn _exit(code: i32) -> !; -} - -fn _f() { - unsafe { _exit(1) } -} diff --git a/src/tools/clippy/tests/ui/used_underscore_items.stderr b/src/tools/clippy/tests/ui/used_underscore_items.stderr index b2f9e2db0dfc4..2274769c5eaf9 100644 --- a/src/tools/clippy/tests/ui/used_underscore_items.stderr +++ b/src/tools/clippy/tests/ui/used_underscore_items.stderr @@ -1,112 +1,112 @@ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:42:5 + --> tests/ui/used_underscore_items.rs:28:9 | -LL | _foo1(); - | ^^^^^^^ +LL | _f; + | ^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:21:1 + --> tests/ui/used_underscore_items.rs:15:9 | -LL | fn _foo1() {} - | ^^^^^^^^^^ +LL | fn _f() {} + | ^^^^^^^ = note: `-D clippy::used-underscore-items` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::used_underscore_items)]` error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:44:13 + --> tests/ui/used_underscore_items.rs:29:9 | -LL | let _ = _foo2(); - | ^^^^^^^ +LL | _f(); + | ^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:23:1 + --> tests/ui/used_underscore_items.rs:15:9 | -LL | fn _foo2() -> i32 { - | ^^^^^^^^^^^^^^^^^ +LL | fn _f() {} + | ^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:46:5 + --> tests/ui/used_underscore_items.rs:30:9 | -LL | a::b::c::_foo3(); - | ^^^^^^^^^^^^^^^^ +LL | _C; + | ^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:30:13 + --> tests/ui/used_underscore_items.rs:16:9 | -LL | pub fn _foo3() {} - | ^^^^^^^^^^^^^^ +LL | const _C: u32 = 0; + | ^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:48:14 + --> tests/ui/used_underscore_items.rs:31:9 | -LL | let _ = &_FooStruct {}; - | ^^^^^^^^^^^^^ +LL | _S; + | ^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:15:1 + --> tests/ui/used_underscore_items.rs:17:9 | -LL | struct _FooStruct {} - | ^^^^^^^^^^^^^^^^^ +LL | static _S: u32 = 0; + | ^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:50:13 + --> tests/ui/used_underscore_items.rs:32:9 | -LL | let _ = _FooStruct {}; - | ^^^^^^^^^^^^^ +LL | _X; + | ^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:15:1 + --> tests/ui/used_underscore_items.rs:18:9 | -LL | struct _FooStruct {} - | ^^^^^^^^^^^^^^^^^ +LL | struct _X; + | ^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:53:22 + --> tests/ui/used_underscore_items.rs:33:9 | -LL | let foo_struct = _FooStruct {}; - | ^^^^^^^^^^^^^ +LL | _X {}; + | ^^^^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:15:1 + --> tests/ui/used_underscore_items.rs:18:9 | -LL | struct _FooStruct {} - | ^^^^^^^^^^^^^^^^^ +LL | struct _X; + | ^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:55:5 + --> tests/ui/used_underscore_items.rs:34:9 | -LL | foo_struct._method_call(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Z::_A; + | ^^^^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:18:5 + --> tests/ui/used_underscore_items.rs:20:13 | -LL | fn _method_call(self) {} - | ^^^^^^^^^^^^^^^^^^^^^ +LL | _A, + | ^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:58:23 + --> tests/ui/used_underscore_items.rs:35:9 | -LL | let foo_struct2 = a::b::c::_FooStruct2 {}; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | X::_m; + | ^^^^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:32:13 + --> tests/ui/used_underscore_items.rs:25:13 | -LL | pub struct _FooStruct2 {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn _m(self) {} + | ^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:60:5 + --> tests/ui/used_underscore_items.rs:36:9 | -LL | foo_struct2._method_call(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | X._m(); + | ^^^^^^ | note: item is defined here - --> tests/ui/used_underscore_items.rs:35:17 + --> tests/ui/used_underscore_items.rs:25:13 | -LL | pub fn _method_call(self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn _m(self) {} + | ^^^^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs index 19ccc7ae96070..c32333d51f20b 100644 --- a/src/tools/clippy/tests/workspace.rs +++ b/src/tools/clippy/tests/workspace.rs @@ -29,6 +29,7 @@ fn test_module_style_with_dep_in_subdir() { let output = Command::new(&*CARGO_CLIPPY_PATH) .current_dir(&cwd) .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TERM_COLOR", "never") .env("CARGO_TARGET_DIR", &target_dir) .arg("clippy") .args(["-p", "pass-no-mod-with-dep-in-subdir"]) @@ -68,6 +69,7 @@ fn test_no_deps_ignores_path_deps_in_workspaces() { let output = Command::new(&*CARGO_CLIPPY_PATH) .current_dir(&cwd) .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TERM_COLOR", "never") .env("CARGO_TARGET_DIR", &target_dir) .arg("clippy") .args(["-p", "subcrate"]) @@ -88,6 +90,7 @@ fn test_no_deps_ignores_path_deps_in_workspaces() { let output = Command::new(&*CARGO_CLIPPY_PATH) .current_dir(&cwd) .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TERM_COLOR", "never") .env("CARGO_TARGET_DIR", &target_dir) .arg("clippy") .args(["-p", "subcrate"]) @@ -115,6 +118,7 @@ fn test_no_deps_ignores_path_deps_in_workspaces() { let output = Command::new(&*CARGO_CLIPPY_PATH) .current_dir(&cwd) .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TERM_COLOR", "never") .env("CARGO_TARGET_DIR", &target_dir) .arg("clippy") .args(["-p", "subcrate"]) diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml index 55f9ca05999d8..7ebff7f79606c 100644 --- a/src/tools/clippy/triagebot.toml +++ b/src/tools/clippy/triagebot.toml @@ -97,7 +97,6 @@ users_on_vacation = [ "matthiaskrgr", "Alexendoo", "y21", - "blyxyas", "ada4a", "samueltardieu" ] @@ -115,6 +114,7 @@ users_on_vacation = [ "@y21", "@samueltardieu", "@ada4a", + "@blyxyas", ] # Require community reviews before automatic assignment