]> git.lizzy.rs Git - rust.git/commitdiff
Merge commit 'da5a6fb1b65ec6581a67e942a3850f6bc15a552c' into clippyup
authorflip1995 <hello@philkrones.com>
Sun, 26 Jul 2020 19:07:07 +0000 (21:07 +0200)
committerflip1995 <hello@philkrones.com>
Sun, 26 Jul 2020 19:07:07 +0000 (21:07 +0200)
53 files changed:
1  2 
src/tools/clippy/.github/deploy.sh
src/tools/clippy/CHANGELOG.md
src/tools/clippy/README.md
src/tools/clippy/clippy_lints/src/deprecated_lints.rs
src/tools/clippy/clippy_lints/src/dereference.rs
src/tools/clippy/clippy_lints/src/inherent_impl.rs
src/tools/clippy/clippy_lints/src/lib.rs
src/tools/clippy/clippy_lints/src/matches.rs
src/tools/clippy/clippy_lints/src/methods/mod.rs
src/tools/clippy/clippy_lints/src/misc.rs
src/tools/clippy/clippy_lints/src/misc_early.rs
src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
src/tools/clippy/clippy_lints/src/modulo_arithmetic.rs
src/tools/clippy/clippy_lints/src/non_expressive_names.rs
src/tools/clippy/clippy_lints/src/option_if_let_else.rs
src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
src/tools/clippy/clippy_lints/src/redundant_clone.rs
src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
src/tools/clippy/clippy_lints/src/shadow.rs
src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
src/tools/clippy/clippy_lints/src/useless_conversion.rs
src/tools/clippy/clippy_lints/src/utils/numeric_literal.rs
src/tools/clippy/clippy_lints/src/utils/paths.rs
src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs
src/tools/clippy/src/lintlist/mod.rs
src/tools/clippy/tests/ui/iter_nth_zero.stderr
src/tools/clippy/tests/ui/manual_async_fn.fixed
src/tools/clippy/tests/ui/manual_async_fn.rs
src/tools/clippy/tests/ui/manual_async_fn.stderr
src/tools/clippy/tests/ui/needless_range_loop2.rs
src/tools/clippy/tests/ui/never_loop.rs
src/tools/clippy/tests/ui/panicking_macros.rs
src/tools/clippy/tests/ui/panicking_macros.stderr
src/tools/clippy/tests/ui/precedence.fixed
src/tools/clippy/tests/ui/precedence.rs
src/tools/clippy/tests/ui/redundant_clone.fixed
src/tools/clippy/tests/ui/redundant_clone.rs
src/tools/clippy/tests/ui/redundant_clone.stderr
src/tools/clippy/tests/ui/redundant_closure_call_early.rs
src/tools/clippy/tests/ui/redundant_closure_call_early.stderr
src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
src/tools/clippy/tests/ui/redundant_closure_call_late.rs
src/tools/clippy/tests/ui/redundant_closure_call_late.stderr
src/tools/clippy/tests/ui/redundant_pattern_matching.fixed
src/tools/clippy/tests/ui/redundant_pattern_matching.rs
src/tools/clippy/tests/ui/redundant_pattern_matching.stderr
src/tools/clippy/tests/ui/shadow.stderr
src/tools/clippy/tests/ui/unit_return_expecting_ord.rs
src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
src/tools/clippy/tests/ui/useless_conversion.fixed
src/tools/clippy/tests/ui/useless_conversion.rs
src/tools/clippy/tests/ui/useless_conversion.stderr
src/tools/clippy/tests/ui/vec_resize_to_zero.rs

index 3f425e5b7258d52580b162ba1b6aecac643d8191,0000000000000000000000000000000000000000..e85e8874ba60039e3ba12819d198603bb95211b4
mode 100644,000000..100644
--- /dev/null
@@@ -1,57 -1,0 +1,66 @@@
-   cp -r out/master out/beta
 +#!/bin/bash
 +
 +set -ex
 +
 +echo "Removing the current docs for master"
 +rm -rf out/master/ || exit 0
 +
 +echo "Making the docs for master"
 +mkdir out/master/
 +cp util/gh-pages/index.html out/master
 +python3 ./util/export.py out/master/lints.json
 +
 +if [[ -n $TAG_NAME ]]; then
 +  echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it"
 +  cp -r out/master "out/$TAG_NAME"
 +  rm -f out/stable
 +  ln -s "$TAG_NAME" out/stable
 +fi
 +
 +if [[ $BETA = "true" ]]; then
 +  echo "Update documentation for the beta release"
- if git diff --exit-code --quiet; then
-   echo "No changes to the output on this push; exiting."
-   exit 0
- fi
++  cp -r out/master/* out/beta
 +fi
 +
 +# Generate version index that is shown as root index page
 +cp util/gh-pages/versions.html out/index.html
 +
 +echo "Making the versions.json file"
 +python3 ./util/versions.py out
 +
 +cd out
 +# Now let's go have some fun with the cloned repo
 +git config user.name "GHA CI"
 +git config user.email "gha@ci.invalid"
 +
 +if [[ -n $TAG_NAME ]]; then
++  # track files, so that the following check works
++  git add --intent-to-add "$TAG_NAME"
++  if git diff --exit-code --quiet -- $TAG_NAME/; then
++    echo "No changes to the output on this push; exiting."
++    exit 0
++  fi
 +  # Add the new dir
 +  git add "$TAG_NAME"
 +  # Update the symlink
 +  git add stable
 +  # Update versions file
 +  git add versions.json
 +  git commit -m "Add documentation for ${TAG_NAME} release: ${SHA}"
 +elif [[ $BETA = "true" ]]; then
++  if git diff --exit-code --quiet -- beta/; then
++    echo "No changes to the output on this push; exiting."
++    exit 0
++  fi
 +  git add beta
 +  git commit -m "Automatic deploy to GitHub Pages (beta): ${SHA}"
 +else
++  if git diff --exit-code --quiet; then
++    echo "No changes to the output on this push; exiting."
++    exit 0
++  fi
 +  git add .
 +  git commit -m "Automatic deploy to GitHub Pages: ${SHA}"
 +fi
 +
 +git push "$SSH_REPO" "$TARGET_BRANCH"
index 5d08b44ba404f9294f0b45973e017e571c208058,0000000000000000000000000000000000000000..776b04295f949c0e46b46fd8a2186fd91604cbd1
mode 100644,000000..100644
--- /dev/null
@@@ -1,1741 -1,0 +1,1804 @@@
- # Change Log
++# Changelog
 +
 +All notable changes to this project will be documented in this file.
 +See [Changelog Update](doc/changelog_update.md) if you want to update this
 +document.
 +
 +## Unreleased / In Rust Nightly
 +
- [7ea7cd1...master](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...master)
++[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...master)
++
++## Rust 1.46
++
++Current beta, release 2020-08-27
++
++[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...master)
++
++### New lints
++
++* [`unnested_or_patterns`] [#5378](https://github.com/rust-lang/rust-clippy/pull/5378)
++* [`iter_next_slice`] [#5597](https://github.com/rust-lang/rust-clippy/pull/5597)
++* [`unnecessary_sort_by`] [#5623](https://github.com/rust-lang/rust-clippy/pull/5623)
++* [`vec_resize_to_zero`] [#5637](https://github.com/rust-lang/rust-clippy/pull/5637)
++
++### Moves and Deprecations
++
++* Move [`cast_ptr_alignment`] to pedantic [#5667](https://github.com/rust-lang/rust-clippy/pull/5667)
++
++### Enhancements
++
++* Improve [`mem_replace_with_uninit`] lint [#5695](https://github.com/rust-lang/rust-clippy/pull/5695)
++
++### False Positive Fixes
++
++* [`len_zero`]: Avoid linting ranges when the `range_is_empty` feature is not enabled
++  [#5656](https://github.com/rust-lang/rust-clippy/pull/5656)
++* [`let_and_return`]: Don't lint if a temporary borrow is involved
++  [#5680](https://github.com/rust-lang/rust-clippy/pull/5680)
++* [`reversed_empty_ranges`]: Avoid linting `N..N` in for loop arguments in
++  [#5692](https://github.com/rust-lang/rust-clippy/pull/5692)
++* [`if_same_then_else`]: Don't assume multiplication is always commutative
++  [#5702](https://github.com/rust-lang/rust-clippy/pull/5702)
++* [`blacklisted_name`]: Remove `bar` from the default configuration
++  [#5712](https://github.com/rust-lang/rust-clippy/pull/5712)
++* [`redundant_pattern_matching`]: Avoid suggesting non-`const fn` calls in const contexts
++  [#5724](https://github.com/rust-lang/rust-clippy/pull/5724)
++
++### Suggestion Fixes/Improvements
++
++* Fix suggestion of [`unit_arg`] lint, so that it suggest semantic equivalent code
++  [#4455](https://github.com/rust-lang/rust-clippy/pull/4455)
++* Add auto applicable suggestion to [`macro_use_imports`]
++  [#5279](https://github.com/rust-lang/rust-clippy/pull/5279)
++
++### ICE Fixes
++
++* Fix ICE in the `consts` module of Clippy [#5709](https://github.com/rust-lang/rust-clippy/pull/5709)
++
++### Documentation Improvements
++
++* Improve code examples across multiple lints [#5664](https://github.com/rust-lang/rust-clippy/pull/5664)
++
++### Others
++
++* Introduce a `--rustc` flag to `clippy-driver`, which turns `clippy-driver`
++  into `rustc` and passes all the given arguments to `rustc`. This is especially
++  useful for tools that need the `rustc` version Clippy was compiled with,
++  instead of the Clippy version. E.g. `clippy-driver --rustc --version` will
++  print the output of `rustc --version`.
++  [#5178](https://github.com/rust-lang/rust-clippy/pull/5178)
++* New issue templates now make it easier to complain if Clippy is too annoying
++  or not annoying enough! [#5735](https://github.com/rust-lang/rust-clippy/pull/5735)
 +
 +## Rust 1.45
 +
- Current beta, release 2020-07-16
++Current stable, released 2020-07-16
 +
 +[891e1a8...7ea7cd1](https://github.com/rust-lang/rust-clippy/compare/891e1a8...7ea7cd1)
 +
 +### New lints
 +
 +* [`match_wildcard_for_single_variants`] [#5582](https://github.com/rust-lang/rust-clippy/pull/5582)
 +* [`unsafe_derive_deserialize`] [#5493](https://github.com/rust-lang/rust-clippy/pull/5493)
 +* [`if_let_mutex`] [#5332](https://github.com/rust-lang/rust-clippy/pull/5332)
 +* [`mismatched_target_os`] [#5506](https://github.com/rust-lang/rust-clippy/pull/5506)
 +* [`await_holding_lock`] [#5439](https://github.com/rust-lang/rust-clippy/pull/5439)
 +* [`match_on_vec_items`] [#5522](https://github.com/rust-lang/rust-clippy/pull/5522)
 +* [`manual_async_fn`] [#5576](https://github.com/rust-lang/rust-clippy/pull/5576)
 +* [`reversed_empty_ranges`] [#5583](https://github.com/rust-lang/rust-clippy/pull/5583)
 +* [`manual_non_exhaustive`] [#5550](https://github.com/rust-lang/rust-clippy/pull/5550)
 +
 +### Moves and Deprecations
 +
 +* Downgrade [`match_bool`] to pedantic [#5408](https://github.com/rust-lang/rust-clippy/pull/5408)
 +* Downgrade [`match_wild_err_arm`] to pedantic and update help messages. [#5622](https://github.com/rust-lang/rust-clippy/pull/5622)
 +* Downgrade [`useless_let_if_seq`] to nursery. [#5599](https://github.com/rust-lang/rust-clippy/pull/5599)
 +* Generalize `option_and_then_some` and rename to [`bind_instead_of_map`]. [#5529](https://github.com/rust-lang/rust-clippy/pull/5529)
 +* Rename `identity_conversion` to [`useless_conversion`]. [#5568](https://github.com/rust-lang/rust-clippy/pull/5568)
 +* Merge `block_in_if_condition_expr` and `block_in_if_condition_stmt` into [`blocks_in_if_conditions`].
 +[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)
 +* Merge `option_map_unwrap_or`, `option_map_unwrap_or_else` and `result_map_unwrap_or_else` into [`map_unwrap_or`].
 +[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)
 +* Merge `option_unwrap_used` and `result_unwrap_used` into [`unwrap_used`].
 +[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)
 +* Merge `option_expect_used` and `result_expect_used` into [`expect_used`].
 +[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)
 +* Merge `for_loop_over_option` and `for_loop_over_result` into [`for_loops_over_fallibles`].
 +[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)
 +
 +### Enhancements
 +
 +* Avoid running cargo lints when not enabled to improve performance. [#5505](https://github.com/rust-lang/rust-clippy/pull/5505)
 +* Extend [`useless_conversion`] with `TryFrom` and `TryInto`. [#5631](https://github.com/rust-lang/rust-clippy/pull/5631)
 +* Lint also in type parameters and where clauses in [`unused_unit`]. [#5592](https://github.com/rust-lang/rust-clippy/pull/5592)
 +* Do not suggest deriving `Default` in [`new_without_default`]. [#5616](https://github.com/rust-lang/rust-clippy/pull/5616)
 +
 +### False Positive Fixes
 +
 +* [`while_let_on_iterator`] [#5525](https://github.com/rust-lang/rust-clippy/pull/5525)
 +* [`empty_line_after_outer_attr`] [#5609](https://github.com/rust-lang/rust-clippy/pull/5609)
 +* [`unnecessary_unwrap`] [#5558](https://github.com/rust-lang/rust-clippy/pull/5558)
 +* [`comparison_chain`] [#5596](https://github.com/rust-lang/rust-clippy/pull/5596)
 +* Don't trigger [`used_underscore_binding`] in await desugaring. [#5535](https://github.com/rust-lang/rust-clippy/pull/5535)
 +* Don't trigger [`borrowed_box`] on mutable references. [#5491](https://github.com/rust-lang/rust-clippy/pull/5491)
 +* Allow `1 << 0` in [`identity_op`]. [#5602](https://github.com/rust-lang/rust-clippy/pull/5602)
 +* Allow `use super::*;` glob imports in [`wildcard_imports`]. [#5564](https://github.com/rust-lang/rust-clippy/pull/5564)
 +* Whitelist more words in [`doc_markdown`]. [#5611](https://github.com/rust-lang/rust-clippy/pull/5611)
 +* Skip dev and build deps in [`multiple_crate_versions`]. [#5636](https://github.com/rust-lang/rust-clippy/pull/5636)
 +* Honor `allow` attribute on arguments in [`ptr_arg`]. [#5647](https://github.com/rust-lang/rust-clippy/pull/5647)
 +* Honor lint level attributes for [`redundant_field_names`], [`just_underscores_and_digits`], [`many_single_char_names`]
 +and [`similar_names`]. [#5651](https://github.com/rust-lang/rust-clippy/pull/5651)
 +* Ignore calls to `len` in [`or_fun_call`]. [#4429](https://github.com/rust-lang/rust-clippy/pull/4429)
 +
 +### Suggestion Improvements
 +
 +* Simplify suggestions in [`manual_memcpy`]. [#5536](https://github.com/rust-lang/rust-clippy/pull/5536)
 +* Fix suggestion in [`redundant_pattern_matching`] for macros. [#5511](https://github.com/rust-lang/rust-clippy/pull/5511)
 +* Avoid suggesting `copied()` for mutable references in [`map_clone`]. [#5530](https://github.com/rust-lang/rust-clippy/pull/5530)
 +* Improve help message for [`clone_double_ref`]. [#5547](https://github.com/rust-lang/rust-clippy/pull/5547)
 +
 +### ICE Fixes
 +
 +* Fix ICE caused in unwrap module. [#5590](https://github.com/rust-lang/rust-clippy/pull/5590)
 +* Fix ICE on rustc test issue-69020-assoc-const-arith-overflow.rs [#5499](https://github.com/rust-lang/rust-clippy/pull/5499)
 +
 +### Documentation
 +
 +* Clarify the documentation of [`unnecessary_mut_passed`]. [#5639](https://github.com/rust-lang/rust-clippy/pull/5639)
 +* Extend example for [`unneeded_field_pattern`]. [#5541](https://github.com/rust-lang/rust-clippy/pull/5541)
 +
 +## Rust 1.44
 +
- Current stable, released 2020-06-04
++Released 2020-06-04
 +
 +[204bb9b...891e1a8](https://github.com/rust-lang/rust-clippy/compare/204bb9b...891e1a8)
 +
 +### New lints
 +
 +* [`explicit_deref_methods`] [#5226](https://github.com/rust-lang/rust-clippy/pull/5226)
 +* [`implicit_saturating_sub`] [#5427](https://github.com/rust-lang/rust-clippy/pull/5427)
 +* [`macro_use_imports`] [#5230](https://github.com/rust-lang/rust-clippy/pull/5230)
 +* [`verbose_file_reads`] [#5272](https://github.com/rust-lang/rust-clippy/pull/5272)
 +* [`future_not_send`] [#5423](https://github.com/rust-lang/rust-clippy/pull/5423)
 +* [`redundant_pub_crate`] [#5319](https://github.com/rust-lang/rust-clippy/pull/5319)
 +* [`large_const_arrays`] [#5248](https://github.com/rust-lang/rust-clippy/pull/5248)
 +* [`result_map_or_into_option`] [#5415](https://github.com/rust-lang/rust-clippy/pull/5415)
 +* [`redundant_allocation`] [#5349](https://github.com/rust-lang/rust-clippy/pull/5349)
 +* [`fn_address_comparisons`] [#5294](https://github.com/rust-lang/rust-clippy/pull/5294)
 +* [`vtable_address_comparisons`] [#5294](https://github.com/rust-lang/rust-clippy/pull/5294)
 +
 +
 +### Moves and Deprecations
 +
 +* Deprecate [`replace_consts`] lint [#5380](https://github.com/rust-lang/rust-clippy/pull/5380)
 +* Move [`cognitive_complexity`] to nursery [#5428](https://github.com/rust-lang/rust-clippy/pull/5428)
 +* Move [`useless_transmute`] to nursery [#5364](https://github.com/rust-lang/rust-clippy/pull/5364)
 +* Downgrade [`inefficient_to_string`] to pedantic [#5412](https://github.com/rust-lang/rust-clippy/pull/5412)
 +* Downgrade [`option_option`] to pedantic [#5401](https://github.com/rust-lang/rust-clippy/pull/5401)
 +* Downgrade [`unreadable_literal`] to pedantic [#5419](https://github.com/rust-lang/rust-clippy/pull/5419)
 +* Downgrade [`let_unit_value`] to pedantic [#5409](https://github.com/rust-lang/rust-clippy/pull/5409)
 +* Downgrade [`trivially_copy_pass_by_ref`] to pedantic [#5410](https://github.com/rust-lang/rust-clippy/pull/5410)
 +* Downgrade [`implicit_hasher`] to pedantic [#5411](https://github.com/rust-lang/rust-clippy/pull/5411)
 +
 +### Enhancements
 +
 +* On _nightly_ you can now use `cargo clippy --fix -Z unstable-options` to
 +  auto-fix lints that support this [#5363](https://github.com/rust-lang/rust-clippy/pull/5363)
 +* Make [`redundant_clone`] also trigger on cases where the cloned value is not
 +  consumed. [#5304](https://github.com/rust-lang/rust-clippy/pull/5304)
 +* Expand [`integer_arithmetic`] to also disallow bit-shifting [#5430](https://github.com/rust-lang/rust-clippy/pull/5430)
 +* [`option_as_ref_deref`] now detects more deref cases [#5425](https://github.com/rust-lang/rust-clippy/pull/5425)
 +* [`large_enum_variant`] now report the sizes of the largest and second-largest variants [#5466](https://github.com/rust-lang/rust-clippy/pull/5466)
 +* [`bool_comparison`] now also checks for inequality comparisons that can be
 +  written more concisely [#5365](https://github.com/rust-lang/rust-clippy/pull/5365)
 +* Expand [`clone_on_copy`] to work in method call arguments as well [#5441](https://github.com/rust-lang/rust-clippy/pull/5441)
 +* [`redundant_pattern_matching`] now also handles `while let` [#5483](https://github.com/rust-lang/rust-clippy/pull/5483)
 +* [`integer_arithmetic`] now also lints references of integers [#5329](https://github.com/rust-lang/rust-clippy/pull/5329)
 +* Expand [`float_cmp_const`] to also work on arrays [#5345](https://github.com/rust-lang/rust-clippy/pull/5345)
 +* Trigger [`map_flatten`] when map is called on an `Option` [#5473](https://github.com/rust-lang/rust-clippy/pull/5473)
 +
 +### False Positive Fixes
 +
 +* [`many_single_char_names`] [#5468](https://github.com/rust-lang/rust-clippy/pull/5468)
 +* [`should_implement_trait`] [#5437](https://github.com/rust-lang/rust-clippy/pull/5437)
 +* [`unused_self`] [#5387](https://github.com/rust-lang/rust-clippy/pull/5387)
 +* [`redundant_clone`] [#5453](https://github.com/rust-lang/rust-clippy/pull/5453)
 +* [`precedence`] [#5445](https://github.com/rust-lang/rust-clippy/pull/5445)
 +* [`suspicious_op_assign_impl`] [#5424](https://github.com/rust-lang/rust-clippy/pull/5424)
 +* [`needless_lifetimes`] [#5293](https://github.com/rust-lang/rust-clippy/pull/5293)
 +* [`redundant_pattern`] [#5287](https://github.com/rust-lang/rust-clippy/pull/5287)
 +* [`inconsistent_digit_grouping`] [#5451](https://github.com/rust-lang/rust-clippy/pull/5451)
 +
 +
 +### Suggestion Improvements
 +
 +* Improved [`question_mark`] lint suggestion so that it doesn't add redundant `as_ref()` [#5481](https://github.com/rust-lang/rust-clippy/pull/5481)
 +* Improve the suggested placeholder in [`option_map_unit_fn`] [#5292](https://github.com/rust-lang/rust-clippy/pull/5292)
 +* Improve suggestion for [`match_single_binding`] when triggered inside a closure [#5350](https://github.com/rust-lang/rust-clippy/pull/5350)
 +
 +### ICE Fixes
 +
 +* Handle the unstable `trivial_bounds` feature [#5296](https://github.com/rust-lang/rust-clippy/pull/5296)
 +* `shadow_*` lints [#5297](https://github.com/rust-lang/rust-clippy/pull/5297)
 +
 +### Documentation
 +
 +* Fix documentation generation for configurable lints [#5353](https://github.com/rust-lang/rust-clippy/pull/5353)
 +* Update documentation for [`new_ret_no_self`] [#5448](https://github.com/rust-lang/rust-clippy/pull/5448)
 +* The documentation for [`option_option`] now suggest using a tri-state enum [#5403](https://github.com/rust-lang/rust-clippy/pull/5403)
 +* Fix bit mask example in [`verbose_bit_mask`] documentation [#5454](https://github.com/rust-lang/rust-clippy/pull/5454)
 +* [`wildcard_imports`] documentation now mentions that `use ...::prelude::*` is
 +  not linted [#5312](https://github.com/rust-lang/rust-clippy/pull/5312)
 +
 +## Rust 1.43
 +
 +Released 2020-04-23
 +
 +[4ee1206...204bb9b](https://github.com/rust-lang/rust-clippy/compare/4ee1206...204bb9b)
 +
 +### New lints
 +
 +* [`imprecise_flops`] [#4897](https://github.com/rust-lang/rust-clippy/pull/4897)
 +* [`suboptimal_flops`] [#4897](https://github.com/rust-lang/rust-clippy/pull/4897)
 +* [`wildcard_imports`] [#5029](https://github.com/rust-lang/rust-clippy/pull/5029)
 +* [`single_component_path_imports`] [#5058](https://github.com/rust-lang/rust-clippy/pull/5058)
 +* [`match_single_binding`] [#5061](https://github.com/rust-lang/rust-clippy/pull/5061)
 +* [`let_underscore_lock`] [#5101](https://github.com/rust-lang/rust-clippy/pull/5101)
 +* [`struct_excessive_bools`] [#5125](https://github.com/rust-lang/rust-clippy/pull/5125)
 +* [`fn_params_excessive_bools`] [#5125](https://github.com/rust-lang/rust-clippy/pull/5125)
 +* [`option_env_unwrap`] [#5148](https://github.com/rust-lang/rust-clippy/pull/5148)
 +* [`lossy_float_literal`] [#5202](https://github.com/rust-lang/rust-clippy/pull/5202)
 +* [`rest_pat_in_fully_bound_structs`] [#5258](https://github.com/rust-lang/rust-clippy/pull/5258)
 +
 +### Moves and Deprecations
 +
 +* Move [`unneeded_field_pattern`] to pedantic group [#5200](https://github.com/rust-lang/rust-clippy/pull/5200)
 +
 +### Enhancements
 +
 +* Make [`missing_errors_doc`] lint also trigger on `async` functions
 +  [#5181](https://github.com/rust-lang/rust-clippy/pull/5181)
 +* Add more constants to [`approx_constant`] [#5193](https://github.com/rust-lang/rust-clippy/pull/5193)
 +* Extend [`question_mark`] lint [#5266](https://github.com/rust-lang/rust-clippy/pull/5266)
 +
 +### False Positive Fixes
 +
 +* [`use_debug`] [#5047](https://github.com/rust-lang/rust-clippy/pull/5047)
 +* [`unnecessary_unwrap`] [#5132](https://github.com/rust-lang/rust-clippy/pull/5132)
 +* [`zero_prefixed_literal`] [#5170](https://github.com/rust-lang/rust-clippy/pull/5170)
 +* [`missing_const_for_fn`] [#5216](https://github.com/rust-lang/rust-clippy/pull/5216)
 +
 +### Suggestion Improvements
 +
 +* Improve suggestion when blocks of code are suggested [#5134](https://github.com/rust-lang/rust-clippy/pull/5134)
 +
 +### ICE Fixes
 +
 +* `misc_early` lints [#5129](https://github.com/rust-lang/rust-clippy/pull/5129)
 +* [`missing_errors_doc`] [#5213](https://github.com/rust-lang/rust-clippy/pull/5213)
 +* Fix ICE when evaluating `usize`s [#5256](https://github.com/rust-lang/rust-clippy/pull/5256)
 +
 +### Documentation
 +
 +* Improve documentation of [`iter_nth_zero`]
 +* Add documentation pages for stable releases [#5171](https://github.com/rust-lang/rust-clippy/pull/5171)
 +
 +### Others
 +
 +* Clippy now completely runs on GitHub Actions [#5190](https://github.com/rust-lang/rust-clippy/pull/5190)
 +
 +
 +## Rust 1.42
 +
 +Released 2020-03-12
 +
 +[69f99e7...4ee1206](https://github.com/rust-lang/rust-clippy/compare/69f99e7...4ee1206)
 +
 +### New lints
 +
 +* [`filetype_is_file`] [#4543](https://github.com/rust-lang/rust-clippy/pull/4543)
 +* [`let_underscore_must_use`] [#4823](https://github.com/rust-lang/rust-clippy/pull/4823)
 +* [`modulo_arithmetic`] [#4867](https://github.com/rust-lang/rust-clippy/pull/4867)
 +* [`mem_replace_with_default`] [#4881](https://github.com/rust-lang/rust-clippy/pull/4881)
 +* [`mutable_key_type`] [#4885](https://github.com/rust-lang/rust-clippy/pull/4885)
 +* [`option_as_ref_deref`] [#4945](https://github.com/rust-lang/rust-clippy/pull/4945)
 +* [`wildcard_in_or_patterns`] [#4960](https://github.com/rust-lang/rust-clippy/pull/4960)
 +* [`iter_nth_zero`] [#4966](https://github.com/rust-lang/rust-clippy/pull/4966)
 +* [`invalid_atomic_ordering`] [#4999](https://github.com/rust-lang/rust-clippy/pull/4999)
 +* [`skip_while_next`] [#5067](https://github.com/rust-lang/rust-clippy/pull/5067)
 +
 +### Moves and Deprecations
 +
 +* Move [`transmute_float_to_int`] from nursery to complexity group
 +  [#5015](https://github.com/rust-lang/rust-clippy/pull/5015)
 +* Move [`range_plus_one`] to pedantic group [#5057](https://github.com/rust-lang/rust-clippy/pull/5057)
 +* Move [`debug_assert_with_mut_call`] to nursery group [#5106](https://github.com/rust-lang/rust-clippy/pull/5106)
 +* Deprecate [`unused_label`] [#4930](https://github.com/rust-lang/rust-clippy/pull/4930)
 +
 +### Enhancements
 +
 +* Lint vectored IO in [`unused_io_amount`] [#5027](https://github.com/rust-lang/rust-clippy/pull/5027)
 +* Make [`vec_box`] configurable by adding a size threshold [#5081](https://github.com/rust-lang/rust-clippy/pull/5081)
 +* Also lint constants in [`cmp_nan`] [#4910](https://github.com/rust-lang/rust-clippy/pull/4910)
 +* Fix false negative in [`expect_fun_call`] [#4915](https://github.com/rust-lang/rust-clippy/pull/4915)
 +* Fix false negative in [`redundant_clone`] [#5017](https://github.com/rust-lang/rust-clippy/pull/5017)
 +
 +### False Positive Fixes
 +
 +* [`map_clone`] [#4937](https://github.com/rust-lang/rust-clippy/pull/4937)
 +* [`replace_consts`] [#4977](https://github.com/rust-lang/rust-clippy/pull/4977)
 +* [`let_and_return`] [#5008](https://github.com/rust-lang/rust-clippy/pull/5008)
 +* [`eq_op`] [#5079](https://github.com/rust-lang/rust-clippy/pull/5079)
 +* [`possible_missing_comma`] [#5083](https://github.com/rust-lang/rust-clippy/pull/5083)
 +* [`debug_assert_with_mut_call`] [#5106](https://github.com/rust-lang/rust-clippy/pull/5106)
 +* Don't trigger [`let_underscore_must_use`] in external macros
 +  [#5082](https://github.com/rust-lang/rust-clippy/pull/5082)
 +* Don't trigger [`empty_loop`] in `no_std` crates [#5086](https://github.com/rust-lang/rust-clippy/pull/5086)
 +
 +### Suggestion Improvements
 +
 +* `option_map_unwrap_or` [#4634](https://github.com/rust-lang/rust-clippy/pull/4634)
 +* [`wildcard_enum_match_arm`] [#4934](https://github.com/rust-lang/rust-clippy/pull/4934)
 +* [`cognitive_complexity`] [#4935](https://github.com/rust-lang/rust-clippy/pull/4935)
 +* [`decimal_literal_representation`] [#4956](https://github.com/rust-lang/rust-clippy/pull/4956)
 +* [`unknown_clippy_lints`] [#4963](https://github.com/rust-lang/rust-clippy/pull/4963)
 +* [`explicit_into_iter_loop`] [#4978](https://github.com/rust-lang/rust-clippy/pull/4978)
 +* [`useless_attribute`] [#5022](https://github.com/rust-lang/rust-clippy/pull/5022)
 +* [`if_let_some_result`] [#5032](https://github.com/rust-lang/rust-clippy/pull/5032)
 +
 +### ICE fixes
 +
 +* [`unsound_collection_transmute`] [#4975](https://github.com/rust-lang/rust-clippy/pull/4975)
 +
 +### Documentation
 +
 +* Improve documentation of [`empty_enum`], [`replace_consts`], [`redundant_clone`], and [`iterator_step_by_zero`]
 +
 +
 +## Rust 1.41
 +
 +Released 2020-01-30
 +
 +[c8e3cfb...69f99e7](https://github.com/rust-lang/rust-clippy/compare/c8e3cfb...69f99e7)
 +
 +* New Lints:
 +  * [`exit`] [#4697](https://github.com/rust-lang/rust-clippy/pull/4697)
 +  * [`to_digit_is_some`] [#4801](https://github.com/rust-lang/rust-clippy/pull/4801)
 +  * [`tabs_in_doc_comments`] [#4806](https://github.com/rust-lang/rust-clippy/pull/4806)
 +  * [`large_stack_arrays`] [#4807](https://github.com/rust-lang/rust-clippy/pull/4807)
 +  * [`same_functions_in_if_condition`] [#4814](https://github.com/rust-lang/rust-clippy/pull/4814)
 +  * [`zst_offset`] [#4816](https://github.com/rust-lang/rust-clippy/pull/4816)
 +  * [`as_conversions`] [#4821](https://github.com/rust-lang/rust-clippy/pull/4821)
 +  * [`missing_errors_doc`] [#4884](https://github.com/rust-lang/rust-clippy/pull/4884)
 +  * [`transmute_float_to_int`] [#4889](https://github.com/rust-lang/rust-clippy/pull/4889)
 +* Remove plugin interface, see
 +  [Inside Rust Blog](https://blog.rust-lang.org/inside-rust/2019/11/04/Clippy-removes-plugin-interface.html) for
 +  details [#4714](https://github.com/rust-lang/rust-clippy/pull/4714)
 +* Move [`use_self`] to nursery group [#4863](https://github.com/rust-lang/rust-clippy/pull/4863)
 +* Deprecate [`into_iter_on_array`] [#4788](https://github.com/rust-lang/rust-clippy/pull/4788)
 +* Expand [`string_lit_as_bytes`] to also trigger when literal has escapes
 +  [#4808](https://github.com/rust-lang/rust-clippy/pull/4808)
 +* Fix false positive in `comparison_chain` [#4842](https://github.com/rust-lang/rust-clippy/pull/4842)
 +* Fix false positive in `while_immutable_condition` [#4730](https://github.com/rust-lang/rust-clippy/pull/4730)
 +* Fix false positive in `explicit_counter_loop` [#4803](https://github.com/rust-lang/rust-clippy/pull/4803)
 +* Fix false positive in `must_use_candidate` [#4794](https://github.com/rust-lang/rust-clippy/pull/4794)
 +* Fix false positive in `print_with_newline` and `write_with_newline`
 +  [#4769](https://github.com/rust-lang/rust-clippy/pull/4769)
 +* Fix false positive in `derive_hash_xor_eq` [#4766](https://github.com/rust-lang/rust-clippy/pull/4766)
 +* Fix false positive in `missing_inline_in_public_items` [#4870](https://github.com/rust-lang/rust-clippy/pull/4870)
 +* Fix false positive in `string_add` [#4880](https://github.com/rust-lang/rust-clippy/pull/4880)
 +* Fix false positive in `float_arithmetic` [#4851](https://github.com/rust-lang/rust-clippy/pull/4851)
 +* Fix false positive in `cast_sign_loss` [#4883](https://github.com/rust-lang/rust-clippy/pull/4883)
 +* Fix false positive in `manual_swap` [#4877](https://github.com/rust-lang/rust-clippy/pull/4877)
 +* Fix ICEs occurring while checking some block expressions [#4772](https://github.com/rust-lang/rust-clippy/pull/4772)
 +* Fix ICE in `use_self` [#4776](https://github.com/rust-lang/rust-clippy/pull/4776)
 +* Fix ICEs related to `const_generics` [#4780](https://github.com/rust-lang/rust-clippy/pull/4780)
 +* Display help when running `clippy-driver` without arguments, instead of ICEing
 +  [#4810](https://github.com/rust-lang/rust-clippy/pull/4810)
 +* Clippy has its own ICE message now [#4588](https://github.com/rust-lang/rust-clippy/pull/4588)
 +* Show deprecated lints in the documentation again [#4757](https://github.com/rust-lang/rust-clippy/pull/4757)
 +* Improve Documentation by adding positive examples to some lints
 +  [#4832](https://github.com/rust-lang/rust-clippy/pull/4832)
 +
 +## Rust 1.40
 +
 +Released 2019-12-19
 +
 +[4e7e71b...c8e3cfb](https://github.com/rust-lang/rust-clippy/compare/4e7e71b...c8e3cfb)
 +
 +* New Lints:
 +  * [`unneeded_wildcard_pattern`] [#4537](https://github.com/rust-lang/rust-clippy/pull/4537)
 +  * [`needless_doctest_main`] [#4603](https://github.com/rust-lang/rust-clippy/pull/4603)
 +  * [`suspicious_unary_op_formatting`] [#4615](https://github.com/rust-lang/rust-clippy/pull/4615)
 +  * [`debug_assert_with_mut_call`] [#4680](https://github.com/rust-lang/rust-clippy/pull/4680)
 +  * [`unused_self`] [#4619](https://github.com/rust-lang/rust-clippy/pull/4619)
 +  * [`inefficient_to_string`] [#4683](https://github.com/rust-lang/rust-clippy/pull/4683)
 +  * [`must_use_unit`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)
 +  * [`must_use_candidate`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)
 +  * [`double_must_use`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)
 +  * [`comparison_chain`] [#4569](https://github.com/rust-lang/rust-clippy/pull/4569)
 +  * [`unsound_collection_transmute`] [#4592](https://github.com/rust-lang/rust-clippy/pull/4592)
 +  * [`panic`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)
 +  * [`unreachable`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)
 +  * [`todo`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)
 +  * `option_expect_used` [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)
 +  * `result_expect_used` [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)
 +* Move `redundant_clone` to perf group [#4509](https://github.com/rust-lang/rust-clippy/pull/4509)
 +* Move `manual_mul_add` to nursery group [#4736](https://github.com/rust-lang/rust-clippy/pull/4736)
 +* Expand `unit_cmp` to also work with `assert_eq!`, `debug_assert_eq!`, `assert_ne!` and `debug_assert_ne!` [#4613](https://github.com/rust-lang/rust-clippy/pull/4613)
 +* Expand `integer_arithmetic` to also detect mutating arithmetic like `+=` [#4585](https://github.com/rust-lang/rust-clippy/pull/4585)
 +* Fix false positive in `nonminimal_bool` [#4568](https://github.com/rust-lang/rust-clippy/pull/4568)
 +* Fix false positive in `missing_safety_doc` [#4611](https://github.com/rust-lang/rust-clippy/pull/4611)
 +* Fix false positive in `cast_sign_loss` [#4614](https://github.com/rust-lang/rust-clippy/pull/4614)
 +* Fix false positive in `redundant_clone` [#4509](https://github.com/rust-lang/rust-clippy/pull/4509)
 +* Fix false positive in `try_err` [#4721](https://github.com/rust-lang/rust-clippy/pull/4721)
 +* Fix false positive in `toplevel_ref_arg` [#4570](https://github.com/rust-lang/rust-clippy/pull/4570)
 +* Fix false positive in `multiple_inherent_impl` [#4593](https://github.com/rust-lang/rust-clippy/pull/4593)
 +* Improve more suggestions and tests in preparation for the unstable `cargo fix --clippy` [#4575](https://github.com/rust-lang/rust-clippy/pull/4575)
 +* Improve suggestion for `zero_ptr` [#4599](https://github.com/rust-lang/rust-clippy/pull/4599)
 +* Improve suggestion for `explicit_counter_loop` [#4691](https://github.com/rust-lang/rust-clippy/pull/4691)
 +* Improve suggestion for `mul_add` [#4602](https://github.com/rust-lang/rust-clippy/pull/4602)
 +* Improve suggestion for `assertions_on_constants` [#4635](https://github.com/rust-lang/rust-clippy/pull/4635)
 +* Fix ICE in `use_self` [#4671](https://github.com/rust-lang/rust-clippy/pull/4671)
 +* Fix ICE when encountering const casts [#4590](https://github.com/rust-lang/rust-clippy/pull/4590)
 +
 +## Rust 1.39
 +
 +Released 2019-11-07
 +
 +[3aea860...4e7e71b](https://github.com/rust-lang/rust-clippy/compare/3aea860...4e7e71b)
 +
 +* New Lints:
 +  * [`uninit_assumed_init`] [#4479](https://github.com/rust-lang/rust-clippy/pull/4479)
 +  * [`flat_map_identity`] [#4231](https://github.com/rust-lang/rust-clippy/pull/4231)
 +  * [`missing_safety_doc`] [#4535](https://github.com/rust-lang/rust-clippy/pull/4535)
 +  * [`mem_replace_with_uninit`] [#4511](https://github.com/rust-lang/rust-clippy/pull/4511)
 +  * [`suspicious_map`] [#4394](https://github.com/rust-lang/rust-clippy/pull/4394)
 +  * `option_and_then_some` [#4386](https://github.com/rust-lang/rust-clippy/pull/4386)
 +  * [`manual_saturating_arithmetic`] [#4498](https://github.com/rust-lang/rust-clippy/pull/4498)
 +* Deprecate `unused_collect` lint. This is fully covered by rustc's `#[must_use]` on `collect` [#4348](https://github.com/rust-lang/rust-clippy/pull/4348)
 +* Move `type_repetition_in_bounds` to pedantic group [#4403](https://github.com/rust-lang/rust-clippy/pull/4403)
 +* Move `cast_lossless` to pedantic group [#4539](https://github.com/rust-lang/rust-clippy/pull/4539)
 +* `temporary_cstring_as_ptr` now catches more cases [#4425](https://github.com/rust-lang/rust-clippy/pull/4425)
 +* `use_self` now works in constructors, too [#4525](https://github.com/rust-lang/rust-clippy/pull/4525)
 +* `cargo_common_metadata` now checks for license files [#4518](https://github.com/rust-lang/rust-clippy/pull/4518)
 +* `cognitive_complexity` now includes the measured complexity in the warning message [#4469](https://github.com/rust-lang/rust-clippy/pull/4469)
 +* Fix false positives in `block_in_if_*` lints [#4458](https://github.com/rust-lang/rust-clippy/pull/4458)
 +* Fix false positive in `cast_lossless` [#4473](https://github.com/rust-lang/rust-clippy/pull/4473)
 +* Fix false positive in `clone_on_copy` [#4411](https://github.com/rust-lang/rust-clippy/pull/4411)
 +* Fix false positive in `deref_addrof` [#4487](https://github.com/rust-lang/rust-clippy/pull/4487)
 +* Fix false positive in `too_many_lines` [#4490](https://github.com/rust-lang/rust-clippy/pull/4490)
 +* Fix false positive in `new_ret_no_self` [#4365](https://github.com/rust-lang/rust-clippy/pull/4365)
 +* Fix false positive in `manual_swap` [#4478](https://github.com/rust-lang/rust-clippy/pull/4478)
 +* Fix false positive in `missing_const_for_fn` [#4450](https://github.com/rust-lang/rust-clippy/pull/4450)
 +* Fix false positive in `extra_unused_lifetimes` [#4477](https://github.com/rust-lang/rust-clippy/pull/4477)
 +* Fix false positive in `inherent_to_string` [#4460](https://github.com/rust-lang/rust-clippy/pull/4460)
 +* Fix false positive in `map_entry` [#4495](https://github.com/rust-lang/rust-clippy/pull/4495)
 +* Fix false positive in `unused_unit` [#4445](https://github.com/rust-lang/rust-clippy/pull/4445)
 +* Fix false positive in `redundant_pattern` [#4489](https://github.com/rust-lang/rust-clippy/pull/4489)
 +* Fix false positive in `wrong_self_convention` [#4369](https://github.com/rust-lang/rust-clippy/pull/4369)
 +* Improve various suggestions and tests in preparation for the unstable `cargo fix --clippy` [#4558](https://github.com/rust-lang/rust-clippy/pull/4558)
 +* Improve suggestions for `redundant_pattern_matching` [#4352](https://github.com/rust-lang/rust-clippy/pull/4352)
 +* Improve suggestions for `explicit_write` [#4544](https://github.com/rust-lang/rust-clippy/pull/4544)
 +* Improve suggestion for `or_fun_call` [#4522](https://github.com/rust-lang/rust-clippy/pull/4522)
 +* Improve suggestion for `match_as_ref` [#4446](https://github.com/rust-lang/rust-clippy/pull/4446)
 +* Improve suggestion for `unnecessary_fold_span` [#4382](https://github.com/rust-lang/rust-clippy/pull/4382)
 +* Add suggestions for `unseparated_literal_suffix` [#4401](https://github.com/rust-lang/rust-clippy/pull/4401)
 +* Add suggestions for `char_lit_as_u8` [#4418](https://github.com/rust-lang/rust-clippy/pull/4418)
 +
 +## Rust 1.38
 +
 +Released 2019-09-26
 +
 +[e3cb40e...3aea860](https://github.com/rust-lang/rust-clippy/compare/e3cb40e...3aea860)
 +
 +* New Lints:
 +  * [`main_recursion`] [#4203](https://github.com/rust-lang/rust-clippy/pull/4203)
 +  * [`inherent_to_string`] [#4259](https://github.com/rust-lang/rust-clippy/pull/4259)
 +  * [`inherent_to_string_shadow_display`] [#4259](https://github.com/rust-lang/rust-clippy/pull/4259)
 +  * [`type_repetition_in_bounds`] [#3766](https://github.com/rust-lang/rust-clippy/pull/3766)
 +  * [`try_err`] [#4222](https://github.com/rust-lang/rust-clippy/pull/4222)
 +* Move `{unnnecessary,panicking}_unwrap` out of nursery [#4307](https://github.com/rust-lang/rust-clippy/pull/4307)
 +* Extend the `use_self` lint to suggest uses of `Self::Variant` [#4308](https://github.com/rust-lang/rust-clippy/pull/4308)
 +* Improve suggestion for needless return [#4262](https://github.com/rust-lang/rust-clippy/pull/4262)
 +* Add auto-fixable suggestion for `let_unit` [#4337](https://github.com/rust-lang/rust-clippy/pull/4337)
 +* Fix false positive in `pub_enum_variant_names` and `enum_variant_names` [#4345](https://github.com/rust-lang/rust-clippy/pull/4345)
 +* Fix false positive in `cast_ptr_alignment` [#4257](https://github.com/rust-lang/rust-clippy/pull/4257)
 +* Fix false positive in `string_lit_as_bytes` [#4233](https://github.com/rust-lang/rust-clippy/pull/4233)
 +* Fix false positive in `needless_lifetimes` [#4266](https://github.com/rust-lang/rust-clippy/pull/4266)
 +* Fix false positive in `float_cmp` [#4275](https://github.com/rust-lang/rust-clippy/pull/4275)
 +* Fix false positives in `needless_return` [#4274](https://github.com/rust-lang/rust-clippy/pull/4274)
 +* Fix false negative in `match_same_arms` [#4246](https://github.com/rust-lang/rust-clippy/pull/4246)
 +* Fix incorrect suggestion for `needless_bool` [#4335](https://github.com/rust-lang/rust-clippy/pull/4335)
 +* Improve suggestion for `cast_ptr_alignment` [#4257](https://github.com/rust-lang/rust-clippy/pull/4257)
 +* Improve suggestion for `single_char_literal` [#4361](https://github.com/rust-lang/rust-clippy/pull/4361)
 +* Improve suggestion for `len_zero` [#4314](https://github.com/rust-lang/rust-clippy/pull/4314)
 +* Fix ICE in `implicit_hasher` [#4268](https://github.com/rust-lang/rust-clippy/pull/4268)
 +* Fix allow bug in `trivially_copy_pass_by_ref` [#4250](https://github.com/rust-lang/rust-clippy/pull/4250)
 +
 +## Rust 1.37
 +
 +Released 2019-08-15
 +
 +[082cfa7...e3cb40e](https://github.com/rust-lang/rust-clippy/compare/082cfa7...e3cb40e)
 +
 +* New Lints:
 +  * [`checked_conversions`] [#4088](https://github.com/rust-lang/rust-clippy/pull/4088)
 +  * [`get_last_with_len`] [#3832](https://github.com/rust-lang/rust-clippy/pull/3832)
 +  * [`integer_division`] [#4195](https://github.com/rust-lang/rust-clippy/pull/4195)
 +* Renamed Lint: `const_static_lifetime` is now called [`redundant_static_lifetimes`].
 +  The lint now covers statics in addition to consts [#4162](https://github.com/rust-lang/rust-clippy/pull/4162)
 +* [`match_same_arms`] now warns for all identical arms, instead of only the first one [#4102](https://github.com/rust-lang/rust-clippy/pull/4102)
 +* [`needless_return`] now works with void functions [#4220](https://github.com/rust-lang/rust-clippy/pull/4220)
 +* Fix false positive in [`redundant_closure`] [#4190](https://github.com/rust-lang/rust-clippy/pull/4190)
 +* Fix false positive in [`useless_attribute`] [#4107](https://github.com/rust-lang/rust-clippy/pull/4107)
 +* Fix incorrect suggestion for [`float_cmp`] [#4214](https://github.com/rust-lang/rust-clippy/pull/4214)
 +* Add suggestions for [`print_with_newline`] and [`write_with_newline`] [#4136](https://github.com/rust-lang/rust-clippy/pull/4136)
 +* Improve suggestions for `option_map_unwrap_or_else` and `result_map_unwrap_or_else` [#4164](https://github.com/rust-lang/rust-clippy/pull/4164)
 +* Improve suggestions for [`non_ascii_literal`] [#4119](https://github.com/rust-lang/rust-clippy/pull/4119)
 +* Improve diagnostics for [`let_and_return`] [#4137](https://github.com/rust-lang/rust-clippy/pull/4137)
 +* Improve diagnostics for [`trivially_copy_pass_by_ref`] [#4071](https://github.com/rust-lang/rust-clippy/pull/4071)
 +* Add macro check for [`unreadable_literal`] [#4099](https://github.com/rust-lang/rust-clippy/pull/4099)
 +
 +## Rust 1.36
 +
 +Released 2019-07-04
 +
 +[eb9f9b1...082cfa7](https://github.com/rust-lang/rust-clippy/compare/eb9f9b1...082cfa7)
 +
 +* New lints: [`find_map`], [`filter_map_next`] [#4039](https://github.com/rust-lang/rust-clippy/pull/4039)
 +* New lint: [`path_buf_push_overwrite`] [#3954](https://github.com/rust-lang/rust-clippy/pull/3954)
 +* Move `path_buf_push_overwrite` to the nursery [#4013](https://github.com/rust-lang/rust-clippy/pull/4013)
 +* Split [`redundant_closure`] into [`redundant_closure`] and [`redundant_closure_for_method_calls`] [#4110](https://github.com/rust-lang/rust-clippy/pull/4101)
 +* Allow allowing of [`toplevel_ref_arg`] lint [#4007](https://github.com/rust-lang/rust-clippy/pull/4007)
 +* Fix false negative in [`or_fun_call`] pertaining to nested constructors [#4084](https://github.com/rust-lang/rust-clippy/pull/4084)
 +* Fix false positive in [`or_fun_call`] pertaining to enum variant constructors [#4018](https://github.com/rust-lang/rust-clippy/pull/4018)
 +* Fix false positive in [`useless_let_if_seq`] pertaining to interior mutability [#4035](https://github.com/rust-lang/rust-clippy/pull/4035)
 +* Fix false positive in [`redundant_closure`] pertaining to non-function types [#4008](https://github.com/rust-lang/rust-clippy/pull/4008)
 +* Fix false positive in [`let_and_return`] pertaining to attributes on `let`s [#4024](https://github.com/rust-lang/rust-clippy/pull/4024)
 +* Fix false positive in [`module_name_repetitions`] lint pertaining to attributes [#4006](https://github.com/rust-lang/rust-clippy/pull/4006)
 +* Fix false positive on [`assertions_on_constants`] pertaining to `debug_assert!` [#3989](https://github.com/rust-lang/rust-clippy/pull/3989)
 +* Improve suggestion in [`map_clone`] to suggest `.copied()` where applicable  [#3970](https://github.com/rust-lang/rust-clippy/pull/3970) [#4043](https://github.com/rust-lang/rust-clippy/pull/4043)
 +* Improve suggestion for [`search_is_some`] [#4049](https://github.com/rust-lang/rust-clippy/pull/4049)
 +* Improve suggestion applicability for [`naive_bytecount`] [#3984](https://github.com/rust-lang/rust-clippy/pull/3984)
 +* Improve suggestion applicability for [`while_let_loop`] [#3975](https://github.com/rust-lang/rust-clippy/pull/3975)
 +* Improve diagnostics for [`too_many_arguments`] [#4053](https://github.com/rust-lang/rust-clippy/pull/4053)
 +* Improve diagnostics for [`cast_lossless`] [#4021](https://github.com/rust-lang/rust-clippy/pull/4021)
 +* Deal with macro checks in desugarings better [#4082](https://github.com/rust-lang/rust-clippy/pull/4082)
 +* Add macro check for [`unnecessary_cast`]  [#4026](https://github.com/rust-lang/rust-clippy/pull/4026)
 +* Remove [`approx_constant`]'s documentation's "Known problems" section. [#4027](https://github.com/rust-lang/rust-clippy/pull/4027)
 +* Fix ICE in [`suspicious_else_formatting`] [#3960](https://github.com/rust-lang/rust-clippy/pull/3960)
 +* Fix ICE in [`decimal_literal_representation`] [#3931](https://github.com/rust-lang/rust-clippy/pull/3931)
 +
 +
 +## Rust 1.35
 +
 +Released 2019-05-20
 +
 +[1fac380..37f5c1e](https://github.com/rust-lang/rust-clippy/compare/1fac380...37f5c1e)
 +
 +* New lint: [`drop_bounds`] to detect `T: Drop` bounds
 +* Split [`redundant_closure`] into [`redundant_closure`] and [`redundant_closure_for_method_calls`] [#4110](https://github.com/rust-lang/rust-clippy/pull/4101)
 +* Rename `cyclomatic_complexity` to [`cognitive_complexity`], start work on making lint more practical for Rust code
 +* Move [`get_unwrap`] to the restriction category
 +* Improve suggestions for [`iter_cloned_collect`]
 +* Improve suggestions for [`cast_lossless`] to suggest suffixed literals
 +* Fix false positives in [`print_with_newline`] and [`write_with_newline`] pertaining to raw strings
 +* Fix false positive in [`needless_range_loop`] pertaining to structs without a `.iter()`
 +* Fix false positive in [`bool_comparison`] pertaining to non-bool types
 +* Fix false positive in [`redundant_closure`] pertaining to differences in borrows
 +* Fix false positive in `option_map_unwrap_or` on non-copy types
 +* Fix false positives in [`missing_const_for_fn`] pertaining to macros and trait method impls
 +* Fix false positive in [`needless_pass_by_value`] pertaining to procedural macros
 +* Fix false positive in [`needless_continue`] pertaining to loop labels
 +* Fix false positive for [`boxed_local`] pertaining to arguments moved into closures
 +* Fix false positive for [`use_self`] in nested functions
 +* Fix suggestion for [`expect_fun_call`] (https://github.com/rust-lang/rust-clippy/pull/3846)
 +* Fix suggestion for [`explicit_counter_loop`] to deal with parenthesizing range variables
 +* Fix suggestion for [`single_char_pattern`] to correctly escape single quotes
 +* Avoid triggering [`redundant_closure`] in macros
 +* ICE fixes: [#3805](https://github.com/rust-lang/rust-clippy/pull/3805), [#3772](https://github.com/rust-lang/rust-clippy/pull/3772), [#3741](https://github.com/rust-lang/rust-clippy/pull/3741)
 +
 +## Rust 1.34
 +
 +Released 2019-04-10
 +
 +[1b89724...1fac380](https://github.com/rust-lang/rust-clippy/compare/1b89724...1fac380)
 +
 +* New lint: [`assertions_on_constants`] to detect for example `assert!(true)`
 +* New lint: [`dbg_macro`] to detect uses of the `dbg!` macro
 +* New lint: [`missing_const_for_fn`] that can suggest functions to be made `const`
 +* New lint: [`too_many_lines`] to detect functions with excessive LOC. It can be
 +  configured using the `too-many-lines-threshold` configuration.
 +* New lint: [`wildcard_enum_match_arm`] to check for wildcard enum matches using `_`
 +* Expand `redundant_closure` to also work for methods (not only functions)
 +* Fix ICEs in `vec_box`, `needless_pass_by_value` and `implicit_hasher`
 +* Fix false positive in `cast_sign_loss`
 +* Fix false positive in `integer_arithmetic`
 +* Fix false positive in `unit_arg`
 +* Fix false positives in `implicit_return`
 +* Add suggestion to `explicit_write`
 +* Improve suggestions for `question_mark` lint
 +* Fix incorrect suggestion for `cast_lossless`
 +* Fix incorrect suggestion for `expect_fun_call`
 +* Fix incorrect suggestion for `needless_bool`
 +* Fix incorrect suggestion for `needless_range_loop`
 +* Fix incorrect suggestion for `use_self`
 +* Fix incorrect suggestion for `while_let_on_iterator`
 +* Clippy is now slightly easier to invoke in non-cargo contexts. See
 +  [#3665][pull3665] for more details.
 +* We now have [improved documentation][adding_lints] on how to add new lints
 +
 +## Rust 1.33
 +
 +Released 2019-02-26
 +
 +[b2601be...1b89724](https://github.com/rust-lang/rust-clippy/compare/b2601be...1b89724)
 +
 +* New lints: [`implicit_return`], [`vec_box`], [`cast_ref_to_mut`]
 +* The `rust-clippy` repository is now part of the `rust-lang` org.
 +* Rename `stutter` to `module_name_repetitions`
 +* Merge `new_without_default_derive` into `new_without_default` lint
 +* Move `large_digit_groups` from `style` group to `pedantic`
 +* Expand `bool_comparison` to check for `<`, `<=`, `>`, `>=`, and `!=`
 +  comparisons against booleans
 +* Expand `no_effect` to detect writes to constants such as `A_CONST.field = 2`
 +* Expand `redundant_clone` to work on struct fields
 +* Expand `suspicious_else_formatting` to detect `if .. {..} {..}`
 +* Expand `use_self` to work on tuple structs and also in local macros
 +* Fix ICE in `result_map_unit_fn` and `option_map_unit_fn`
 +* Fix false positives in `implicit_return`
 +* Fix false positives in `use_self`
 +* Fix false negative in `clone_on_copy`
 +* Fix false positive in `doc_markdown`
 +* Fix false positive in `empty_loop`
 +* Fix false positive in `if_same_then_else`
 +* Fix false positive in `infinite_iter`
 +* Fix false positive in `question_mark`
 +* Fix false positive in `useless_asref`
 +* Fix false positive in `wildcard_dependencies`
 +* Fix false positive in `write_with_newline`
 +* Add suggestion to `explicit_write`
 +* Improve suggestions for `question_mark` lint
 +* Fix incorrect suggestion for `get_unwrap`
 +
 +## Rust 1.32
 +
 +Released 2019-01-17
 +
 +[2e26fdc2...b2601be](https://github.com/rust-lang/rust-clippy/compare/2e26fdc2...b2601be)
 +
 +* New lints: [`slow_vector_initialization`], [`mem_discriminant_non_enum`],
 +  [`redundant_clone`], [`wildcard_dependencies`],
 +  [`into_iter_on_ref`], [`into_iter_on_array`], [`deprecated_cfg_attr`],
 +  [`mem_discriminant_non_enum`], [`cargo_common_metadata`]
 +* Add support for `u128` and `i128` to integer related lints
 +* Add float support to `mistyped_literal_suffixes`
 +* Fix false positives in `use_self`
 +* Fix false positives in `missing_comma`
 +* Fix false positives in `new_ret_no_self`
 +* Fix false positives in `possible_missing_comma`
 +* Fix false positive in `integer_arithmetic` in constant items
 +* Fix false positive in `needless_borrow`
 +* Fix false positive in `out_of_bounds_indexing`
 +* Fix false positive in `new_without_default_derive`
 +* Fix false positive in `string_lit_as_bytes`
 +* Fix false negative in `out_of_bounds_indexing`
 +* Fix false negative in `use_self`. It will now also check existential types
 +* Fix incorrect suggestion for `redundant_closure_call`
 +* Fix various suggestions that contained expanded macros
 +* Fix `bool_comparison` triggering 3 times on on on the same code
 +* Expand `trivially_copy_pass_by_ref` to work on trait methods
 +* Improve suggestion for `needless_range_loop`
 +* Move `needless_pass_by_value` from `pedantic` group to `style`
 +
 +## Rust 1.31
 +
 +Released 2018-12-06
 +
 +[125907ad..2e26fdc2](https://github.com/rust-lang/rust-clippy/compare/125907ad..2e26fdc2)
 +
 +* Clippy has been relicensed under a dual MIT / Apache license.
 +  See [#3093](https://github.com/rust-lang/rust-clippy/issues/3093) for more
 +  information.
 +* With Rust 1.31, Clippy is no longer available via crates.io. The recommended
 +  installation method is via `rustup component add clippy`.
 +* New lints: [`redundant_pattern_matching`], [`unnecessary_filter_map`],
 +  [`unused_unit`], [`map_flatten`], [`mem_replace_option_with_none`]
 +* Fix ICE in `if_let_redundant_pattern_matching`
 +* Fix ICE in `needless_pass_by_value` when encountering a generic function
 +  argument with a lifetime parameter
 +* Fix ICE in `needless_range_loop`
 +* Fix ICE in `single_char_pattern` when encountering a constant value
 +* Fix false positive in `assign_op_pattern`
 +* Fix false positive in `boxed_local` on trait implementations
 +* Fix false positive in `cmp_owned`
 +* Fix false positive in `collapsible_if` when conditionals have comments
 +* Fix false positive in `double_parens`
 +* Fix false positive in `excessive_precision`
 +* Fix false positive in `explicit_counter_loop`
 +* Fix false positive in `fn_to_numeric_cast_with_truncation`
 +* Fix false positive in `map_clone`
 +* Fix false positive in `new_ret_no_self`
 +* Fix false positive in `new_without_default` when `new` is unsafe
 +* Fix false positive in `type_complexity` when using extern types
 +* Fix false positive in `useless_format`
 +* Fix false positive in `wrong_self_convention`
 +* Fix incorrect suggestion for `excessive_precision`
 +* Fix incorrect suggestion for `expect_fun_call`
 +* Fix incorrect suggestion for `get_unwrap`
 +* Fix incorrect suggestion for `useless_format`
 +* `fn_to_numeric_cast_with_truncation` lint can be disabled again
 +* Improve suggestions for `manual_memcpy`
 +* Improve help message for `needless_lifetimes`
 +
 +## Rust 1.30
 +
 +Released 2018-10-25
 +
 +[14207503...125907ad](https://github.com/rust-lang/rust-clippy/compare/14207503...125907ad)
 +
 +* Deprecate `assign_ops` lint
 +* New lints: [`mistyped_literal_suffixes`], [`ptr_offset_with_cast`],
 +  [`needless_collect`], [`copy_iterator`]
 +* `cargo clippy -V` now includes the Clippy commit hash of the Rust
 +  Clippy component
 +* Fix ICE in `implicit_hasher`
 +* Fix ICE when encountering `println!("{}" a);`
 +* Fix ICE when encountering a macro call in match statements
 +* Fix false positive in `default_trait_access`
 +* Fix false positive in `trivially_copy_pass_by_ref`
 +* Fix false positive in `similar_names`
 +* Fix false positive in `redundant_field_name`
 +* Fix false positive in `expect_fun_call`
 +* Fix false negative in `identity_conversion`
 +* Fix false negative in `explicit_counter_loop`
 +* Fix `range_plus_one` suggestion and false negative
 +* `print_with_newline` / `write_with_newline`: don't warn about string with several `\n`s in them
 +* Fix `useless_attribute` to also whitelist `unused_extern_crates`
 +* Fix incorrect suggestion for `single_char_pattern`
 +* Improve suggestion for `identity_conversion` lint
 +* Move `explicit_iter_loop` and `explicit_into_iter_loop` from `style` group to `pedantic`
 +* Move `range_plus_one` and `range_minus_one` from `nursery` group to `complexity`
 +* Move `shadow_unrelated` from `restriction` group to `pedantic`
 +* Move `indexing_slicing` from `pedantic` group to `restriction`
 +
 +## Rust 1.29
 +
 +Released 2018-09-13
 +
 +[v0.0.212...14207503](https://github.com/rust-lang/rust-clippy/compare/v0.0.212...14207503)
 +
 +* :tada: :tada: **Rust 1.29 is the first stable Rust that includes a bundled Clippy** :tada:
 +  :tada:
 +  You can now run `rustup component add clippy-preview` and then `cargo
 +  clippy` to run Clippy. This should put an end to the continuous nightly
 +  upgrades for Clippy users.
 +* Clippy now follows the Rust versioning scheme instead of its own
 +* Fix ICE when encountering a `while let (..) = x.iter()` construct
 +* Fix false positives in `use_self`
 +* Fix false positive in `trivially_copy_pass_by_ref`
 +* Fix false positive in `useless_attribute` lint
 +* Fix false positive in `print_literal`
 +* Fix `use_self` regressions
 +* Improve lint message for `neg_cmp_op_on_partial_ord`
 +* Improve suggestion highlight for `single_char_pattern`
 +* Improve suggestions for various print/write macro lints
 +* Improve website header
 +
 +## 0.0.212 (2018-07-10)
 +* Rustup to *rustc 1.29.0-nightly (e06c87544 2018-07-06)*
 +
 +## 0.0.211
 +* Rustup to *rustc 1.28.0-nightly (e3bf634e0 2018-06-28)*
 +
 +## 0.0.210
 +* Rustup to *rustc 1.28.0-nightly (01cc982e9 2018-06-24)*
 +
 +## 0.0.209
 +* Rustup to *rustc 1.28.0-nightly (523097979 2018-06-18)*
 +
 +## 0.0.208
 +* Rustup to *rustc 1.28.0-nightly (86a8f1a63 2018-06-17)*
 +
 +## 0.0.207
 +* Rustup to *rustc 1.28.0-nightly (2a0062974 2018-06-09)*
 +
 +## 0.0.206
 +* Rustup to *rustc 1.28.0-nightly (5bf68db6e 2018-05-28)*
 +
 +## 0.0.205
 +* Rustup to *rustc 1.28.0-nightly (990d8aa74 2018-05-25)*
 +* Rename `unused_lifetimes` to `extra_unused_lifetimes` because of naming conflict with new rustc lint
 +
 +## 0.0.204
 +* Rustup to *rustc 1.28.0-nightly (71e87be38 2018-05-22)*
 +
 +## 0.0.203
 +* Rustup to *rustc 1.28.0-nightly (a3085756e 2018-05-19)*
 +* Clippy attributes are now of the form `clippy::cyclomatic_complexity` instead of `clippy(cyclomatic_complexity)`
 +
 +## 0.0.202
 +* Rustup to *rustc 1.28.0-nightly (952f344cd 2018-05-18)*
 +
 +## 0.0.201
 +* Rustup to *rustc 1.27.0-nightly (2f2a11dfc 2018-05-16)*
 +
 +## 0.0.200
 +* Rustup to *rustc 1.27.0-nightly (9fae15374 2018-05-13)*
 +
 +## 0.0.199
 +* Rustup to *rustc 1.27.0-nightly (ff2ac35db 2018-05-12)*
 +
 +## 0.0.198
 +* Rustup to *rustc 1.27.0-nightly (acd3871ba 2018-05-10)*
 +
 +## 0.0.197
 +* Rustup to *rustc 1.27.0-nightly (428ea5f6b 2018-05-06)*
 +
 +## 0.0.196
 +* Rustup to *rustc 1.27.0-nightly (e82261dfb 2018-05-03)*
 +
 +## 0.0.195
 +* Rustup to *rustc 1.27.0-nightly (ac3c2288f 2018-04-18)*
 +
 +## 0.0.194
 +* Rustup to *rustc 1.27.0-nightly (bd40cbbe1 2018-04-14)*
 +* New lints: [`cast_ptr_alignment`], [`transmute_ptr_to_ptr`], [`write_literal`], [`write_with_newline`], [`writeln_empty_string`]
 +
 +## 0.0.193
 +* Rustup to *rustc 1.27.0-nightly (eeea94c11 2018-04-06)*
 +
 +## 0.0.192
 +* Rustup to *rustc 1.27.0-nightly (fb44b4c0e 2018-04-04)*
 +* New lint: [`print_literal`]
 +
 +## 0.0.191
 +* Rustup to *rustc 1.26.0-nightly (ae544ee1c 2018-03-29)*
 +* Lint audit; categorize lints as style, correctness, complexity, pedantic, nursery, restriction.
 +
 +## 0.0.190
 +* Fix a bunch of intermittent cargo bugs
 +
 +## 0.0.189
 +* Rustup to *rustc 1.26.0-nightly (5508b2714 2018-03-18)*
 +
 +## 0.0.188
 +* Rustup to *rustc 1.26.0-nightly (392645394 2018-03-15)*
 +* New lint: [`while_immutable_condition`]
 +
 +## 0.0.187
 +* Rustup to *rustc 1.26.0-nightly (322d7f7b9 2018-02-25)*
 +* New lints: [`redundant_field_names`], [`suspicious_arithmetic_impl`], [`suspicious_op_assign_impl`]
 +
 +## 0.0.186
 +* Rustup to *rustc 1.25.0-nightly (0c6091fbd 2018-02-04)*
 +* Various false positive fixes
 +
 +## 0.0.185
 +* Rustup to *rustc 1.25.0-nightly (56733bc9f 2018-02-01)*
 +* New lint: [`question_mark`]
 +
 +## 0.0.184
 +* Rustup to *rustc 1.25.0-nightly (90eb44a58 2018-01-29)*
 +* New lints: [`double_comparisons`], [`empty_line_after_outer_attr`]
 +
 +## 0.0.183
 +* Rustup to *rustc 1.25.0-nightly (21882aad7 2018-01-28)*
 +* New lint: [`misaligned_transmute`]
 +
 +## 0.0.182
 +* Rustup to *rustc 1.25.0-nightly (a0dcecff9 2018-01-24)*
 +* New lint: [`decimal_literal_representation`]
 +
 +## 0.0.181
 +* Rustup to *rustc 1.25.0-nightly (97520ccb1 2018-01-21)*
 +* New lints: [`else_if_without_else`], [`option_option`], [`unit_arg`], [`unnecessary_fold`]
 +* Removed `unit_expr`
 +* Various false positive fixes for [`needless_pass_by_value`]
 +
 +## 0.0.180
 +* Rustup to *rustc 1.25.0-nightly (3f92e8d89 2018-01-14)*
 +
 +## 0.0.179
 +* Rustup to *rustc 1.25.0-nightly (61452e506 2018-01-09)*
 +
 +## 0.0.178
 +* Rustup to *rustc 1.25.0-nightly (ee220daca 2018-01-07)*
 +
 +## 0.0.177
 +* Rustup to *rustc 1.24.0-nightly (250b49205 2017-12-21)*
 +* New lint: [`match_as_ref`]
 +
 +## 0.0.176
 +* Rustup to *rustc 1.24.0-nightly (0077d128d 2017-12-14)*
 +
 +## 0.0.175
 +* Rustup to *rustc 1.24.0-nightly (bb42071f6 2017-12-01)*
 +
 +## 0.0.174
 +* Rustup to *rustc 1.23.0-nightly (63739ab7b 2017-11-21)*
 +
 +## 0.0.173
 +* Rustup to *rustc 1.23.0-nightly (33374fa9d 2017-11-20)*
 +
 +## 0.0.172
 +* Rustup to *rustc 1.23.0-nightly (d0f8e2913 2017-11-16)*
 +
 +## 0.0.171
 +* Rustup to *rustc 1.23.0-nightly (ff0f5de3b 2017-11-14)*
 +
 +## 0.0.170
 +* Rustup to *rustc 1.23.0-nightly (d6b06c63a 2017-11-09)*
 +
 +## 0.0.169
 +* Rustup to *rustc 1.23.0-nightly (3b82e4c74 2017-11-05)*
 +* New lints: [`just_underscores_and_digits`], `result_map_unwrap_or_else`, [`transmute_bytes_to_str`]
 +
 +## 0.0.168
 +* Rustup to *rustc 1.23.0-nightly (f0fe716db 2017-10-30)*
 +
 +## 0.0.167
 +* Rustup to *rustc 1.23.0-nightly (90ef3372e 2017-10-29)*
 +* New lints: `const_static_lifetime`, [`erasing_op`], [`fallible_impl_from`], [`println_empty_string`], [`useless_asref`]
 +
 +## 0.0.166
 +* Rustup to *rustc 1.22.0-nightly (b7960878b 2017-10-18)*
 +* New lints: [`explicit_write`], `identity_conversion`, [`implicit_hasher`], [`invalid_ref`], [`option_map_or_none`],
 +  [`range_minus_one`], [`range_plus_one`], [`transmute_int_to_bool`], [`transmute_int_to_char`],
 +  [`transmute_int_to_float`]
 +
 +## 0.0.165
 +* Rust upgrade to rustc 1.22.0-nightly (0e6f4cf51 2017-09-27)
 +* New lint: [`mut_range_bound`]
 +
 +## 0.0.164
 +* Update to *rustc 1.22.0-nightly (6c476ce46 2017-09-25)*
 +* New lint: [`int_plus_one`]
 +
 +## 0.0.163
 +* Update to *rustc 1.22.0-nightly (14039a42a 2017-09-22)*
 +
 +## 0.0.162
 +* Update to *rustc 1.22.0-nightly (0701b37d9 2017-09-18)*
 +* New lint: [`chars_last_cmp`]
 +* Improved suggestions for [`needless_borrow`], [`ptr_arg`],
 +
 +## 0.0.161
 +* Update to *rustc 1.22.0-nightly (539f2083d 2017-09-13)*
 +
 +## 0.0.160
 +* Update to *rustc 1.22.0-nightly (dd08c3070 2017-09-12)*
 +
 +## 0.0.159
 +* Update to *rustc 1.22.0-nightly (eba374fb2 2017-09-11)*
 +* New lint: [`clone_on_ref_ptr`]
 +
 +## 0.0.158
 +* New lint: [`manual_memcpy`]
 +* [`cast_lossless`] no longer has redundant parentheses in its suggestions
 +* Update to *rustc 1.22.0-nightly (dead08cb3 2017-09-08)*
 +
 +## 0.0.157 - 2017-09-04
 +* Update to *rustc 1.22.0-nightly (981ce7d8d 2017-09-03)*
 +* New lint: `unit_expr`
 +
 +## 0.0.156 - 2017-09-03
 +* Update to *rustc 1.22.0-nightly (744dd6c1d 2017-09-02)*
 +
 +## 0.0.155
 +* Update to *rustc 1.21.0-nightly (c11f689d2 2017-08-29)*
 +* New lint: [`infinite_iter`], [`maybe_infinite_iter`], [`cast_lossless`]
 +
 +## 0.0.154
 +* Update to *rustc 1.21.0-nightly (2c0558f63 2017-08-24)*
 +* Fix [`use_self`] triggering inside derives
 +* Add support for linting an entire workspace with `cargo clippy --all`
 +* New lint: [`naive_bytecount`]
 +
 +## 0.0.153
 +* Update to *rustc 1.21.0-nightly (8c303ed87 2017-08-20)*
 +* New lint: [`use_self`]
 +
 +## 0.0.152
 +* Update to *rustc 1.21.0-nightly (df511d554 2017-08-14)*
 +
 +## 0.0.151
 +* Update to *rustc 1.21.0-nightly (13d94d5fa 2017-08-10)*
 +
 +## 0.0.150
 +* Update to *rustc 1.21.0-nightly (215e0b10e 2017-08-08)*
 +
 +## 0.0.148
 +* Update to *rustc 1.21.0-nightly (37c7d0ebb 2017-07-31)*
 +* New lints: [`unreadable_literal`], [`inconsistent_digit_grouping`], [`large_digit_groups`]
 +
 +## 0.0.147
 +* Update to *rustc 1.21.0-nightly (aac223f4f 2017-07-30)*
 +
 +## 0.0.146
 +* Update to *rustc 1.21.0-nightly (52a330969 2017-07-27)*
 +* Fixes false positives in `inline_always`
 +* Fixes false negatives in `panic_params`
 +
 +## 0.0.145
 +* Update to *rustc 1.20.0-nightly (afe145d22 2017-07-23)*
 +
 +## 0.0.144
 +* Update to *rustc 1.20.0-nightly (086eaa78e 2017-07-15)*
 +
 +## 0.0.143
 +* Update to *rustc 1.20.0-nightly (d84693b93 2017-07-09)*
 +* Fix `cargo clippy` crashing on `dylib` projects
 +* Fix false positives around `nested_while_let` and `never_loop`
 +
 +## 0.0.142
 +* Update to *rustc 1.20.0-nightly (067971139 2017-07-02)*
 +
 +## 0.0.141
 +* Rewrite of the `doc_markdown` lint.
 +* Deprecated [`range_step_by_zero`]
 +* New lint: [`iterator_step_by_zero`]
 +* New lint: [`needless_borrowed_reference`]
 +* Update to *rustc 1.20.0-nightly (69c65d296 2017-06-28)*
 +
 +## 0.0.140 - 2017-06-16
 +* Update to *rustc 1.19.0-nightly (258ae6dd9 2017-06-15)*
 +
 +## 0.0.139 — 2017-06-10
 +* Update to *rustc 1.19.0-nightly (4bf5c99af 2017-06-10)*
 +* Fix bugs with for loop desugaring
 +* Check for [`AsRef`]/[`AsMut`] arguments in [`wrong_self_convention`]
 +
 +## 0.0.138 — 2017-06-05
 +* Update to *rustc 1.19.0-nightly (0418fa9d3 2017-06-04)*
 +
 +## 0.0.137 — 2017-06-05
 +* Update to *rustc 1.19.0-nightly (6684d176c 2017-06-03)*
 +
 +## 0.0.136 — 2017—05—26
 +* Update to *rustc 1.19.0-nightly (557967766 2017-05-26)*
 +
 +## 0.0.135 — 2017—05—24
 +* Update to *rustc 1.19.0-nightly (5b13bff52 2017-05-23)*
 +
 +## 0.0.134 — 2017—05—19
 +* Update to *rustc 1.19.0-nightly (0ed1ec9f9 2017-05-18)*
 +
 +## 0.0.133 — 2017—05—14
 +* Update to *rustc 1.19.0-nightly (826d8f385 2017-05-13)*
 +
 +## 0.0.132 — 2017—05—05
 +* Fix various bugs and some ices
 +
 +## 0.0.131 — 2017—05—04
 +* Update to *rustc 1.19.0-nightly (2d4ed8e0c 2017-05-03)*
 +
 +## 0.0.130 — 2017—05—03
 +* Update to *rustc 1.19.0-nightly (6a5fc9eec 2017-05-02)*
 +
 +## 0.0.129 — 2017-05-01
 +* Update to *rustc 1.19.0-nightly (06fb4d256 2017-04-30)*
 +
 +## 0.0.128 — 2017-04-28
 +* Update to *rustc 1.18.0-nightly (94e884b63 2017-04-27)*
 +
 +## 0.0.127 — 2017-04-27
 +* Update to *rustc 1.18.0-nightly (036983201 2017-04-26)*
 +* New lint: [`needless_continue`]
 +
 +## 0.0.126 — 2017-04-24
 +* Update to *rustc 1.18.0-nightly (2bd4b5c6d 2017-04-23)*
 +
 +## 0.0.125 — 2017-04-19
 +* Update to *rustc 1.18.0-nightly (9f2abadca 2017-04-18)*
 +
 +## 0.0.124 — 2017-04-16
 +* Update to *rustc 1.18.0-nightly (d5cf1cb64 2017-04-15)*
 +
 +## 0.0.123 — 2017-04-07
 +* Fix various false positives
 +
 +## 0.0.122 — 2017-04-07
 +* Rustup to *rustc 1.18.0-nightly (91ae22a01 2017-04-05)*
 +* New lint: [`op_ref`]
 +
 +## 0.0.121 — 2017-03-21
 +* Rustup to *rustc 1.17.0-nightly (134c4a0f0 2017-03-20)*
 +
 +## 0.0.120 — 2017-03-17
 +* Rustup to *rustc 1.17.0-nightly (0aeb9c129 2017-03-15)*
 +
 +## 0.0.119 — 2017-03-13
 +* Rustup to *rustc 1.17.0-nightly (824c9ebbd 2017-03-12)*
 +
 +## 0.0.118 — 2017-03-05
 +* Rustup to *rustc 1.17.0-nightly (b1e31766d 2017-03-03)*
 +
 +## 0.0.117 — 2017-03-01
 +* Rustup to *rustc 1.17.0-nightly (be760566c 2017-02-28)*
 +
 +## 0.0.116 — 2017-02-28
 +* Fix `cargo clippy` on 64 bit windows systems
 +
 +## 0.0.115 — 2017-02-27
 +* Rustup to *rustc 1.17.0-nightly (60a0edc6c 2017-02-26)*
 +* New lints: [`zero_ptr`], [`never_loop`], [`mut_from_ref`]
 +
 +## 0.0.114 — 2017-02-08
 +* Rustup to *rustc 1.17.0-nightly (c49d10207 2017-02-07)*
 +* Tests are now ui tests (testing the exact output of rustc)
 +
 +## 0.0.113 — 2017-02-04
 +* Rustup to *rustc 1.16.0-nightly (eedaa94e3 2017-02-02)*
 +* New lint: [`large_enum_variant`]
 +* `explicit_into_iter_loop` provides suggestions
 +
 +## 0.0.112 — 2017-01-27
 +* Rustup to *rustc 1.16.0-nightly (df8debf6d 2017-01-25)*
 +
 +## 0.0.111 — 2017-01-21
 +* Rustup to *rustc 1.16.0-nightly (a52da95ce 2017-01-20)*
 +
 +## 0.0.110 — 2017-01-20
 +* Add badges and categories to `Cargo.toml`
 +
 +## 0.0.109 — 2017-01-19
 +* Update to *rustc 1.16.0-nightly (c07a6ae77 2017-01-17)*
 +
 +## 0.0.108 — 2017-01-12
 +* Update to *rustc 1.16.0-nightly (2782e8f8f 2017-01-12)*
 +
 +## 0.0.107 — 2017-01-11
 +* Update regex dependency
 +* Fix FP when matching `&&mut` by `&ref`
 +* Reintroduce `for (_, x) in &mut hash_map` -> `for x in hash_map.values_mut()`
 +* New lints: [`unused_io_amount`], [`forget_ref`], [`short_circuit_statement`]
 +
 +## 0.0.106 — 2017-01-04
 +* Fix FP introduced by rustup in [`wrong_self_convention`]
 +
 +## 0.0.105 — 2017-01-04
 +* Update to *rustc 1.16.0-nightly (468227129 2017-01-03)*
 +* New lints: [`deref_addrof`], [`double_parens`], [`pub_enum_variant_names`]
 +* Fix suggestion in [`new_without_default`]
 +* FP fix in [`absurd_extreme_comparisons`]
 +
 +## 0.0.104 — 2016-12-15
 +* Update to *rustc 1.15.0-nightly (8f02c429a 2016-12-15)*
 +
 +## 0.0.103 — 2016-11-25
 +* Update to *rustc 1.15.0-nightly (d5814b03e 2016-11-23)*
 +
 +## 0.0.102 — 2016-11-24
 +* Update to *rustc 1.15.0-nightly (3bf2be9ce 2016-11-22)*
 +
 +## 0.0.101 — 2016-11-23
 +* Update to *rustc 1.15.0-nightly (7b3eeea22 2016-11-21)*
 +* New lint: [`string_extend_chars`]
 +
 +## 0.0.100 — 2016-11-20
 +* Update to *rustc 1.15.0-nightly (ac635aa95 2016-11-18)*
 +
 +## 0.0.99 — 2016-11-18
 +* Update to rustc 1.15.0-nightly (0ed951993 2016-11-14)
 +* New lint: [`get_unwrap`]
 +
 +## 0.0.98 — 2016-11-08
 +* Fixes an issue due to a change in how cargo handles `--sysroot`, which broke `cargo clippy`
 +
 +## 0.0.97 — 2016-11-03
 +* For convenience, `cargo clippy` defines a `cargo-clippy` feature. This was
 +  previously added for a short time under the name `clippy` but removed for
 +  compatibility.
 +* `cargo clippy --help` is more helping (and less helpful :smile:)
 +* Rustup to *rustc 1.14.0-nightly (5665bdf3e 2016-11-02)*
 +* New lints: [`if_let_redundant_pattern_matching`], [`partialeq_ne_impl`]
 +
 +## 0.0.96 — 2016-10-22
 +* Rustup to *rustc 1.14.0-nightly (f09420685 2016-10-20)*
 +* New lint: [`iter_skip_next`]
 +
 +## 0.0.95 — 2016-10-06
 +* Rustup to *rustc 1.14.0-nightly (3210fd5c2 2016-10-05)*
 +
 +## 0.0.94 — 2016-10-04
 +* Fixes bustage on Windows due to forbidden directory name
 +
 +## 0.0.93 — 2016-10-03
 +* Rustup to *rustc 1.14.0-nightly (144af3e97 2016-10-02)*
 +* `option_map_unwrap_or` and `option_map_unwrap_or_else` are now
 +  allowed by default.
 +* New lint: [`explicit_into_iter_loop`]
 +
 +## 0.0.92 — 2016-09-30
 +* Rustup to *rustc 1.14.0-nightly (289f3a4ca 2016-09-29)*
 +
 +## 0.0.91 — 2016-09-28
 +* Rustup to *rustc 1.13.0-nightly (d0623cf7b 2016-09-26)*
 +
 +## 0.0.90 — 2016-09-09
 +* Rustup to *rustc 1.13.0-nightly (f1f40f850 2016-09-09)*
 +
 +## 0.0.89 — 2016-09-06
 +* Rustup to *rustc 1.13.0-nightly (cbe4de78e 2016-09-05)*
 +
 +## 0.0.88 — 2016-09-04
 +* Rustup to *rustc 1.13.0-nightly (70598e04f 2016-09-03)*
 +* The following lints are not new but were only usable through the `clippy`
 +  lint groups: [`filter_next`], `for_loop_over_option`,
 +  `for_loop_over_result` and [`match_overlapping_arm`]. You should now be
 +  able to `#[allow/deny]` them individually and they are available directly
 +  through `cargo clippy`.
 +
 +## 0.0.87 — 2016-08-31
 +* Rustup to *rustc 1.13.0-nightly (eac41469d 2016-08-30)*
 +* New lints: [`builtin_type_shadow`]
 +* Fix FP in [`zero_prefixed_literal`] and `0b`/`0o`
 +
 +## 0.0.86 — 2016-08-28
 +* Rustup to *rustc 1.13.0-nightly (a23064af5 2016-08-27)*
 +* New lints: [`missing_docs_in_private_items`], [`zero_prefixed_literal`]
 +
 +## 0.0.85 — 2016-08-19
 +* Fix ICE with [`useless_attribute`]
 +* [`useless_attribute`] ignores `unused_imports` on `use` statements
 +
 +## 0.0.84 — 2016-08-18
 +* Rustup to *rustc 1.13.0-nightly (aef6971ca 2016-08-17)*
 +
 +## 0.0.83 — 2016-08-17
 +* Rustup to *rustc 1.12.0-nightly (1bf5fa326 2016-08-16)*
 +* New lints: [`print_with_newline`], [`useless_attribute`]
 +
 +## 0.0.82 — 2016-08-17
 +* Rustup to *rustc 1.12.0-nightly (197be89f3 2016-08-15)*
 +* New lint: [`module_inception`]
 +
 +## 0.0.81 — 2016-08-14
 +* Rustup to *rustc 1.12.0-nightly (1deb02ea6 2016-08-12)*
 +* New lints: [`eval_order_dependence`], [`mixed_case_hex_literals`], [`unseparated_literal_suffix`]
 +* False positive fix in [`too_many_arguments`]
 +* Addition of functionality to [`needless_borrow`]
 +* Suggestions for [`clone_on_copy`]
 +* Bug fix in [`wrong_self_convention`]
 +* Doc improvements
 +
 +## 0.0.80 — 2016-07-31
 +* Rustup to *rustc 1.12.0-nightly (1225e122f 2016-07-30)*
 +* New lints: [`misrefactored_assign_op`], [`serde_api_misuse`]
 +
 +## 0.0.79 — 2016-07-10
 +* Rustup to *rustc 1.12.0-nightly (f93aaf84c 2016-07-09)*
 +* Major suggestions refactoring
 +
 +## 0.0.78 — 2016-07-02
 +* Rustup to *rustc 1.11.0-nightly (01411937f 2016-07-01)*
 +* New lints: [`wrong_transmute`], [`double_neg`], [`filter_map`]
 +* For compatibility, `cargo clippy` does not defines the `clippy` feature
 +  introduced in 0.0.76 anymore
 +* [`collapsible_if`] now considers `if let`
 +
 +## 0.0.77 — 2016-06-21
 +* Rustup to *rustc 1.11.0-nightly (5522e678b 2016-06-20)*
 +* New lints: `stutter` and [`iter_nth`]
 +
 +## 0.0.76 — 2016-06-10
 +* Rustup to *rustc 1.11.0-nightly (7d2f75a95 2016-06-09)*
 +* `cargo clippy` now automatically defines the `clippy` feature
 +* New lint: [`not_unsafe_ptr_arg_deref`]
 +
 +## 0.0.75 — 2016-06-08
 +* Rustup to *rustc 1.11.0-nightly (763f9234b 2016-06-06)*
 +
 +## 0.0.74 — 2016-06-07
 +* Fix bug with `cargo-clippy` JSON parsing
 +* Add the `CLIPPY_DISABLE_DOCS_LINKS` environment variable to deactivate the
 +  “for further information visit *lint-link*” message.
 +
 +## 0.0.73 — 2016-06-05
 +* Fix false positives in [`useless_let_if_seq`]
 +
 +## 0.0.72 — 2016-06-04
 +* Fix false positives in [`useless_let_if_seq`]
 +
 +## 0.0.71 — 2016-05-31
 +* Rustup to *rustc 1.11.0-nightly (a967611d8 2016-05-30)*
 +* New lint: [`useless_let_if_seq`]
 +
 +## 0.0.70 — 2016-05-28
 +* Rustup to *rustc 1.10.0-nightly (7bddce693 2016-05-27)*
 +* [`invalid_regex`] and [`trivial_regex`] can now warn on `RegexSet::new`,
 +  `RegexBuilder::new` and byte regexes
 +
 +## 0.0.69 — 2016-05-20
 +* Rustup to *rustc 1.10.0-nightly (476fe6eef 2016-05-21)*
 +* [`used_underscore_binding`] has been made `Allow` temporarily
 +
 +## 0.0.68 — 2016-05-17
 +* Rustup to *rustc 1.10.0-nightly (cd6a40017 2016-05-16)*
 +* New lint: [`unnecessary_operation`]
 +
 +## 0.0.67 — 2016-05-12
 +* Rustup to *rustc 1.10.0-nightly (22ac88f1a 2016-05-11)*
 +
 +## 0.0.66 — 2016-05-11
 +* New `cargo clippy` subcommand
 +* New lints: [`assign_op_pattern`], [`assign_ops`], [`needless_borrow`]
 +
 +## 0.0.65 — 2016-05-08
 +* Rustup to *rustc 1.10.0-nightly (62e2b2fb7 2016-05-06)*
 +* New lints: [`float_arithmetic`], [`integer_arithmetic`]
 +
 +## 0.0.64 — 2016-04-26
 +* Rustup to *rustc 1.10.0-nightly (645dd013a 2016-04-24)*
 +* New lints: [`temporary_cstring_as_ptr`], [`unsafe_removed_from_name`], and [`mem_forget`]
 +
 +## 0.0.63 — 2016-04-08
 +* Rustup to *rustc 1.9.0-nightly (7979dd608 2016-04-07)*
 +
 +## 0.0.62 — 2016-04-07
 +* Rustup to *rustc 1.9.0-nightly (bf5da36f1 2016-04-06)*
 +
 +## 0.0.61 — 2016-04-03
 +* Rustup to *rustc 1.9.0-nightly (5ab11d72c 2016-04-02)*
 +* New lint: [`invalid_upcast_comparisons`]
 +
 +## 0.0.60 — 2016-04-01
 +* Rustup to *rustc 1.9.0-nightly (e1195c24b 2016-03-31)*
 +
 +## 0.0.59 — 2016-03-31
 +* Rustup to *rustc 1.9.0-nightly (30a3849f2 2016-03-30)*
 +* New lints: [`logic_bug`], [`nonminimal_bool`]
 +* Fixed: [`match_same_arms`] now ignores arms with guards
 +* Improved: [`useless_vec`] now warns on `for … in vec![…]`
 +
 +## 0.0.58 — 2016-03-27
 +* Rustup to *rustc 1.9.0-nightly (d5a91e695 2016-03-26)*
 +* New lint: [`doc_markdown`]
 +
 +## 0.0.57 — 2016-03-27
 +* Update to *rustc 1.9.0-nightly (a1e29daf1 2016-03-25)*
 +* Deprecated lints: [`str_to_string`], [`string_to_string`], [`unstable_as_slice`], [`unstable_as_mut_slice`]
 +* New lint: [`crosspointer_transmute`]
 +
 +## 0.0.56 — 2016-03-23
 +* Update to *rustc 1.9.0-nightly (0dcc413e4 2016-03-22)*
 +* New lints: [`many_single_char_names`] and [`similar_names`]
 +
 +## 0.0.55 — 2016-03-21
 +* Update to *rustc 1.9.0-nightly (02310fd31 2016-03-19)*
 +
 +## 0.0.54 — 2016-03-16
 +* Update to *rustc 1.9.0-nightly (c66d2380a 2016-03-15)*
 +
 +## 0.0.53 — 2016-03-15
 +* Add a [configuration file]
 +
 +## ~~0.0.52~~
 +
 +## 0.0.51 — 2016-03-13
 +* Add `str` to types considered by [`len_zero`]
 +* New lints: [`indexing_slicing`]
 +
 +## 0.0.50 — 2016-03-11
 +* Update to *rustc 1.9.0-nightly (c9629d61c 2016-03-10)*
 +
 +## 0.0.49 — 2016-03-09
 +* Update to *rustc 1.9.0-nightly (eabfc160f 2016-03-08)*
 +* New lints: [`overflow_check_conditional`], [`unused_label`], [`new_without_default`]
 +
 +## 0.0.48 — 2016-03-07
 +* Fixed: ICE in [`needless_range_loop`] with globals
 +
 +## 0.0.47 — 2016-03-07
 +* Update to *rustc 1.9.0-nightly (998a6720b 2016-03-07)*
 +* New lint: [`redundant_closure_call`]
 +
 +[`AsMut`]: https://doc.rust-lang.org/std/convert/trait.AsMut.html
 +[`AsRef`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html
 +[configuration file]: ./rust-clippy#configuration
 +[pull3665]: https://github.com/rust-lang/rust-clippy/pull/3665
 +[adding_lints]: https://github.com/rust-lang/rust-clippy/blob/master/doc/adding_lints.md
 +
 +<!-- lint disable no-unused-definitions -->
 +<!-- begin autogenerated links to lint list -->
 +[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
 +[`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
 +[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
 +[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
 +[`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
 +[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
 +[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
 +[`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
 +[`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions
 +[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
 +[`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_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
 +[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow
 +[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
 +[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
 +[`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
 +[`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
 +[`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
 +[`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
 +[`cognitive_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity
 +[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
 +[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
 +[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
 +[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
 +[`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_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_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access
 +[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_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
 +[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 +[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
 +[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
 +[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
 +[`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
 +[`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_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_ref
 +[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument
 +[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec
 +[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else
 +[`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum
 +[`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
 +[`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
 +[`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op
 +[`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence
 +[`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision
 +[`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_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
 +[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
 +[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from
 +[`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_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
 +[`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
 +[`fn_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_address_comparisons
 +[`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_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_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles
 +[`forget_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_copy
 +[`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref
 +[`future_not_send`]: https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send
 +[`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
 +[`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
 +[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond
 +[`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_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub
 +[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
 +[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
 +[`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
 +[`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
 +[`infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_iter
 +[`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
 +[`inline_always`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_always
 +[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body
 +[`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
 +[`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
 +[`invalid_atomic_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering
 +[`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
 +[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
 +[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect
 +[`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_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_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
 +[`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero
 +[`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_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
 +[`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_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_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
 +[`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist
 +[`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_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_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
 +[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
 +[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
 +[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic
 +[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap
 +[`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names
 +[`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone
 +[`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
 +[`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_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or
 +[`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_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_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
 +[`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_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_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_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os
 +[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
 +[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
 +[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
 +[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
 +[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
 +[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
 +[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
 +[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
 +[`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
 +[`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
 +[`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_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_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool
 +[`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_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_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
 +[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
 +[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
 +[`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
 +[`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
 +[`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
 +[`no_effect`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect
 +[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal
 +[`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool
 +[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
 +[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
 +[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
 +[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
 +[`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_if_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else
 +[`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_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_option
 +[`or_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
 +[`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
 +[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic
 +[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
 +[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
 +[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
 +[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
 +[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
 +[`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma
 +[`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence
 +[`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal
 +[`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_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
 +[`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark
 +[`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
 +[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
 +[`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_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
 +[`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_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
 +[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
 +[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
 +[`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once
 +[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
 +[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs
 +[`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
 +[`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
 +[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
 +[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
 +[`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
 +[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names
 +[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
 +[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports
 +[`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
 +[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next
 +[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
 +[`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_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
 +[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
 +[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools
 +[`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_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_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting
 +[`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
 +[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some
 +[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
 +[`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
 +[`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_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
 +[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmuting_null
 +[`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
 +[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
 +[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
 +[`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
 +[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init
 +[`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_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_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
 +[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
 +[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
 +[`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_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by
 +[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
 +[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_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_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
 +[`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_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
 +[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
 +[`unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used
 +[`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
 +[`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_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_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_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
 +[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons
 +[`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
 +[`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_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space
 +[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 +<!-- end autogenerated links to lint list -->
index 222b81023a7705aa87847ea6fd913d50a380036c,0000000000000000000000000000000000000000..a2984d73641694b500415990e41c25b9b57fbeda
mode 100644,000000..100644
--- /dev/null
@@@ -1,193 -1,0 +1,191 @@@
- Since this is a tool for helping the developer of a library or application
- write better code, it is recommended not to include Clippy as a hard dependency.
- Options include using it as an optional dependency, as a cargo subcommand, or
- as an included feature during build. These options are detailed below.
 +# Clippy
 +
 +[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test%22+event%3Apush+branch%3Aauto)
 +[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)
 +
 +A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
 +
 +[There are over 350 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 +
 +We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
 +
 +* `clippy::all` (everything that is on by default: all the categories below except for `nursery`, `pedantic`, and `cargo`)
 +* `clippy::correctness` (code that is just **outright wrong** or **very very useless**, causes hard errors by default)
 +* `clippy::style` (code that should be written in a more idiomatic way)
 +* `clippy::complexity` (code that does something simple but in a complex way)
 +* `clippy::perf` (code that can be written in a faster way)
 +* `clippy::pedantic` (lints which are rather strict, off by default)
 +* `clippy::nursery` (new lints that aren't quite ready yet, off by default)
 +* `clippy::cargo` (checks against the cargo manifest, off by default)
 +
 +More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!
 +
 +Only the following of those categories are enabled by default:
 +
 +* `clippy::style`
 +* `clippy::correctness`
 +* `clippy::complexity`
 +* `clippy::perf`
 +
 +Other categories need to be enabled in order for their lints to be executed.
 +
 +The [lint list](https://rust-lang.github.io/rust-clippy/master/index.html) also contains "restriction lints", which are
 +for things which are usually not considered "bad", but may be useful to turn on in specific cases. These should be used
 +very selectively, if at all.
 +
 +Table of contents:
 +
 +*   [Usage instructions](#usage)
 +*   [Configuration](#configuration)
 +*   [Contributing](#contributing)
 +*   [License](#license)
 +
 +## Usage
 +
++Below are instructions on how to use Clippy as a subcommand, compiled from source
++or in Travis CI.
 +
 +### As a cargo subcommand (`cargo clippy`)
 +
 +One way to use Clippy is by installing Clippy through rustup as a cargo
 +subcommand.
 +
 +#### Step 1: Install rustup
 +
 +You can install [rustup](https://rustup.rs/) on supported platforms. This will help
 +us install Clippy and its dependencies.
 +
 +If you already have rustup installed, update to ensure you have the latest
 +rustup and compiler:
 +
 +```terminal
 +rustup update
 +```
 +
 +#### Step 2: Install Clippy
 +
 +Once you have rustup and the latest stable release (at least Rust 1.29) installed, run the following command:
 +
 +```terminal
 +rustup component add clippy
 +```
 +If it says that it can't find the `clippy` component, please run `rustup self update`.
 +
 +#### Step 3: Run Clippy
 +
 +Now you can run Clippy by invoking the following command:
 +
 +```terminal
 +cargo clippy
 +```
 +
 +#### Automatically applying Clippy suggestions
 +
 +Clippy can automatically apply some lint suggestions.
 +Note that this is still experimental and only supported on the nightly channel:
 +
 +```terminal
 +cargo clippy --fix -Z unstable-options
 +```
 +
 +### Running Clippy from the command line without installing it
 +
 +To have cargo compile your crate with Clippy without Clippy installation
 +in your code, you can use:
 +
 +```terminal
 +cargo run --bin cargo-clippy --manifest-path=path_to_clippys_Cargo.toml
 +```
 +
 +*Note:* Be sure that Clippy was compiled with the same version of rustc that cargo invokes here!
 +
 +### Travis CI
 +
 +You can add Clippy to Travis CI in the same way you use it locally:
 +
 +```yml
 +language: rust
 +rust:
 +  - stable
 +  - beta
 +before_script:
 +  - rustup component add clippy
 +script:
 +  - cargo clippy
 +  # if you want the build job to fail when encountering warnings, use
 +  - cargo clippy -- -D warnings
 +  # in order to also check tests and non-default crate features, use
 +  - cargo clippy --all-targets --all-features -- -D warnings
 +  - cargo test
 +  # etc.
 +```
 +
 +If you are on nightly, It might happen that Clippy is not available for a certain nightly release.
 +In this case you can try to conditionally install Clippy from the Git repo.
 +
 +```yaml
 +language: rust
 +rust:
 +  - nightly
 +before_script:
 +   - rustup component add clippy --toolchain=nightly || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
 +   # etc.
 +```
 +
 +Note that adding `-D warnings` will cause your build to fail if **any** warnings are found in your code.
 +That includes warnings found by rustc (e.g. `dead_code`, etc.). If you want to avoid this and only cause
 +an error for Clippy warnings, use `#![deny(clippy::all)]` in your code or `-D clippy::all` on the command
 +line. (You can swap `clippy::all` with the specific lint category you are targeting.)
 +
 +## Configuration
 +
 +Some lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`. It contains a basic `variable =
 +value` mapping eg.
 +
 +```toml
 +blacklisted-names = ["toto", "tata", "titi"]
 +cognitive-complexity-threshold = 30
 +```
 +
 +See the [list of lints](https://rust-lang.github.io/rust-clippy/master/index.html) for more information about which
 +lints can be configured and the meaning of the variables.
 +
 +To deactivate the “for further information visit *lint-link*” message you can
 +define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable.
 +
 +### Allowing/denying lints
 +
 +You can add options to your code to `allow`/`warn`/`deny` Clippy lints:
 +
 +*   the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy::all)]`)
 +
 +*   all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![deny(clippy::all)]`,
 +    `#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
 +    lints prone to false positives.
 +
 +*   only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc.)
 +
 +*   `allow`/`warn`/`deny` can be limited to a single function or module using `#[allow(...)]`, etc.
 +
 +Note: `deny` produces errors instead of warnings.
 +
 +If you do not want to include your lint levels in your code, you can globally enable/disable lints by passing extra
 +flags to Clippy during the run: `cargo clippy -- -A clippy::lint_name` will run Clippy with `lint_name` disabled and
 +`cargo clippy -- -W clippy::lint_name` will run it with that enabled. This also works with lint groups. For example you
 +can run Clippy with warnings for all lints enabled: `cargo clippy -- -W clippy::pedantic`
 +If you care only about a single lint, you can allow all others and then explicitly reenable
 +the lint(s) you are interested in: `cargo clippy -- -Aclippy::all -Wclippy::useless_format -Wclippy::...`
 +
 +## Contributing
 +
 +If you want to contribute to Clippy, you can find more information in [CONTRIBUTING.md](https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md).
 +
 +## License
 +
 +Copyright 2014-2020 The Rust Project Developers
 +
 +Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 +[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license
 +<LICENSE-MIT or [https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)>, at your
 +option. Files in the project may not be
 +copied, modified, or distributed except according to those terms.
index 818d8188a787a6608f3071810b539010fea3ffcb,0000000000000000000000000000000000000000..c17a0e8333058fe91497dc9d67f3c0434481fe38
mode 100644,000000..100644
--- /dev/null
@@@ -1,165 -1,0 +1,165 @@@
-     "associated-constants `MIN`/`MAX` of integers are prefered to `{min,max}_value()` and module constants"
 +macro_rules! declare_deprecated_lint {
 +    (pub $name: ident, $_reason: expr) => {
 +        declare_lint!(pub $name, Allow, "deprecated lint")
 +    }
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `assert!(a == b)` and recommend
 +    /// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.
 +    pub SHOULD_ASSERT_EQ,
 +    "`assert!()` will be more flexible with RFC 2011"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `Vec::extend`, which was slower than
 +    /// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true.
 +    pub EXTEND_FROM_SLICE,
 +    "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** `Range::step_by(0)` used to be linted since it's
 +    /// an infinite iterator, which is better expressed by `iter::repeat`,
 +    /// but the method has been removed for `Iterator::step_by` which panics
 +    /// if given a zero
 +    pub RANGE_STEP_BY_ZERO,
 +    "`iterator.step_by(0)` panics nowadays"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `Vec::as_slice`, which was unstable with good
 +    /// stable alternatives. `Vec::as_slice` has now been stabilized.
 +    pub UNSTABLE_AS_SLICE,
 +    "`Vec::as_slice` has been stabilized in 1.7"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `Vec::as_mut_slice`, which was unstable with good
 +    /// stable alternatives. `Vec::as_mut_slice` has now been stabilized.
 +    pub UNSTABLE_AS_MUT_SLICE,
 +    "`Vec::as_mut_slice` has been stabilized in 1.7"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `.to_string()` method calls on values
 +    /// of type `&str`. This is not unidiomatic and with specialization coming, `to_string` could be
 +    /// specialized to be as efficient as `to_owned`.
 +    pub STR_TO_STRING,
 +    "using `str::to_string` is common even today and specialization will likely happen soon"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This used to check for `.to_string()` method calls on values
 +    /// of type `String`. This is not unidiomatic and with specialization coming, `to_string` could be
 +    /// specialized to be as efficient as `clone`.
 +    pub STRING_TO_STRING,
 +    "using `string::to_string` is common even today and specialization will likely happen soon"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint should never have applied to non-pointer types, as transmuting
 +    /// between non-pointer types of differing alignment is well-defined behavior (it's semantically
 +    /// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
 +    /// cast_ptr_alignment and transmute_ptr_to_ptr.
 +    pub MISALIGNED_TRANSMUTE,
 +    "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint is too subjective, not having a good reason for being in clippy.
 +    /// Additionally, compound assignment operators may be overloaded separately from their non-assigning
 +    /// counterparts, so this lint may suggest a change in behavior or the code may not compile.
 +    pub ASSIGN_OPS,
 +    "using compound assignment operators (e.g., `+=`) is harmless"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** The original rule will only lint for `if let`. After
 +    /// making it support to lint `match`, naming as `if let` is not suitable for it.
 +    /// So, this lint is deprecated.
 +    pub IF_LET_REDUNDANT_PATTERN_MATCHING,
 +    "this lint has been changed to redundant_pattern_matching"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint used to suggest replacing `let mut vec =
 +    /// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The
 +    /// replacement has very different performance characteristics so the lint is
 +    /// deprecated.
 +    pub UNSAFE_VECTOR_INITIALIZATION,
 +    "the replacement suggested by this lint had substantially different behavior"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint has been superseded by the warn-by-default
 +    /// `invalid_value` rustc lint.
 +    pub INVALID_REF,
 +    "superseded by rustc lint `invalid_value`"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint has been superseded by #[must_use] in rustc.
 +    pub UNUSED_COLLECT,
 +    "`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint has been uplifted to rustc and is now called
 +    /// `array_into_iter`.
 +    pub INTO_ITER_ON_ARRAY,
 +    "this lint has been uplifted to rustc and is now called `array_into_iter`"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** This lint has been uplifted to rustc and is now called
 +    /// `unused_labels`.
 +    pub UNUSED_LABEL,
 +    "this lint has been uplifted to rustc and is now called `unused_labels`"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** Associated-constants are now preferred.
 +    pub REPLACE_CONSTS,
++    "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants"
 +}
 +
 +declare_deprecated_lint! {
 +    /// **What it does:** Nothing. This lint has been deprecated.
 +    ///
 +    /// **Deprecation reason:** The regex! macro does not exist anymore.
 +    pub REGEX_MACRO,
 +    "the regex! macro has been removed from the regex crate in 2018"
 +}
index 102cf597d22e368ee04d86b01ffd5a57de24cbd0,0000000000000000000000000000000000000000..b5fb51af1c7f31f6192ac279d107f274cf5156bc
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,109 @@@
-     /// **Why is this bad?** Derefencing by `&*x` or `&mut *x` is clearer and more concise,
 +use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg};
 +use if_chain::if_chain;
 +use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX, PREC_PREFIX};
 +use rustc_errors::Applicability;
 +use rustc_hir::{Expr, ExprKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for explicit `deref()` or `deref_mut()` method calls.
 +    ///
++    /// **Why is this bad?** Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
 +    /// when not part of a method chain.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// use std::ops::Deref;
 +    /// let a: &mut String = &mut String::from("foo");
 +    /// let b: &str = a.deref();
 +    /// ```
 +    /// Could be written as:
 +    /// ```rust
 +    /// let a: &mut String = &mut String::from("foo");
 +    /// let b = &*a;
 +    /// ```
 +    ///
 +    /// This lint excludes
 +    /// ```rust,ignore
 +    /// let _ = d.unwrap().deref();
 +    /// ```
 +    pub EXPLICIT_DEREF_METHODS,
 +    pedantic,
 +    "Explicit use of deref or deref_mut method while not in a method chain."
 +}
 +
 +declare_lint_pass!(Dereferencing => [
 +    EXPLICIT_DEREF_METHODS
 +]);
 +
 +impl<'tcx> LateLintPass<'tcx> for Dereferencing {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if_chain! {
 +            if !expr.span.from_expansion();
 +            if let ExprKind::MethodCall(ref method_name, _, ref args, _) = &expr.kind;
 +            if args.len() == 1;
 +
 +            then {
 +                if let Some(parent_expr) = get_parent_expr(cx, expr) {
 +                    // Check if we have the whole call chain here
 +                    if let ExprKind::MethodCall(..) = parent_expr.kind {
 +                        return;
 +                    }
 +                    // Check for Expr that we don't want to be linted
 +                    let precedence = parent_expr.precedence();
 +                    match precedence {
 +                        // Lint a Call is ok though
 +                        ExprPrecedence::Call | ExprPrecedence::AddrOf => (),
 +                        _ => {
 +                            if precedence.order() >= PREC_PREFIX && precedence.order() <= PREC_POSTFIX {
 +                                return;
 +                            }
 +                        }
 +                    }
 +                }
 +                let name = method_name.ident.as_str();
 +                lint_deref(cx, &*name, &args[0], args[0].span, expr.span);
 +            }
 +        }
 +    }
 +}
 +
 +fn lint_deref(cx: &LateContext<'_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) {
 +    match method_name {
 +        "deref" => {
 +            let impls_deref_trait = cx.tcx.lang_items().deref_trait().map_or(false, |id| {
 +                implements_trait(cx, cx.typeck_results().expr_ty(&call_expr), id, &[])
 +            });
 +            if impls_deref_trait {
 +                span_lint_and_sugg(
 +                    cx,
 +                    EXPLICIT_DEREF_METHODS,
 +                    expr_span,
 +                    "explicit deref method call",
 +                    "try this",
 +                    format!("&*{}", &snippet(cx, var_span, "..")),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +        },
 +        "deref_mut" => {
 +            let impls_deref_mut_trait = cx.tcx.lang_items().deref_mut_trait().map_or(false, |id| {
 +                implements_trait(cx, cx.typeck_results().expr_ty(&call_expr), id, &[])
 +            });
 +            if impls_deref_mut_trait {
 +                span_lint_and_sugg(
 +                    cx,
 +                    EXPLICIT_DEREF_METHODS,
 +                    expr_span,
 +                    "explicit deref_mut method call",
 +                    "try this",
 +                    format!("&mut *{}", &snippet(cx, var_span, "..")),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +        },
 +        _ => (),
 +    }
 +}
index bd7ca03883945023458fc4ed6328e3ad14bc6d31,0000000000000000000000000000000000000000..9fb10c7f62768583ec311d0748f68796cf0a5b32
mode 100644,000000..100644
--- /dev/null
@@@ -1,94 -1,0 +1,94 @@@
-             // Remember for each inherent implementation encoutered its span and generics
 +//! lint on inherent implementations
 +
 +use crate::utils::{in_macro, span_lint_and_then};
 +use rustc_data_structures::fx::FxHashMap;
 +use rustc_hir::{def_id, Crate, Item, ItemKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_span::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for multiple inherent implementations of a struct
 +    ///
 +    /// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// struct X;
 +    /// impl X {
 +    ///     fn one() {}
 +    /// }
 +    /// impl X {
 +    ///     fn other() {}
 +    /// }
 +    /// ```
 +    ///
 +    /// Could be written:
 +    ///
 +    /// ```rust
 +    /// struct X;
 +    /// impl X {
 +    ///     fn one() {}
 +    ///     fn other() {}
 +    /// }
 +    /// ```
 +    pub MULTIPLE_INHERENT_IMPL,
 +    restriction,
 +    "Multiple inherent impl that could be grouped"
 +}
 +
 +#[allow(clippy::module_name_repetitions)]
 +#[derive(Default)]
 +pub struct MultipleInherentImpl {
 +    impls: FxHashMap<def_id::DefId, Span>,
 +}
 +
 +impl_lint_pass!(MultipleInherentImpl => [MULTIPLE_INHERENT_IMPL]);
 +
 +impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
 +    fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
 +        if let ItemKind::Impl {
 +            ref generics,
 +            of_trait: None,
 +            ..
 +        } = item.kind
 +        {
++            // Remember for each inherent implementation encountered its span and generics
 +            // but filter out implementations that have generic params (type or lifetime)
 +            // or are derived from a macro
 +            if !in_macro(item.span) && generics.params.is_empty() {
 +                self.impls.insert(item.hir_id.owner.to_def_id(), item.span);
 +            }
 +        }
 +    }
 +
 +    fn check_crate_post(&mut self, cx: &LateContext<'tcx>, krate: &'tcx Crate<'_>) {
 +        if let Some(item) = krate.items.values().next() {
 +            // Retrieve all inherent implementations from the crate, grouped by type
 +            for impls in cx
 +                .tcx
 +                .crate_inherent_impls(item.hir_id.owner.to_def_id().krate)
 +                .inherent_impls
 +                .values()
 +            {
 +                // Filter out implementations that have generic params (type or lifetime)
 +                let mut impl_spans = impls.iter().filter_map(|impl_def| self.impls.get(impl_def));
 +                if let Some(initial_span) = impl_spans.next() {
 +                    impl_spans.for_each(|additional_span| {
 +                        span_lint_and_then(
 +                            cx,
 +                            MULTIPLE_INHERENT_IMPL,
 +                            *additional_span,
 +                            "Multiple implementations of this structure",
 +                            |diag| {
 +                                diag.span_note(*initial_span, "First implementation here");
 +                            },
 +                        )
 +                    })
 +                }
 +            }
 +        }
 +    }
 +}
index 32e79317f82254119bf9b3075ef15f3b827f3ea7,0000000000000000000000000000000000000000..f371942dbeec57056ca35176bbda2f005d9d8084
mode 100644,000000..100644
--- /dev/null
@@@ -1,1828 -1,0 +1,1836 @@@
-         "associated-constants `MIN`/`MAX` of integers are prefered to `{min,max}_value()` and module constants",
 +// error-pattern:cargo-clippy
 +
 +#![feature(bindings_after_at)]
 +#![feature(box_patterns)]
 +#![feature(box_syntax)]
 +#![feature(concat_idents)]
 +#![feature(crate_visibility_modifier)]
 +#![feature(drain_filter)]
 +#![feature(or_patterns)]
 +#![feature(rustc_private)]
 +#![feature(stmt_expr_attributes)]
 +#![recursion_limit = "512"]
 +#![cfg_attr(feature = "deny-warnings", deny(warnings))]
 +#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)]
 +#![warn(trivial_casts, trivial_numeric_casts)]
 +// warn on lints, that are included in `rust-lang/rust`s bootstrap
 +#![warn(rust_2018_idioms, unused_lifetimes)]
 +// warn on rustc internal lints
 +#![deny(rustc::internal)]
 +
 +// FIXME: switch to something more ergonomic here, once available.
 +// (Currently there is no way to opt into sysroot crates without `extern crate`.)
 +extern crate rustc_ast;
 +extern crate rustc_ast_pretty;
 +extern crate rustc_attr;
 +extern crate rustc_data_structures;
 +extern crate rustc_errors;
 +extern crate rustc_hir;
 +extern crate rustc_hir_pretty;
 +extern crate rustc_index;
 +extern crate rustc_infer;
 +extern crate rustc_lexer;
 +extern crate rustc_lint;
 +extern crate rustc_middle;
 +extern crate rustc_mir;
 +extern crate rustc_parse;
 +extern crate rustc_parse_format;
 +extern crate rustc_session;
 +extern crate rustc_span;
 +extern crate rustc_target;
 +extern crate rustc_trait_selection;
 +extern crate rustc_typeck;
 +
 +use rustc_data_structures::fx::FxHashSet;
 +use rustc_lint::LintId;
 +use rustc_session::Session;
 +
 +/// Macro used to declare a Clippy lint.
 +///
 +/// Every lint declaration consists of 4 parts:
 +///
 +/// 1. The documentation, which is used for the website
 +/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
 +/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
 +///    `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
 +/// 4. The `description` that contains a short explanation on what's wrong with code where the
 +///    lint is triggered.
 +///
 +/// Currently the categories `style`, `correctness`, `complexity` and `perf` are enabled by default.
 +/// As said in the README.md of this repository, if the lint level mapping changes, please update
 +/// README.md.
 +///
 +/// # Example
 +///
 +/// ```
 +/// #![feature(rustc_private)]
 +/// extern crate rustc_session;
 +/// use rustc_session::declare_tool_lint;
 +/// use clippy_lints::declare_clippy_lint;
 +///
 +/// declare_clippy_lint! {
 +///     /// **What it does:** Checks for ... (describe what the lint matches).
 +///     ///
 +///     /// **Why is this bad?** Supply the reason for linting the code.
 +///     ///
 +///     /// **Known problems:** None. (Or describe where it could go wrong.)
 +///     ///
 +///     /// **Example:**
 +///     ///
 +///     /// ```rust
 +///     /// // Bad
 +///     /// Insert a short example of code that triggers the lint
 +///     ///
 +///     /// // Good
 +///     /// Insert a short example of improved code that doesn't trigger the lint
 +///     /// ```
 +///     pub LINT_NAME,
 +///     pedantic,
 +///     "description"
 +/// }
 +/// ```
 +/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
 +#[macro_export]
 +macro_rules! declare_clippy_lint {
 +    { $(#[$attr:meta])* pub $name:tt, style, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
 +        }
 +    };
 +    { $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => {
 +        declare_tool_lint! {
 +            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
 +        }
 +    };
 +}
 +
 +mod consts;
 +#[macro_use]
 +mod utils;
 +
 +// begin lints modules, do not remove this comment, it’s used in `update_lints`
 +mod approx_const;
 +mod arithmetic;
 +mod as_conversions;
 +mod assertions_on_constants;
 +mod assign_ops;
 +mod atomic_ordering;
 +mod attrs;
 +mod await_holding_lock;
 +mod bit_mask;
 +mod blacklisted_name;
 +mod blocks_in_if_conditions;
 +mod booleans;
 +mod bytecount;
 +mod cargo_common_metadata;
 +mod checked_conversions;
 +mod cognitive_complexity;
 +mod collapsible_if;
 +mod comparison_chain;
 +mod copies;
 +mod copy_iterator;
 +mod dbg_macro;
 +mod default_trait_access;
 +mod dereference;
 +mod derive;
 +mod doc;
 +mod double_comparison;
 +mod double_parens;
 +mod drop_bounds;
 +mod drop_forget_ref;
 +mod duration_subsec;
 +mod else_if_without_else;
 +mod empty_enum;
 +mod entry;
 +mod enum_clike;
 +mod enum_variants;
 +mod eq_op;
 +mod erasing_op;
 +mod escape;
 +mod eta_reduction;
 +mod eval_order_dependence;
 +mod excessive_bools;
 +mod exit;
 +mod explicit_write;
 +mod fallible_impl_from;
 +mod float_literal;
 +mod floating_point_arithmetic;
 +mod format;
 +mod formatting;
 +mod functions;
 +mod future_not_send;
 +mod get_last_with_len;
 +mod identity_op;
 +mod if_let_mutex;
 +mod if_let_some_result;
 +mod if_not_else;
 +mod implicit_return;
 +mod implicit_saturating_sub;
 +mod indexing_slicing;
 +mod infinite_iter;
 +mod inherent_impl;
 +mod inherent_to_string;
 +mod inline_fn_without_body;
 +mod int_plus_one;
 +mod integer_division;
 +mod items_after_statements;
 +mod large_const_arrays;
 +mod large_enum_variant;
 +mod large_stack_arrays;
 +mod len_zero;
 +mod let_and_return;
 +mod let_if_seq;
 +mod let_underscore;
 +mod lifetimes;
 +mod literal_representation;
 +mod loops;
 +mod macro_use;
 +mod main_recursion;
 +mod manual_async_fn;
 +mod manual_non_exhaustive;
 +mod map_clone;
 +mod map_identity;
 +mod map_unit_fn;
 +mod match_on_vec_items;
 +mod matches;
 +mod mem_discriminant;
 +mod mem_forget;
 +mod mem_replace;
 +mod methods;
 +mod minmax;
 +mod misc;
 +mod misc_early;
 +mod missing_const_for_fn;
 +mod missing_doc;
 +mod missing_inline;
 +mod modulo_arithmetic;
 +mod multiple_crate_versions;
 +mod mut_key;
 +mod mut_mut;
 +mod mut_reference;
 +mod mutable_debug_assertion;
 +mod mutex_atomic;
 +mod needless_bool;
 +mod needless_borrow;
 +mod needless_borrowed_ref;
 +mod needless_continue;
 +mod needless_pass_by_value;
 +mod needless_update;
 +mod neg_cmp_op_on_partial_ord;
 +mod neg_multiply;
 +mod new_without_default;
 +mod no_effect;
 +mod non_copy_const;
 +mod non_expressive_names;
 +mod open_options;
 +mod option_env_unwrap;
 +mod option_if_let_else;
 +mod overflow_check_conditional;
 +mod panic_unimplemented;
 +mod partialeq_ne_impl;
 +mod path_buf_push_overwrite;
 +mod pattern_type_mismatch;
 +mod precedence;
 +mod ptr;
 +mod ptr_offset_with_cast;
 +mod question_mark;
 +mod ranges;
 +mod redundant_clone;
++mod redundant_closure_call;
 +mod redundant_field_names;
 +mod redundant_pub_crate;
 +mod redundant_static_lifetimes;
 +mod reference;
 +mod regex;
 +mod repeat_once;
 +mod returns;
 +mod serde_api;
 +mod shadow;
 +mod single_component_path_imports;
 +mod slow_vector_initialization;
 +mod strings;
 +mod suspicious_trait_impl;
 +mod swap;
 +mod tabs_in_doc_comments;
 +mod temporary_assignment;
 +mod to_digit_is_some;
 +mod trait_bounds;
 +mod transmute;
 +mod transmuting_null;
 +mod trivially_copy_pass_by_ref;
 +mod try_err;
 +mod types;
 +mod unicode;
++mod unit_return_expecting_ord;
 +mod unnamed_address;
 +mod unnecessary_sort_by;
 +mod unnested_or_patterns;
 +mod unsafe_removed_from_name;
 +mod unused_io_amount;
 +mod unused_self;
 +mod unwrap;
 +mod use_self;
 +mod useless_conversion;
 +mod vec;
 +mod vec_resize_to_zero;
 +mod verbose_file_reads;
 +mod wildcard_dependencies;
 +mod wildcard_imports;
 +mod write;
 +mod zero_div_zero;
 +// end lints modules, do not remove this comment, it’s used in `update_lints`
 +
 +pub use crate::utils::conf::Conf;
 +
 +mod reexport {
 +    pub use rustc_span::Symbol as Name;
 +}
 +
 +/// Register all pre expansion lints
 +///
 +/// Pre-expansion lints run before any macro expansion has happened.
 +///
 +/// Note that due to the architecture of the compiler, currently `cfg_attr` attributes on crate
 +/// level (i.e `#![cfg_attr(...)]`) will still be expanded even when using a pre-expansion pass.
 +///
 +/// Used in `./src/driver.rs`.
 +pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore) {
 +    store.register_pre_expansion_pass(|| box write::Write::default());
 +    store.register_pre_expansion_pass(|| box attrs::EarlyAttributes);
 +    store.register_pre_expansion_pass(|| box dbg_macro::DbgMacro);
 +}
 +
 +#[doc(hidden)]
 +pub fn read_conf(args: &[rustc_ast::ast::NestedMetaItem], sess: &Session) -> Conf {
 +    use std::path::Path;
 +    match utils::conf::file_from_args(args) {
 +        Ok(file_name) => {
 +            // if the user specified a file, it must exist, otherwise default to `clippy.toml` but
 +            // do not require the file to exist
 +            let file_name = match file_name {
 +                Some(file_name) => file_name,
 +                None => match utils::conf::lookup_conf_file() {
 +                    Ok(Some(path)) => path,
 +                    Ok(None) => return Conf::default(),
 +                    Err(error) => {
 +                        sess.struct_err(&format!("error finding Clippy's configuration file: {}", error))
 +                            .emit();
 +                        return Conf::default();
 +                    },
 +                },
 +            };
 +
 +            let file_name = if file_name.is_relative() {
 +                sess.local_crate_source_file
 +                    .as_deref()
 +                    .and_then(Path::parent)
 +                    .unwrap_or_else(|| Path::new(""))
 +                    .join(file_name)
 +            } else {
 +                file_name
 +            };
 +
 +            let (conf, errors) = utils::conf::read(&file_name);
 +
 +            // all conf errors are non-fatal, we just use the default conf in case of error
 +            for error in errors {
 +                sess.struct_err(&format!(
 +                    "error reading Clippy's configuration file `{}`: {}",
 +                    file_name.display(),
 +                    error
 +                ))
 +                .emit();
 +            }
 +
 +            conf
 +        },
 +        Err((err, span)) => {
 +            sess.struct_span_err(span, err)
 +                .span_note(span, "Clippy will use default configuration")
 +                .emit();
 +            Conf::default()
 +        },
 +    }
 +}
 +
 +/// Register all lints and lint groups with the rustc plugin registry
 +///
 +/// Used in `./src/driver.rs`.
 +#[allow(clippy::too_many_lines)]
 +#[rustfmt::skip]
 +pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
 +    register_removed_non_tool_lints(store);
 +
 +    // begin deprecated lints, do not remove this comment, it’s used in `update_lints`
 +    store.register_removed(
 +        "clippy::should_assert_eq",
 +        "`assert!()` will be more flexible with RFC 2011",
 +    );
 +    store.register_removed(
 +        "clippy::extend_from_slice",
 +        "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice",
 +    );
 +    store.register_removed(
 +        "clippy::range_step_by_zero",
 +        "`iterator.step_by(0)` panics nowadays",
 +    );
 +    store.register_removed(
 +        "clippy::unstable_as_slice",
 +        "`Vec::as_slice` has been stabilized in 1.7",
 +    );
 +    store.register_removed(
 +        "clippy::unstable_as_mut_slice",
 +        "`Vec::as_mut_slice` has been stabilized in 1.7",
 +    );
 +    store.register_removed(
 +        "clippy::str_to_string",
 +        "using `str::to_string` is common even today and specialization will likely happen soon",
 +    );
 +    store.register_removed(
 +        "clippy::string_to_string",
 +        "using `string::to_string` is common even today and specialization will likely happen soon",
 +    );
 +    store.register_removed(
 +        "clippy::misaligned_transmute",
 +        "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
 +    );
 +    store.register_removed(
 +        "clippy::assign_ops",
 +        "using compound assignment operators (e.g., `+=`) is harmless",
 +    );
 +    store.register_removed(
 +        "clippy::if_let_redundant_pattern_matching",
 +        "this lint has been changed to redundant_pattern_matching",
 +    );
 +    store.register_removed(
 +        "clippy::unsafe_vector_initialization",
 +        "the replacement suggested by this lint had substantially different behavior",
 +    );
 +    store.register_removed(
 +        "clippy::invalid_ref",
 +        "superseded by rustc lint `invalid_value`",
 +    );
 +    store.register_removed(
 +        "clippy::unused_collect",
 +        "`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint",
 +    );
 +    store.register_removed(
 +        "clippy::into_iter_on_array",
 +        "this lint has been uplifted to rustc and is now called `array_into_iter`",
 +    );
 +    store.register_removed(
 +        "clippy::unused_label",
 +        "this lint has been uplifted to rustc and is now called `unused_labels`",
 +    );
 +    store.register_removed(
 +        "clippy::replace_consts",
-         &misc_early::REDUNDANT_CLOSURE_CALL,
++        "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants",
 +    );
 +    store.register_removed(
 +        "clippy::regex_macro",
 +        "the regex! macro has been removed from the regex crate in 2018",
 +    );
 +    // end deprecated lints, do not remove this comment, it’s used in `update_lints`
 +
 +    // begin register lints, do not remove this comment, it’s used in `update_lints`
 +    store.register_lints(&[
 +        &approx_const::APPROX_CONSTANT,
 +        &arithmetic::FLOAT_ARITHMETIC,
 +        &arithmetic::INTEGER_ARITHMETIC,
 +        &as_conversions::AS_CONVERSIONS,
 +        &assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
 +        &assign_ops::ASSIGN_OP_PATTERN,
 +        &assign_ops::MISREFACTORED_ASSIGN_OP,
 +        &atomic_ordering::INVALID_ATOMIC_ORDERING,
 +        &attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
 +        &attrs::DEPRECATED_CFG_ATTR,
 +        &attrs::DEPRECATED_SEMVER,
 +        &attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
 +        &attrs::INLINE_ALWAYS,
 +        &attrs::MISMATCHED_TARGET_OS,
 +        &attrs::UNKNOWN_CLIPPY_LINTS,
 +        &attrs::USELESS_ATTRIBUTE,
 +        &await_holding_lock::AWAIT_HOLDING_LOCK,
 +        &bit_mask::BAD_BIT_MASK,
 +        &bit_mask::INEFFECTIVE_BIT_MASK,
 +        &bit_mask::VERBOSE_BIT_MASK,
 +        &blacklisted_name::BLACKLISTED_NAME,
 +        &blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
 +        &booleans::LOGIC_BUG,
 +        &booleans::NONMINIMAL_BOOL,
 +        &bytecount::NAIVE_BYTECOUNT,
 +        &cargo_common_metadata::CARGO_COMMON_METADATA,
 +        &checked_conversions::CHECKED_CONVERSIONS,
 +        &cognitive_complexity::COGNITIVE_COMPLEXITY,
 +        &collapsible_if::COLLAPSIBLE_IF,
 +        &comparison_chain::COMPARISON_CHAIN,
 +        &copies::IFS_SAME_COND,
 +        &copies::IF_SAME_THEN_ELSE,
 +        &copies::MATCH_SAME_ARMS,
 +        &copies::SAME_FUNCTIONS_IN_IF_CONDITION,
 +        &copy_iterator::COPY_ITERATOR,
 +        &dbg_macro::DBG_MACRO,
 +        &default_trait_access::DEFAULT_TRAIT_ACCESS,
 +        &dereference::EXPLICIT_DEREF_METHODS,
 +        &derive::DERIVE_HASH_XOR_EQ,
 +        &derive::EXPL_IMPL_CLONE_ON_COPY,
 +        &derive::UNSAFE_DERIVE_DESERIALIZE,
 +        &doc::DOC_MARKDOWN,
 +        &doc::MISSING_ERRORS_DOC,
 +        &doc::MISSING_SAFETY_DOC,
 +        &doc::NEEDLESS_DOCTEST_MAIN,
 +        &double_comparison::DOUBLE_COMPARISONS,
 +        &double_parens::DOUBLE_PARENS,
 +        &drop_bounds::DROP_BOUNDS,
 +        &drop_forget_ref::DROP_COPY,
 +        &drop_forget_ref::DROP_REF,
 +        &drop_forget_ref::FORGET_COPY,
 +        &drop_forget_ref::FORGET_REF,
 +        &duration_subsec::DURATION_SUBSEC,
 +        &else_if_without_else::ELSE_IF_WITHOUT_ELSE,
 +        &empty_enum::EMPTY_ENUM,
 +        &entry::MAP_ENTRY,
 +        &enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
 +        &enum_variants::ENUM_VARIANT_NAMES,
 +        &enum_variants::MODULE_INCEPTION,
 +        &enum_variants::MODULE_NAME_REPETITIONS,
 +        &enum_variants::PUB_ENUM_VARIANT_NAMES,
 +        &eq_op::EQ_OP,
 +        &eq_op::OP_REF,
 +        &erasing_op::ERASING_OP,
 +        &escape::BOXED_LOCAL,
 +        &eta_reduction::REDUNDANT_CLOSURE,
 +        &eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
 +        &eval_order_dependence::DIVERGING_SUB_EXPRESSION,
 +        &eval_order_dependence::EVAL_ORDER_DEPENDENCE,
 +        &excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
 +        &excessive_bools::STRUCT_EXCESSIVE_BOOLS,
 +        &exit::EXIT,
 +        &explicit_write::EXPLICIT_WRITE,
 +        &fallible_impl_from::FALLIBLE_IMPL_FROM,
 +        &float_literal::EXCESSIVE_PRECISION,
 +        &float_literal::LOSSY_FLOAT_LITERAL,
 +        &floating_point_arithmetic::IMPRECISE_FLOPS,
 +        &floating_point_arithmetic::SUBOPTIMAL_FLOPS,
 +        &format::USELESS_FORMAT,
 +        &formatting::POSSIBLE_MISSING_COMMA,
 +        &formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
 +        &formatting::SUSPICIOUS_ELSE_FORMATTING,
 +        &formatting::SUSPICIOUS_UNARY_OP_FORMATTING,
 +        &functions::DOUBLE_MUST_USE,
 +        &functions::MUST_USE_CANDIDATE,
 +        &functions::MUST_USE_UNIT,
 +        &functions::NOT_UNSAFE_PTR_ARG_DEREF,
 +        &functions::TOO_MANY_ARGUMENTS,
 +        &functions::TOO_MANY_LINES,
 +        &future_not_send::FUTURE_NOT_SEND,
 +        &get_last_with_len::GET_LAST_WITH_LEN,
 +        &identity_op::IDENTITY_OP,
 +        &if_let_mutex::IF_LET_MUTEX,
 +        &if_let_some_result::IF_LET_SOME_RESULT,
 +        &if_not_else::IF_NOT_ELSE,
 +        &implicit_return::IMPLICIT_RETURN,
 +        &implicit_saturating_sub::IMPLICIT_SATURATING_SUB,
 +        &indexing_slicing::INDEXING_SLICING,
 +        &indexing_slicing::OUT_OF_BOUNDS_INDEXING,
 +        &infinite_iter::INFINITE_ITER,
 +        &infinite_iter::MAYBE_INFINITE_ITER,
 +        &inherent_impl::MULTIPLE_INHERENT_IMPL,
 +        &inherent_to_string::INHERENT_TO_STRING,
 +        &inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY,
 +        &inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
 +        &int_plus_one::INT_PLUS_ONE,
 +        &integer_division::INTEGER_DIVISION,
 +        &items_after_statements::ITEMS_AFTER_STATEMENTS,
 +        &large_const_arrays::LARGE_CONST_ARRAYS,
 +        &large_enum_variant::LARGE_ENUM_VARIANT,
 +        &large_stack_arrays::LARGE_STACK_ARRAYS,
 +        &len_zero::LEN_WITHOUT_IS_EMPTY,
 +        &len_zero::LEN_ZERO,
 +        &let_and_return::LET_AND_RETURN,
 +        &let_if_seq::USELESS_LET_IF_SEQ,
 +        &let_underscore::LET_UNDERSCORE_LOCK,
 +        &let_underscore::LET_UNDERSCORE_MUST_USE,
 +        &lifetimes::EXTRA_UNUSED_LIFETIMES,
 +        &lifetimes::NEEDLESS_LIFETIMES,
 +        &literal_representation::DECIMAL_LITERAL_REPRESENTATION,
 +        &literal_representation::INCONSISTENT_DIGIT_GROUPING,
 +        &literal_representation::LARGE_DIGIT_GROUPS,
 +        &literal_representation::MISTYPED_LITERAL_SUFFIXES,
 +        &literal_representation::UNREADABLE_LITERAL,
 +        &loops::EMPTY_LOOP,
 +        &loops::EXPLICIT_COUNTER_LOOP,
 +        &loops::EXPLICIT_INTO_ITER_LOOP,
 +        &loops::EXPLICIT_ITER_LOOP,
 +        &loops::FOR_KV_MAP,
 +        &loops::FOR_LOOPS_OVER_FALLIBLES,
 +        &loops::ITER_NEXT_LOOP,
 +        &loops::MANUAL_MEMCPY,
 +        &loops::MUT_RANGE_BOUND,
 +        &loops::NEEDLESS_COLLECT,
 +        &loops::NEEDLESS_RANGE_LOOP,
 +        &loops::NEVER_LOOP,
 +        &loops::WHILE_IMMUTABLE_CONDITION,
 +        &loops::WHILE_LET_LOOP,
 +        &loops::WHILE_LET_ON_ITERATOR,
 +        &macro_use::MACRO_USE_IMPORTS,
 +        &main_recursion::MAIN_RECURSION,
 +        &manual_async_fn::MANUAL_ASYNC_FN,
 +        &manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
 +        &map_clone::MAP_CLONE,
 +        &map_identity::MAP_IDENTITY,
 +        &map_unit_fn::OPTION_MAP_UNIT_FN,
 +        &map_unit_fn::RESULT_MAP_UNIT_FN,
 +        &match_on_vec_items::MATCH_ON_VEC_ITEMS,
 +        &matches::INFALLIBLE_DESTRUCTURING_MATCH,
 +        &matches::MATCH_AS_REF,
 +        &matches::MATCH_BOOL,
 +        &matches::MATCH_LIKE_MATCHES_MACRO,
 +        &matches::MATCH_OVERLAPPING_ARM,
 +        &matches::MATCH_REF_PATS,
 +        &matches::MATCH_SINGLE_BINDING,
 +        &matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
 +        &matches::MATCH_WILD_ERR_ARM,
 +        &matches::REDUNDANT_PATTERN_MATCHING,
 +        &matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
 +        &matches::SINGLE_MATCH,
 +        &matches::SINGLE_MATCH_ELSE,
 +        &matches::WILDCARD_ENUM_MATCH_ARM,
 +        &matches::WILDCARD_IN_OR_PATTERNS,
 +        &mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
 +        &mem_forget::MEM_FORGET,
 +        &mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
 +        &mem_replace::MEM_REPLACE_WITH_DEFAULT,
 +        &mem_replace::MEM_REPLACE_WITH_UNINIT,
 +        &methods::BIND_INSTEAD_OF_MAP,
 +        &methods::CHARS_LAST_CMP,
 +        &methods::CHARS_NEXT_CMP,
 +        &methods::CLONE_DOUBLE_REF,
 +        &methods::CLONE_ON_COPY,
 +        &methods::CLONE_ON_REF_PTR,
 +        &methods::EXPECT_FUN_CALL,
 +        &methods::EXPECT_USED,
 +        &methods::FILETYPE_IS_FILE,
 +        &methods::FILTER_MAP,
 +        &methods::FILTER_MAP_NEXT,
 +        &methods::FILTER_NEXT,
 +        &methods::FIND_MAP,
 +        &methods::FLAT_MAP_IDENTITY,
 +        &methods::GET_UNWRAP,
 +        &methods::INEFFICIENT_TO_STRING,
 +        &methods::INTO_ITER_ON_REF,
 +        &methods::ITERATOR_STEP_BY_ZERO,
 +        &methods::ITER_CLONED_COLLECT,
 +        &methods::ITER_NEXT_SLICE,
 +        &methods::ITER_NTH,
 +        &methods::ITER_NTH_ZERO,
 +        &methods::ITER_SKIP_NEXT,
 +        &methods::MANUAL_SATURATING_ARITHMETIC,
 +        &methods::MAP_FLATTEN,
 +        &methods::MAP_UNWRAP_OR,
 +        &methods::NEW_RET_NO_SELF,
 +        &methods::OK_EXPECT,
 +        &methods::OPTION_AS_REF_DEREF,
 +        &methods::OPTION_MAP_OR_NONE,
 +        &methods::OR_FUN_CALL,
 +        &methods::RESULT_MAP_OR_INTO_OPTION,
 +        &methods::SEARCH_IS_SOME,
 +        &methods::SHOULD_IMPLEMENT_TRAIT,
 +        &methods::SINGLE_CHAR_PATTERN,
 +        &methods::SKIP_WHILE_NEXT,
 +        &methods::STRING_EXTEND_CHARS,
 +        &methods::SUSPICIOUS_MAP,
 +        &methods::TEMPORARY_CSTRING_AS_PTR,
 +        &methods::UNINIT_ASSUMED_INIT,
 +        &methods::UNNECESSARY_FILTER_MAP,
 +        &methods::UNNECESSARY_FOLD,
 +        &methods::UNWRAP_USED,
 +        &methods::USELESS_ASREF,
 +        &methods::WRONG_PUB_SELF_CONVENTION,
 +        &methods::WRONG_SELF_CONVENTION,
 +        &methods::ZST_OFFSET,
 +        &minmax::MIN_MAX,
 +        &misc::CMP_NAN,
 +        &misc::CMP_OWNED,
 +        &misc::FLOAT_CMP,
 +        &misc::FLOAT_CMP_CONST,
 +        &misc::MODULO_ONE,
 +        &misc::SHORT_CIRCUIT_STATEMENT,
 +        &misc::TOPLEVEL_REF_ARG,
 +        &misc::USED_UNDERSCORE_BINDING,
 +        &misc::ZERO_PTR,
 +        &misc_early::BUILTIN_TYPE_SHADOW,
 +        &misc_early::DOUBLE_NEG,
 +        &misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
 +        &misc_early::MIXED_CASE_HEX_LITERALS,
-         LintId::of(&misc_early::REDUNDANT_CLOSURE_CALL),
 +        &misc_early::REDUNDANT_PATTERN,
 +        &misc_early::UNNEEDED_FIELD_PATTERN,
 +        &misc_early::UNNEEDED_WILDCARD_PATTERN,
 +        &misc_early::UNSEPARATED_LITERAL_SUFFIX,
 +        &misc_early::ZERO_PREFIXED_LITERAL,
 +        &missing_const_for_fn::MISSING_CONST_FOR_FN,
 +        &missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
 +        &missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
 +        &modulo_arithmetic::MODULO_ARITHMETIC,
 +        &multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
 +        &mut_key::MUTABLE_KEY_TYPE,
 +        &mut_mut::MUT_MUT,
 +        &mut_reference::UNNECESSARY_MUT_PASSED,
 +        &mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
 +        &mutex_atomic::MUTEX_ATOMIC,
 +        &mutex_atomic::MUTEX_INTEGER,
 +        &needless_bool::BOOL_COMPARISON,
 +        &needless_bool::NEEDLESS_BOOL,
 +        &needless_borrow::NEEDLESS_BORROW,
 +        &needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
 +        &needless_continue::NEEDLESS_CONTINUE,
 +        &needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
 +        &needless_update::NEEDLESS_UPDATE,
 +        &neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
 +        &neg_multiply::NEG_MULTIPLY,
 +        &new_without_default::NEW_WITHOUT_DEFAULT,
 +        &no_effect::NO_EFFECT,
 +        &no_effect::UNNECESSARY_OPERATION,
 +        &non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
 +        &non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
 +        &non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
 +        &non_expressive_names::MANY_SINGLE_CHAR_NAMES,
 +        &non_expressive_names::SIMILAR_NAMES,
 +        &open_options::NONSENSICAL_OPEN_OPTIONS,
 +        &option_env_unwrap::OPTION_ENV_UNWRAP,
 +        &option_if_let_else::OPTION_IF_LET_ELSE,
 +        &overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
 +        &panic_unimplemented::PANIC,
 +        &panic_unimplemented::PANIC_PARAMS,
 +        &panic_unimplemented::TODO,
 +        &panic_unimplemented::UNIMPLEMENTED,
 +        &panic_unimplemented::UNREACHABLE,
 +        &partialeq_ne_impl::PARTIALEQ_NE_IMPL,
 +        &path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE,
 +        &pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
 +        &precedence::PRECEDENCE,
 +        &ptr::CMP_NULL,
 +        &ptr::MUT_FROM_REF,
 +        &ptr::PTR_ARG,
 +        &ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
 +        &question_mark::QUESTION_MARK,
 +        &ranges::RANGE_MINUS_ONE,
 +        &ranges::RANGE_PLUS_ONE,
 +        &ranges::RANGE_ZIP_WITH_LEN,
 +        &ranges::REVERSED_EMPTY_RANGES,
 +        &redundant_clone::REDUNDANT_CLONE,
++        &redundant_closure_call::REDUNDANT_CLOSURE_CALL,
 +        &redundant_field_names::REDUNDANT_FIELD_NAMES,
 +        &redundant_pub_crate::REDUNDANT_PUB_CRATE,
 +        &redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
 +        &reference::DEREF_ADDROF,
 +        &reference::REF_IN_DEREF,
 +        &regex::INVALID_REGEX,
 +        &regex::TRIVIAL_REGEX,
 +        &repeat_once::REPEAT_ONCE,
 +        &returns::NEEDLESS_RETURN,
 +        &returns::UNUSED_UNIT,
 +        &serde_api::SERDE_API_MISUSE,
 +        &shadow::SHADOW_REUSE,
 +        &shadow::SHADOW_SAME,
 +        &shadow::SHADOW_UNRELATED,
 +        &single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
 +        &slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
 +        &strings::STRING_ADD,
 +        &strings::STRING_ADD_ASSIGN,
 +        &strings::STRING_LIT_AS_BYTES,
 +        &suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
 +        &suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
 +        &swap::ALMOST_SWAPPED,
 +        &swap::MANUAL_SWAP,
 +        &tabs_in_doc_comments::TABS_IN_DOC_COMMENTS,
 +        &temporary_assignment::TEMPORARY_ASSIGNMENT,
 +        &to_digit_is_some::TO_DIGIT_IS_SOME,
 +        &trait_bounds::TYPE_REPETITION_IN_BOUNDS,
 +        &transmute::CROSSPOINTER_TRANSMUTE,
 +        &transmute::TRANSMUTE_BYTES_TO_STR,
 +        &transmute::TRANSMUTE_FLOAT_TO_INT,
 +        &transmute::TRANSMUTE_INT_TO_BOOL,
 +        &transmute::TRANSMUTE_INT_TO_CHAR,
 +        &transmute::TRANSMUTE_INT_TO_FLOAT,
 +        &transmute::TRANSMUTE_PTR_TO_PTR,
 +        &transmute::TRANSMUTE_PTR_TO_REF,
 +        &transmute::UNSOUND_COLLECTION_TRANSMUTE,
 +        &transmute::USELESS_TRANSMUTE,
 +        &transmute::WRONG_TRANSMUTE,
 +        &transmuting_null::TRANSMUTING_NULL,
 +        &trivially_copy_pass_by_ref::TRIVIALLY_COPY_PASS_BY_REF,
 +        &try_err::TRY_ERR,
 +        &types::ABSURD_EXTREME_COMPARISONS,
 +        &types::BORROWED_BOX,
 +        &types::BOX_VEC,
 +        &types::CAST_LOSSLESS,
 +        &types::CAST_POSSIBLE_TRUNCATION,
 +        &types::CAST_POSSIBLE_WRAP,
 +        &types::CAST_PRECISION_LOSS,
 +        &types::CAST_PTR_ALIGNMENT,
 +        &types::CAST_REF_TO_MUT,
 +        &types::CAST_SIGN_LOSS,
 +        &types::CHAR_LIT_AS_U8,
 +        &types::FN_TO_NUMERIC_CAST,
 +        &types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
 +        &types::IMPLICIT_HASHER,
 +        &types::INVALID_UPCAST_COMPARISONS,
 +        &types::LET_UNIT_VALUE,
 +        &types::LINKEDLIST,
 +        &types::OPTION_OPTION,
 +        &types::REDUNDANT_ALLOCATION,
 +        &types::TYPE_COMPLEXITY,
 +        &types::UNIT_ARG,
 +        &types::UNIT_CMP,
 +        &types::UNNECESSARY_CAST,
 +        &types::VEC_BOX,
 +        &unicode::NON_ASCII_LITERAL,
 +        &unicode::UNICODE_NOT_NFC,
 +        &unicode::ZERO_WIDTH_SPACE,
++        &unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
 +        &unnamed_address::FN_ADDRESS_COMPARISONS,
 +        &unnamed_address::VTABLE_ADDRESS_COMPARISONS,
 +        &unnecessary_sort_by::UNNECESSARY_SORT_BY,
 +        &unnested_or_patterns::UNNESTED_OR_PATTERNS,
 +        &unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
 +        &unused_io_amount::UNUSED_IO_AMOUNT,
 +        &unused_self::UNUSED_SELF,
 +        &unwrap::PANICKING_UNWRAP,
 +        &unwrap::UNNECESSARY_UNWRAP,
 +        &use_self::USE_SELF,
 +        &useless_conversion::USELESS_CONVERSION,
 +        &utils::internal_lints::CLIPPY_LINTS_INTERNAL,
 +        &utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS,
 +        &utils::internal_lints::COMPILER_LINT_FUNCTIONS,
 +        &utils::internal_lints::DEFAULT_LINT,
 +        &utils::internal_lints::LINT_WITHOUT_LINT_PASS,
 +        &utils::internal_lints::OUTER_EXPN_EXPN_DATA,
 +        &utils::internal_lints::PRODUCE_ICE,
 +        &vec::USELESS_VEC,
 +        &vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
 +        &verbose_file_reads::VERBOSE_FILE_READS,
 +        &wildcard_dependencies::WILDCARD_DEPENDENCIES,
 +        &wildcard_imports::ENUM_GLOB_USE,
 +        &wildcard_imports::WILDCARD_IMPORTS,
 +        &write::PRINTLN_EMPTY_STRING,
 +        &write::PRINT_LITERAL,
 +        &write::PRINT_STDOUT,
 +        &write::PRINT_WITH_NEWLINE,
 +        &write::USE_DEBUG,
 +        &write::WRITELN_EMPTY_STRING,
 +        &write::WRITE_LITERAL,
 +        &write::WRITE_WITH_NEWLINE,
 +        &zero_div_zero::ZERO_DIVIDED_BY_ZERO,
 +    ]);
 +    // end register lints, do not remove this comment, it’s used in `update_lints`
 +
 +    store.register_late_pass(|| box await_holding_lock::AwaitHoldingLock);
 +    store.register_late_pass(|| box serde_api::SerdeAPI);
 +    store.register_late_pass(|| box utils::internal_lints::CompilerLintFunctions::new());
 +    store.register_late_pass(|| box utils::internal_lints::LintWithoutLintPass::default());
 +    store.register_late_pass(|| box utils::internal_lints::OuterExpnDataPass);
 +    store.register_late_pass(|| box utils::inspector::DeepCodeInspector);
 +    store.register_late_pass(|| box utils::author::Author);
 +    let vec_box_size_threshold = conf.vec_box_size_threshold;
 +    store.register_late_pass(move || box types::Types::new(vec_box_size_threshold));
 +    store.register_late_pass(|| box booleans::NonminimalBool);
 +    store.register_late_pass(|| box eq_op::EqOp);
 +    store.register_late_pass(|| box enum_clike::UnportableVariant);
 +    store.register_late_pass(|| box float_literal::FloatLiteral);
 +    let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
 +    store.register_late_pass(move || box bit_mask::BitMask::new(verbose_bit_mask_threshold));
 +    store.register_late_pass(|| box ptr::Ptr);
 +    store.register_late_pass(|| box needless_bool::NeedlessBool);
 +    store.register_late_pass(|| box needless_bool::BoolComparison);
 +    store.register_late_pass(|| box approx_const::ApproxConstant);
 +    store.register_late_pass(|| box misc::MiscLints);
 +    store.register_late_pass(|| box eta_reduction::EtaReduction);
 +    store.register_late_pass(|| box identity_op::IdentityOp);
 +    store.register_late_pass(|| box erasing_op::ErasingOp);
 +    store.register_late_pass(|| box mut_mut::MutMut);
 +    store.register_late_pass(|| box mut_reference::UnnecessaryMutPassed);
 +    store.register_late_pass(|| box len_zero::LenZero);
 +    store.register_late_pass(|| box attrs::Attributes);
 +    store.register_late_pass(|| box blocks_in_if_conditions::BlocksInIfConditions);
 +    store.register_late_pass(|| box unicode::Unicode);
++    store.register_late_pass(|| box unit_return_expecting_ord::UnitReturnExpectingOrd);
 +    store.register_late_pass(|| box strings::StringAdd);
 +    store.register_late_pass(|| box implicit_return::ImplicitReturn);
 +    store.register_late_pass(|| box implicit_saturating_sub::ImplicitSaturatingSub);
 +    store.register_late_pass(|| box methods::Methods);
 +    store.register_late_pass(|| box map_clone::MapClone);
 +    store.register_late_pass(|| box shadow::Shadow);
 +    store.register_late_pass(|| box types::LetUnitValue);
 +    store.register_late_pass(|| box types::UnitCmp);
 +    store.register_late_pass(|| box loops::Loops);
 +    store.register_late_pass(|| box main_recursion::MainRecursion::default());
 +    store.register_late_pass(|| box lifetimes::Lifetimes);
 +    store.register_late_pass(|| box entry::HashMapPass);
 +    store.register_late_pass(|| box ranges::Ranges);
 +    store.register_late_pass(|| box types::Casts);
 +    let type_complexity_threshold = conf.type_complexity_threshold;
 +    store.register_late_pass(move || box types::TypeComplexity::new(type_complexity_threshold));
 +    store.register_late_pass(|| box matches::Matches::default());
 +    store.register_late_pass(|| box minmax::MinMaxPass);
 +    store.register_late_pass(|| box open_options::OpenOptions);
 +    store.register_late_pass(|| box zero_div_zero::ZeroDiv);
 +    store.register_late_pass(|| box mutex_atomic::Mutex);
 +    store.register_late_pass(|| box needless_update::NeedlessUpdate);
 +    store.register_late_pass(|| box needless_borrow::NeedlessBorrow::default());
 +    store.register_late_pass(|| box needless_borrowed_ref::NeedlessBorrowedRef);
 +    store.register_late_pass(|| box no_effect::NoEffect);
 +    store.register_late_pass(|| box temporary_assignment::TemporaryAssignment);
 +    store.register_late_pass(|| box transmute::Transmute);
 +    let cognitive_complexity_threshold = conf.cognitive_complexity_threshold;
 +    store.register_late_pass(move || box cognitive_complexity::CognitiveComplexity::new(cognitive_complexity_threshold));
 +    let too_large_for_stack = conf.too_large_for_stack;
 +    store.register_late_pass(move || box escape::BoxedLocal{too_large_for_stack});
 +    store.register_late_pass(|| box panic_unimplemented::PanicUnimplemented);
 +    store.register_late_pass(|| box strings::StringLitAsBytes);
 +    store.register_late_pass(|| box derive::Derive);
 +    store.register_late_pass(|| box types::CharLitAsU8);
 +    store.register_late_pass(|| box vec::UselessVec);
 +    store.register_late_pass(|| box drop_bounds::DropBounds);
 +    store.register_late_pass(|| box get_last_with_len::GetLastWithLen);
 +    store.register_late_pass(|| box drop_forget_ref::DropForgetRef);
 +    store.register_late_pass(|| box empty_enum::EmptyEnum);
 +    store.register_late_pass(|| box types::AbsurdExtremeComparisons);
 +    store.register_late_pass(|| box types::InvalidUpcastComparisons);
 +    store.register_late_pass(|| box regex::Regex::default());
 +    store.register_late_pass(|| box copies::CopyAndPaste);
 +    store.register_late_pass(|| box copy_iterator::CopyIterator);
 +    store.register_late_pass(|| box format::UselessFormat);
 +    store.register_late_pass(|| box swap::Swap);
 +    store.register_late_pass(|| box overflow_check_conditional::OverflowCheckConditional);
 +    store.register_late_pass(|| box new_without_default::NewWithoutDefault::default());
 +    let blacklisted_names = conf.blacklisted_names.iter().cloned().collect::<FxHashSet<_>>();
 +    store.register_late_pass(move || box blacklisted_name::BlacklistedName::new(blacklisted_names.clone()));
 +    let too_many_arguments_threshold1 = conf.too_many_arguments_threshold;
 +    let too_many_lines_threshold2 = conf.too_many_lines_threshold;
 +    store.register_late_pass(move || box functions::Functions::new(too_many_arguments_threshold1, too_many_lines_threshold2));
 +    let doc_valid_idents = conf.doc_valid_idents.iter().cloned().collect::<FxHashSet<_>>();
 +    store.register_late_pass(move || box doc::DocMarkdown::new(doc_valid_idents.clone()));
 +    store.register_late_pass(|| box neg_multiply::NegMultiply);
 +    store.register_late_pass(|| box mem_discriminant::MemDiscriminant);
 +    store.register_late_pass(|| box mem_forget::MemForget);
 +    store.register_late_pass(|| box mem_replace::MemReplace);
 +    store.register_late_pass(|| box arithmetic::Arithmetic::default());
 +    store.register_late_pass(|| box assign_ops::AssignOps);
 +    store.register_late_pass(|| box let_if_seq::LetIfSeq);
 +    store.register_late_pass(|| box eval_order_dependence::EvalOrderDependence);
 +    store.register_late_pass(|| box missing_doc::MissingDoc::new());
 +    store.register_late_pass(|| box missing_inline::MissingInline);
 +    store.register_late_pass(|| box if_let_some_result::OkIfLet);
 +    store.register_late_pass(|| box partialeq_ne_impl::PartialEqNeImpl);
 +    store.register_late_pass(|| box unused_io_amount::UnusedIoAmount);
 +    let enum_variant_size_threshold = conf.enum_variant_size_threshold;
 +    store.register_late_pass(move || box large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold));
 +    store.register_late_pass(|| box explicit_write::ExplicitWrite);
 +    store.register_late_pass(|| box needless_pass_by_value::NeedlessPassByValue);
 +    let trivially_copy_pass_by_ref = trivially_copy_pass_by_ref::TriviallyCopyPassByRef::new(
 +        conf.trivial_copy_size_limit,
 +        &sess.target,
 +    );
 +    store.register_late_pass(move || box trivially_copy_pass_by_ref);
 +    store.register_late_pass(|| box try_err::TryErr);
 +    store.register_late_pass(|| box use_self::UseSelf);
 +    store.register_late_pass(|| box bytecount::ByteCount);
 +    store.register_late_pass(|| box infinite_iter::InfiniteIter);
 +    store.register_late_pass(|| box inline_fn_without_body::InlineFnWithoutBody);
 +    store.register_late_pass(|| box useless_conversion::UselessConversion::default());
 +    store.register_late_pass(|| box types::ImplicitHasher);
 +    store.register_late_pass(|| box fallible_impl_from::FallibleImplFrom);
 +    store.register_late_pass(|| box types::UnitArg);
 +    store.register_late_pass(|| box double_comparison::DoubleComparisons);
 +    store.register_late_pass(|| box question_mark::QuestionMark);
 +    store.register_late_pass(|| box suspicious_trait_impl::SuspiciousImpl);
 +    store.register_late_pass(|| box map_unit_fn::MapUnit);
 +    store.register_late_pass(|| box inherent_impl::MultipleInherentImpl::default());
 +    store.register_late_pass(|| box neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd);
 +    store.register_late_pass(|| box unwrap::Unwrap);
 +    store.register_late_pass(|| box duration_subsec::DurationSubsec);
 +    store.register_late_pass(|| box default_trait_access::DefaultTraitAccess);
 +    store.register_late_pass(|| box indexing_slicing::IndexingSlicing);
 +    store.register_late_pass(|| box non_copy_const::NonCopyConst);
 +    store.register_late_pass(|| box ptr_offset_with_cast::PtrOffsetWithCast);
 +    store.register_late_pass(|| box redundant_clone::RedundantClone);
 +    store.register_late_pass(|| box slow_vector_initialization::SlowVectorInit);
 +    store.register_late_pass(|| box unnecessary_sort_by::UnnecessarySortBy);
 +    store.register_late_pass(|| box types::RefToMut);
 +    store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants);
 +    store.register_late_pass(|| box missing_const_for_fn::MissingConstForFn);
 +    store.register_late_pass(|| box transmuting_null::TransmutingNull);
 +    store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);
 +    store.register_late_pass(|| box checked_conversions::CheckedConversions);
 +    store.register_late_pass(|| box integer_division::IntegerDivision);
 +    store.register_late_pass(|| box inherent_to_string::InherentToString);
 +    let max_trait_bounds = conf.max_trait_bounds;
 +    store.register_late_pass(move || box trait_bounds::TraitBounds::new(max_trait_bounds));
 +    store.register_late_pass(|| box comparison_chain::ComparisonChain);
 +    store.register_late_pass(|| box mut_key::MutableKeyType);
 +    store.register_late_pass(|| box modulo_arithmetic::ModuloArithmetic);
 +    store.register_early_pass(|| box reference::DerefAddrOf);
 +    store.register_early_pass(|| box reference::RefInDeref);
 +    store.register_early_pass(|| box double_parens::DoubleParens);
 +    store.register_early_pass(|| box unsafe_removed_from_name::UnsafeNameRemoval);
 +    store.register_early_pass(|| box if_not_else::IfNotElse);
 +    store.register_early_pass(|| box else_if_without_else::ElseIfWithoutElse);
 +    store.register_early_pass(|| box int_plus_one::IntPlusOne);
 +    store.register_early_pass(|| box formatting::Formatting);
 +    store.register_early_pass(|| box misc_early::MiscEarlyLints);
++    store.register_early_pass(|| box redundant_closure_call::RedundantClosureCall);
++    store.register_late_pass(|| box redundant_closure_call::RedundantClosureCall);
 +    store.register_early_pass(|| box returns::Return);
 +    store.register_late_pass(|| box let_and_return::LetReturn);
 +    store.register_early_pass(|| box collapsible_if::CollapsibleIf);
 +    store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
 +    store.register_early_pass(|| box precedence::Precedence);
 +    store.register_early_pass(|| box needless_continue::NeedlessContinue);
 +    store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
 +    store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
 +    store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
 +    store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
 +    store.register_early_pass(|| box literal_representation::LiteralDigitGrouping);
 +    let literal_representation_threshold = conf.literal_representation_threshold;
 +    store.register_early_pass(move || box literal_representation::DecimalLiteralRepresentation::new(literal_representation_threshold));
 +    store.register_early_pass(|| box utils::internal_lints::ClippyLintsInternal);
 +    let enum_variant_name_threshold = conf.enum_variant_name_threshold;
 +    store.register_early_pass(move || box enum_variants::EnumVariantNames::new(enum_variant_name_threshold));
 +    store.register_early_pass(|| box tabs_in_doc_comments::TabsInDocComments);
 +    store.register_late_pass(|| box unused_self::UnusedSelf);
 +    store.register_late_pass(|| box mutable_debug_assertion::DebugAssertWithMutCall);
 +    store.register_late_pass(|| box exit::Exit);
 +    store.register_late_pass(|| box to_digit_is_some::ToDigitIsSome);
 +    let array_size_threshold = conf.array_size_threshold;
 +    store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold));
 +    store.register_late_pass(move || box large_const_arrays::LargeConstArrays::new(array_size_threshold));
 +    store.register_late_pass(|| box floating_point_arithmetic::FloatingPointArithmetic);
 +    store.register_early_pass(|| box as_conversions::AsConversions);
 +    store.register_early_pass(|| box utils::internal_lints::ProduceIce);
 +    store.register_late_pass(|| box let_underscore::LetUnderscore);
 +    store.register_late_pass(|| box atomic_ordering::AtomicOrdering);
 +    store.register_early_pass(|| box single_component_path_imports::SingleComponentPathImports);
 +    let max_fn_params_bools = conf.max_fn_params_bools;
 +    let max_struct_bools = conf.max_struct_bools;
 +    store.register_early_pass(move || box excessive_bools::ExcessiveBools::new(max_struct_bools, max_fn_params_bools));
 +    store.register_early_pass(|| box option_env_unwrap::OptionEnvUnwrap);
 +    let warn_on_all_wildcard_imports = conf.warn_on_all_wildcard_imports;
 +    store.register_late_pass(move || box wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports));
 +    store.register_late_pass(|| box verbose_file_reads::VerboseFileReads);
 +    store.register_late_pass(|| box redundant_pub_crate::RedundantPubCrate::default());
 +    store.register_late_pass(|| box unnamed_address::UnnamedAddress);
 +    store.register_late_pass(|| box dereference::Dereferencing);
 +    store.register_late_pass(|| box option_if_let_else::OptionIfLetElse);
 +    store.register_late_pass(|| box future_not_send::FutureNotSend);
 +    store.register_late_pass(|| box utils::internal_lints::CollapsibleCalls);
 +    store.register_late_pass(|| box if_let_mutex::IfLetMutex);
 +    store.register_late_pass(|| box match_on_vec_items::MatchOnVecItems);
 +    store.register_early_pass(|| box manual_non_exhaustive::ManualNonExhaustive);
 +    store.register_late_pass(|| box manual_async_fn::ManualAsyncFn);
 +    store.register_early_pass(|| box redundant_field_names::RedundantFieldNames);
 +    store.register_late_pass(|| box vec_resize_to_zero::VecResizeToZero);
 +    let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
 +    store.register_early_pass(move || box non_expressive_names::NonExpressiveNames {
 +        single_char_binding_names_threshold,
 +    });
 +    store.register_early_pass(|| box unnested_or_patterns::UnnestedOrPatterns);
 +    store.register_late_pass(|| box macro_use::MacroUseImports::default());
 +    store.register_late_pass(|| box map_identity::MapIdentity);
 +    store.register_late_pass(|| box pattern_type_mismatch::PatternTypeMismatch);
 +    store.register_late_pass(|| box repeat_once::RepeatOnce);
 +
 +    store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
 +        LintId::of(&arithmetic::FLOAT_ARITHMETIC),
 +        LintId::of(&arithmetic::INTEGER_ARITHMETIC),
 +        LintId::of(&as_conversions::AS_CONVERSIONS),
 +        LintId::of(&dbg_macro::DBG_MACRO),
 +        LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
 +        LintId::of(&exit::EXIT),
 +        LintId::of(&float_literal::LOSSY_FLOAT_LITERAL),
 +        LintId::of(&implicit_return::IMPLICIT_RETURN),
 +        LintId::of(&indexing_slicing::INDEXING_SLICING),
 +        LintId::of(&inherent_impl::MULTIPLE_INHERENT_IMPL),
 +        LintId::of(&integer_division::INTEGER_DIVISION),
 +        LintId::of(&let_underscore::LET_UNDERSCORE_MUST_USE),
 +        LintId::of(&literal_representation::DECIMAL_LITERAL_REPRESENTATION),
 +        LintId::of(&matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
 +        LintId::of(&matches::WILDCARD_ENUM_MATCH_ARM),
 +        LintId::of(&mem_forget::MEM_FORGET),
 +        LintId::of(&methods::CLONE_ON_REF_PTR),
 +        LintId::of(&methods::EXPECT_USED),
 +        LintId::of(&methods::FILETYPE_IS_FILE),
 +        LintId::of(&methods::GET_UNWRAP),
 +        LintId::of(&methods::UNWRAP_USED),
 +        LintId::of(&methods::WRONG_PUB_SELF_CONVENTION),
 +        LintId::of(&misc::FLOAT_CMP_CONST),
 +        LintId::of(&misc_early::UNNEEDED_FIELD_PATTERN),
 +        LintId::of(&missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
 +        LintId::of(&missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
 +        LintId::of(&modulo_arithmetic::MODULO_ARITHMETIC),
 +        LintId::of(&panic_unimplemented::PANIC),
 +        LintId::of(&panic_unimplemented::TODO),
 +        LintId::of(&panic_unimplemented::UNIMPLEMENTED),
 +        LintId::of(&panic_unimplemented::UNREACHABLE),
 +        LintId::of(&pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
 +        LintId::of(&shadow::SHADOW_REUSE),
 +        LintId::of(&shadow::SHADOW_SAME),
 +        LintId::of(&strings::STRING_ADD),
 +        LintId::of(&verbose_file_reads::VERBOSE_FILE_READS),
 +        LintId::of(&write::PRINT_STDOUT),
 +        LintId::of(&write::USE_DEBUG),
 +    ]);
 +
 +    store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
 +        LintId::of(&attrs::INLINE_ALWAYS),
 +        LintId::of(&await_holding_lock::AWAIT_HOLDING_LOCK),
 +        LintId::of(&checked_conversions::CHECKED_CONVERSIONS),
 +        LintId::of(&copies::MATCH_SAME_ARMS),
 +        LintId::of(&copies::SAME_FUNCTIONS_IN_IF_CONDITION),
 +        LintId::of(&copy_iterator::COPY_ITERATOR),
 +        LintId::of(&default_trait_access::DEFAULT_TRAIT_ACCESS),
 +        LintId::of(&dereference::EXPLICIT_DEREF_METHODS),
 +        LintId::of(&derive::EXPL_IMPL_CLONE_ON_COPY),
 +        LintId::of(&derive::UNSAFE_DERIVE_DESERIALIZE),
 +        LintId::of(&doc::DOC_MARKDOWN),
 +        LintId::of(&doc::MISSING_ERRORS_DOC),
 +        LintId::of(&empty_enum::EMPTY_ENUM),
 +        LintId::of(&enum_variants::MODULE_NAME_REPETITIONS),
 +        LintId::of(&enum_variants::PUB_ENUM_VARIANT_NAMES),
 +        LintId::of(&eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
 +        LintId::of(&excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
 +        LintId::of(&excessive_bools::STRUCT_EXCESSIVE_BOOLS),
 +        LintId::of(&functions::MUST_USE_CANDIDATE),
 +        LintId::of(&functions::TOO_MANY_LINES),
 +        LintId::of(&if_not_else::IF_NOT_ELSE),
 +        LintId::of(&implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
 +        LintId::of(&infinite_iter::MAYBE_INFINITE_ITER),
 +        LintId::of(&items_after_statements::ITEMS_AFTER_STATEMENTS),
 +        LintId::of(&large_stack_arrays::LARGE_STACK_ARRAYS),
 +        LintId::of(&literal_representation::LARGE_DIGIT_GROUPS),
 +        LintId::of(&literal_representation::UNREADABLE_LITERAL),
 +        LintId::of(&loops::EXPLICIT_INTO_ITER_LOOP),
 +        LintId::of(&loops::EXPLICIT_ITER_LOOP),
 +        LintId::of(&macro_use::MACRO_USE_IMPORTS),
 +        LintId::of(&match_on_vec_items::MATCH_ON_VEC_ITEMS),
 +        LintId::of(&matches::MATCH_BOOL),
 +        LintId::of(&matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
 +        LintId::of(&matches::MATCH_WILD_ERR_ARM),
 +        LintId::of(&matches::SINGLE_MATCH_ELSE),
 +        LintId::of(&methods::FILTER_MAP),
 +        LintId::of(&methods::FILTER_MAP_NEXT),
 +        LintId::of(&methods::FIND_MAP),
 +        LintId::of(&methods::INEFFICIENT_TO_STRING),
 +        LintId::of(&methods::MAP_FLATTEN),
 +        LintId::of(&methods::MAP_UNWRAP_OR),
 +        LintId::of(&misc::USED_UNDERSCORE_BINDING),
 +        LintId::of(&misc_early::UNSEPARATED_LITERAL_SUFFIX),
 +        LintId::of(&mut_mut::MUT_MUT),
 +        LintId::of(&needless_continue::NEEDLESS_CONTINUE),
 +        LintId::of(&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
 +        LintId::of(&non_expressive_names::SIMILAR_NAMES),
 +        LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE),
 +        LintId::of(&ranges::RANGE_MINUS_ONE),
 +        LintId::of(&ranges::RANGE_PLUS_ONE),
 +        LintId::of(&shadow::SHADOW_UNRELATED),
 +        LintId::of(&strings::STRING_ADD_ASSIGN),
 +        LintId::of(&trait_bounds::TYPE_REPETITION_IN_BOUNDS),
 +        LintId::of(&trivially_copy_pass_by_ref::TRIVIALLY_COPY_PASS_BY_REF),
 +        LintId::of(&types::CAST_LOSSLESS),
 +        LintId::of(&types::CAST_POSSIBLE_TRUNCATION),
 +        LintId::of(&types::CAST_POSSIBLE_WRAP),
 +        LintId::of(&types::CAST_PRECISION_LOSS),
 +        LintId::of(&types::CAST_PTR_ALIGNMENT),
 +        LintId::of(&types::CAST_SIGN_LOSS),
 +        LintId::of(&types::IMPLICIT_HASHER),
 +        LintId::of(&types::INVALID_UPCAST_COMPARISONS),
 +        LintId::of(&types::LET_UNIT_VALUE),
 +        LintId::of(&types::LINKEDLIST),
 +        LintId::of(&types::OPTION_OPTION),
 +        LintId::of(&unicode::NON_ASCII_LITERAL),
 +        LintId::of(&unicode::UNICODE_NOT_NFC),
 +        LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
 +        LintId::of(&unused_self::UNUSED_SELF),
 +        LintId::of(&wildcard_imports::ENUM_GLOB_USE),
 +        LintId::of(&wildcard_imports::WILDCARD_IMPORTS),
 +    ]);
 +
 +    store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
 +        LintId::of(&utils::internal_lints::CLIPPY_LINTS_INTERNAL),
 +        LintId::of(&utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
 +        LintId::of(&utils::internal_lints::COMPILER_LINT_FUNCTIONS),
 +        LintId::of(&utils::internal_lints::DEFAULT_LINT),
 +        LintId::of(&utils::internal_lints::LINT_WITHOUT_LINT_PASS),
 +        LintId::of(&utils::internal_lints::OUTER_EXPN_EXPN_DATA),
 +        LintId::of(&utils::internal_lints::PRODUCE_ICE),
 +    ]);
 +
 +    store.register_group(true, "clippy::all", Some("clippy"), vec![
 +        LintId::of(&approx_const::APPROX_CONSTANT),
 +        LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
 +        LintId::of(&assign_ops::ASSIGN_OP_PATTERN),
 +        LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP),
 +        LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
 +        LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
 +        LintId::of(&attrs::DEPRECATED_CFG_ATTR),
 +        LintId::of(&attrs::DEPRECATED_SEMVER),
 +        LintId::of(&attrs::MISMATCHED_TARGET_OS),
 +        LintId::of(&attrs::UNKNOWN_CLIPPY_LINTS),
 +        LintId::of(&attrs::USELESS_ATTRIBUTE),
 +        LintId::of(&bit_mask::BAD_BIT_MASK),
 +        LintId::of(&bit_mask::INEFFECTIVE_BIT_MASK),
 +        LintId::of(&bit_mask::VERBOSE_BIT_MASK),
 +        LintId::of(&blacklisted_name::BLACKLISTED_NAME),
 +        LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
 +        LintId::of(&booleans::LOGIC_BUG),
 +        LintId::of(&booleans::NONMINIMAL_BOOL),
 +        LintId::of(&bytecount::NAIVE_BYTECOUNT),
 +        LintId::of(&collapsible_if::COLLAPSIBLE_IF),
 +        LintId::of(&comparison_chain::COMPARISON_CHAIN),
 +        LintId::of(&copies::IFS_SAME_COND),
 +        LintId::of(&copies::IF_SAME_THEN_ELSE),
 +        LintId::of(&derive::DERIVE_HASH_XOR_EQ),
 +        LintId::of(&doc::MISSING_SAFETY_DOC),
 +        LintId::of(&doc::NEEDLESS_DOCTEST_MAIN),
 +        LintId::of(&double_comparison::DOUBLE_COMPARISONS),
 +        LintId::of(&double_parens::DOUBLE_PARENS),
 +        LintId::of(&drop_bounds::DROP_BOUNDS),
 +        LintId::of(&drop_forget_ref::DROP_COPY),
 +        LintId::of(&drop_forget_ref::DROP_REF),
 +        LintId::of(&drop_forget_ref::FORGET_COPY),
 +        LintId::of(&drop_forget_ref::FORGET_REF),
 +        LintId::of(&duration_subsec::DURATION_SUBSEC),
 +        LintId::of(&entry::MAP_ENTRY),
 +        LintId::of(&enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
 +        LintId::of(&enum_variants::ENUM_VARIANT_NAMES),
 +        LintId::of(&enum_variants::MODULE_INCEPTION),
 +        LintId::of(&eq_op::EQ_OP),
 +        LintId::of(&eq_op::OP_REF),
 +        LintId::of(&erasing_op::ERASING_OP),
 +        LintId::of(&escape::BOXED_LOCAL),
 +        LintId::of(&eta_reduction::REDUNDANT_CLOSURE),
 +        LintId::of(&eval_order_dependence::DIVERGING_SUB_EXPRESSION),
 +        LintId::of(&eval_order_dependence::EVAL_ORDER_DEPENDENCE),
 +        LintId::of(&explicit_write::EXPLICIT_WRITE),
 +        LintId::of(&float_literal::EXCESSIVE_PRECISION),
 +        LintId::of(&format::USELESS_FORMAT),
 +        LintId::of(&formatting::POSSIBLE_MISSING_COMMA),
 +        LintId::of(&formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
 +        LintId::of(&formatting::SUSPICIOUS_ELSE_FORMATTING),
 +        LintId::of(&formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
 +        LintId::of(&functions::DOUBLE_MUST_USE),
 +        LintId::of(&functions::MUST_USE_UNIT),
 +        LintId::of(&functions::NOT_UNSAFE_PTR_ARG_DEREF),
 +        LintId::of(&functions::TOO_MANY_ARGUMENTS),
 +        LintId::of(&get_last_with_len::GET_LAST_WITH_LEN),
 +        LintId::of(&identity_op::IDENTITY_OP),
 +        LintId::of(&if_let_mutex::IF_LET_MUTEX),
 +        LintId::of(&if_let_some_result::IF_LET_SOME_RESULT),
 +        LintId::of(&indexing_slicing::OUT_OF_BOUNDS_INDEXING),
 +        LintId::of(&infinite_iter::INFINITE_ITER),
 +        LintId::of(&inherent_to_string::INHERENT_TO_STRING),
 +        LintId::of(&inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
 +        LintId::of(&inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
 +        LintId::of(&int_plus_one::INT_PLUS_ONE),
 +        LintId::of(&large_const_arrays::LARGE_CONST_ARRAYS),
 +        LintId::of(&large_enum_variant::LARGE_ENUM_VARIANT),
 +        LintId::of(&len_zero::LEN_WITHOUT_IS_EMPTY),
 +        LintId::of(&len_zero::LEN_ZERO),
 +        LintId::of(&let_and_return::LET_AND_RETURN),
 +        LintId::of(&let_underscore::LET_UNDERSCORE_LOCK),
 +        LintId::of(&lifetimes::EXTRA_UNUSED_LIFETIMES),
 +        LintId::of(&lifetimes::NEEDLESS_LIFETIMES),
 +        LintId::of(&literal_representation::INCONSISTENT_DIGIT_GROUPING),
 +        LintId::of(&literal_representation::MISTYPED_LITERAL_SUFFIXES),
 +        LintId::of(&loops::EMPTY_LOOP),
 +        LintId::of(&loops::EXPLICIT_COUNTER_LOOP),
 +        LintId::of(&loops::FOR_KV_MAP),
 +        LintId::of(&loops::FOR_LOOPS_OVER_FALLIBLES),
 +        LintId::of(&loops::ITER_NEXT_LOOP),
 +        LintId::of(&loops::MANUAL_MEMCPY),
 +        LintId::of(&loops::MUT_RANGE_BOUND),
 +        LintId::of(&loops::NEEDLESS_COLLECT),
 +        LintId::of(&loops::NEEDLESS_RANGE_LOOP),
 +        LintId::of(&loops::NEVER_LOOP),
 +        LintId::of(&loops::WHILE_IMMUTABLE_CONDITION),
 +        LintId::of(&loops::WHILE_LET_LOOP),
 +        LintId::of(&loops::WHILE_LET_ON_ITERATOR),
 +        LintId::of(&main_recursion::MAIN_RECURSION),
 +        LintId::of(&manual_async_fn::MANUAL_ASYNC_FN),
 +        LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
 +        LintId::of(&map_clone::MAP_CLONE),
 +        LintId::of(&map_identity::MAP_IDENTITY),
 +        LintId::of(&map_unit_fn::OPTION_MAP_UNIT_FN),
 +        LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN),
 +        LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH),
 +        LintId::of(&matches::MATCH_AS_REF),
 +        LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO),
 +        LintId::of(&matches::MATCH_OVERLAPPING_ARM),
 +        LintId::of(&matches::MATCH_REF_PATS),
 +        LintId::of(&matches::MATCH_SINGLE_BINDING),
 +        LintId::of(&matches::REDUNDANT_PATTERN_MATCHING),
 +        LintId::of(&matches::SINGLE_MATCH),
 +        LintId::of(&matches::WILDCARD_IN_OR_PATTERNS),
 +        LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
 +        LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
 +        LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
 +        LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
 +        LintId::of(&methods::BIND_INSTEAD_OF_MAP),
 +        LintId::of(&methods::CHARS_LAST_CMP),
 +        LintId::of(&methods::CHARS_NEXT_CMP),
 +        LintId::of(&methods::CLONE_DOUBLE_REF),
 +        LintId::of(&methods::CLONE_ON_COPY),
 +        LintId::of(&methods::EXPECT_FUN_CALL),
 +        LintId::of(&methods::FILTER_NEXT),
 +        LintId::of(&methods::FLAT_MAP_IDENTITY),
 +        LintId::of(&methods::INTO_ITER_ON_REF),
 +        LintId::of(&methods::ITERATOR_STEP_BY_ZERO),
 +        LintId::of(&methods::ITER_CLONED_COLLECT),
 +        LintId::of(&methods::ITER_NEXT_SLICE),
 +        LintId::of(&methods::ITER_NTH),
 +        LintId::of(&methods::ITER_NTH_ZERO),
 +        LintId::of(&methods::ITER_SKIP_NEXT),
 +        LintId::of(&methods::MANUAL_SATURATING_ARITHMETIC),
 +        LintId::of(&methods::NEW_RET_NO_SELF),
 +        LintId::of(&methods::OK_EXPECT),
 +        LintId::of(&methods::OPTION_AS_REF_DEREF),
 +        LintId::of(&methods::OPTION_MAP_OR_NONE),
 +        LintId::of(&methods::OR_FUN_CALL),
 +        LintId::of(&methods::RESULT_MAP_OR_INTO_OPTION),
 +        LintId::of(&methods::SEARCH_IS_SOME),
 +        LintId::of(&methods::SHOULD_IMPLEMENT_TRAIT),
 +        LintId::of(&methods::SINGLE_CHAR_PATTERN),
 +        LintId::of(&methods::SKIP_WHILE_NEXT),
 +        LintId::of(&methods::STRING_EXTEND_CHARS),
 +        LintId::of(&methods::SUSPICIOUS_MAP),
 +        LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
 +        LintId::of(&methods::UNINIT_ASSUMED_INIT),
 +        LintId::of(&methods::UNNECESSARY_FILTER_MAP),
 +        LintId::of(&methods::UNNECESSARY_FOLD),
 +        LintId::of(&methods::USELESS_ASREF),
 +        LintId::of(&methods::WRONG_SELF_CONVENTION),
 +        LintId::of(&methods::ZST_OFFSET),
 +        LintId::of(&minmax::MIN_MAX),
 +        LintId::of(&misc::CMP_NAN),
 +        LintId::of(&misc::CMP_OWNED),
 +        LintId::of(&misc::FLOAT_CMP),
 +        LintId::of(&misc::MODULO_ONE),
 +        LintId::of(&misc::SHORT_CIRCUIT_STATEMENT),
 +        LintId::of(&misc::TOPLEVEL_REF_ARG),
 +        LintId::of(&misc::ZERO_PTR),
 +        LintId::of(&misc_early::BUILTIN_TYPE_SHADOW),
 +        LintId::of(&misc_early::DOUBLE_NEG),
 +        LintId::of(&misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
 +        LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
-         LintId::of(&misc_early::REDUNDANT_CLOSURE_CALL),
 +        LintId::of(&misc_early::REDUNDANT_PATTERN),
 +        LintId::of(&misc_early::UNNEEDED_WILDCARD_PATTERN),
 +        LintId::of(&misc_early::ZERO_PREFIXED_LITERAL),
 +        LintId::of(&mut_key::MUTABLE_KEY_TYPE),
 +        LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
 +        LintId::of(&mutex_atomic::MUTEX_ATOMIC),
 +        LintId::of(&needless_bool::BOOL_COMPARISON),
 +        LintId::of(&needless_bool::NEEDLESS_BOOL),
 +        LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
 +        LintId::of(&needless_update::NEEDLESS_UPDATE),
 +        LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
 +        LintId::of(&neg_multiply::NEG_MULTIPLY),
 +        LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
 +        LintId::of(&no_effect::NO_EFFECT),
 +        LintId::of(&no_effect::UNNECESSARY_OPERATION),
 +        LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
 +        LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
 +        LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
 +        LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES),
 +        LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
 +        LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP),
 +        LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
 +        LintId::of(&panic_unimplemented::PANIC_PARAMS),
 +        LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL),
 +        LintId::of(&precedence::PRECEDENCE),
 +        LintId::of(&ptr::CMP_NULL),
 +        LintId::of(&ptr::MUT_FROM_REF),
 +        LintId::of(&ptr::PTR_ARG),
 +        LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
 +        LintId::of(&question_mark::QUESTION_MARK),
 +        LintId::of(&ranges::RANGE_ZIP_WITH_LEN),
 +        LintId::of(&ranges::REVERSED_EMPTY_RANGES),
 +        LintId::of(&redundant_clone::REDUNDANT_CLONE),
++        LintId::of(&redundant_closure_call::REDUNDANT_CLOSURE_CALL),
 +        LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
 +        LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
 +        LintId::of(&reference::DEREF_ADDROF),
 +        LintId::of(&reference::REF_IN_DEREF),
 +        LintId::of(&regex::INVALID_REGEX),
 +        LintId::of(&regex::TRIVIAL_REGEX),
 +        LintId::of(&repeat_once::REPEAT_ONCE),
 +        LintId::of(&returns::NEEDLESS_RETURN),
 +        LintId::of(&returns::UNUSED_UNIT),
 +        LintId::of(&serde_api::SERDE_API_MISUSE),
 +        LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
 +        LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
 +        LintId::of(&strings::STRING_LIT_AS_BYTES),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
 +        LintId::of(&swap::ALMOST_SWAPPED),
 +        LintId::of(&swap::MANUAL_SWAP),
 +        LintId::of(&tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
 +        LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT),
 +        LintId::of(&to_digit_is_some::TO_DIGIT_IS_SOME),
 +        LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),
 +        LintId::of(&transmute::TRANSMUTE_BYTES_TO_STR),
 +        LintId::of(&transmute::TRANSMUTE_FLOAT_TO_INT),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_BOOL),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_CHAR),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_FLOAT),
 +        LintId::of(&transmute::TRANSMUTE_PTR_TO_PTR),
 +        LintId::of(&transmute::TRANSMUTE_PTR_TO_REF),
 +        LintId::of(&transmute::UNSOUND_COLLECTION_TRANSMUTE),
 +        LintId::of(&transmute::WRONG_TRANSMUTE),
 +        LintId::of(&transmuting_null::TRANSMUTING_NULL),
 +        LintId::of(&try_err::TRY_ERR),
 +        LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
 +        LintId::of(&types::BORROWED_BOX),
 +        LintId::of(&types::BOX_VEC),
 +        LintId::of(&types::CAST_REF_TO_MUT),
 +        LintId::of(&types::CHAR_LIT_AS_U8),
 +        LintId::of(&types::FN_TO_NUMERIC_CAST),
 +        LintId::of(&types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
 +        LintId::of(&types::REDUNDANT_ALLOCATION),
 +        LintId::of(&types::TYPE_COMPLEXITY),
 +        LintId::of(&types::UNIT_ARG),
 +        LintId::of(&types::UNIT_CMP),
 +        LintId::of(&types::UNNECESSARY_CAST),
 +        LintId::of(&types::VEC_BOX),
 +        LintId::of(&unicode::ZERO_WIDTH_SPACE),
++        LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
 +        LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
 +        LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
 +        LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
 +        LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
 +        LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
 +        LintId::of(&unwrap::PANICKING_UNWRAP),
 +        LintId::of(&unwrap::UNNECESSARY_UNWRAP),
 +        LintId::of(&useless_conversion::USELESS_CONVERSION),
 +        LintId::of(&vec::USELESS_VEC),
 +        LintId::of(&vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
 +        LintId::of(&write::PRINTLN_EMPTY_STRING),
 +        LintId::of(&write::PRINT_LITERAL),
 +        LintId::of(&write::PRINT_WITH_NEWLINE),
 +        LintId::of(&write::WRITELN_EMPTY_STRING),
 +        LintId::of(&write::WRITE_LITERAL),
 +        LintId::of(&write::WRITE_WITH_NEWLINE),
 +        LintId::of(&zero_div_zero::ZERO_DIVIDED_BY_ZERO),
 +    ]);
 +
 +    store.register_group(true, "clippy::style", Some("clippy_style"), vec![
 +        LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
 +        LintId::of(&assign_ops::ASSIGN_OP_PATTERN),
 +        LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
 +        LintId::of(&attrs::UNKNOWN_CLIPPY_LINTS),
 +        LintId::of(&bit_mask::VERBOSE_BIT_MASK),
 +        LintId::of(&blacklisted_name::BLACKLISTED_NAME),
 +        LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
 +        LintId::of(&collapsible_if::COLLAPSIBLE_IF),
 +        LintId::of(&comparison_chain::COMPARISON_CHAIN),
 +        LintId::of(&doc::MISSING_SAFETY_DOC),
 +        LintId::of(&doc::NEEDLESS_DOCTEST_MAIN),
 +        LintId::of(&enum_variants::ENUM_VARIANT_NAMES),
 +        LintId::of(&enum_variants::MODULE_INCEPTION),
 +        LintId::of(&eq_op::OP_REF),
 +        LintId::of(&eta_reduction::REDUNDANT_CLOSURE),
 +        LintId::of(&float_literal::EXCESSIVE_PRECISION),
 +        LintId::of(&formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
 +        LintId::of(&formatting::SUSPICIOUS_ELSE_FORMATTING),
 +        LintId::of(&formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
 +        LintId::of(&functions::DOUBLE_MUST_USE),
 +        LintId::of(&functions::MUST_USE_UNIT),
 +        LintId::of(&if_let_some_result::IF_LET_SOME_RESULT),
 +        LintId::of(&inherent_to_string::INHERENT_TO_STRING),
 +        LintId::of(&len_zero::LEN_WITHOUT_IS_EMPTY),
 +        LintId::of(&len_zero::LEN_ZERO),
 +        LintId::of(&let_and_return::LET_AND_RETURN),
 +        LintId::of(&literal_representation::INCONSISTENT_DIGIT_GROUPING),
 +        LintId::of(&loops::EMPTY_LOOP),
 +        LintId::of(&loops::FOR_KV_MAP),
 +        LintId::of(&loops::NEEDLESS_RANGE_LOOP),
 +        LintId::of(&loops::WHILE_LET_ON_ITERATOR),
 +        LintId::of(&main_recursion::MAIN_RECURSION),
 +        LintId::of(&manual_async_fn::MANUAL_ASYNC_FN),
 +        LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
 +        LintId::of(&map_clone::MAP_CLONE),
 +        LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH),
 +        LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO),
 +        LintId::of(&matches::MATCH_OVERLAPPING_ARM),
 +        LintId::of(&matches::MATCH_REF_PATS),
 +        LintId::of(&matches::REDUNDANT_PATTERN_MATCHING),
 +        LintId::of(&matches::SINGLE_MATCH),
 +        LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
 +        LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
 +        LintId::of(&methods::CHARS_LAST_CMP),
 +        LintId::of(&methods::CHARS_NEXT_CMP),
 +        LintId::of(&methods::INTO_ITER_ON_REF),
 +        LintId::of(&methods::ITER_CLONED_COLLECT),
 +        LintId::of(&methods::ITER_NEXT_SLICE),
 +        LintId::of(&methods::ITER_NTH_ZERO),
 +        LintId::of(&methods::ITER_SKIP_NEXT),
 +        LintId::of(&methods::MANUAL_SATURATING_ARITHMETIC),
 +        LintId::of(&methods::NEW_RET_NO_SELF),
 +        LintId::of(&methods::OK_EXPECT),
 +        LintId::of(&methods::OPTION_MAP_OR_NONE),
 +        LintId::of(&methods::RESULT_MAP_OR_INTO_OPTION),
 +        LintId::of(&methods::SHOULD_IMPLEMENT_TRAIT),
 +        LintId::of(&methods::STRING_EXTEND_CHARS),
 +        LintId::of(&methods::UNNECESSARY_FOLD),
 +        LintId::of(&methods::WRONG_SELF_CONVENTION),
 +        LintId::of(&misc::TOPLEVEL_REF_ARG),
 +        LintId::of(&misc::ZERO_PTR),
 +        LintId::of(&misc_early::BUILTIN_TYPE_SHADOW),
 +        LintId::of(&misc_early::DOUBLE_NEG),
 +        LintId::of(&misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
 +        LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
 +        LintId::of(&misc_early::REDUNDANT_PATTERN),
 +        LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
 +        LintId::of(&neg_multiply::NEG_MULTIPLY),
 +        LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
 +        LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
 +        LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES),
 +        LintId::of(&panic_unimplemented::PANIC_PARAMS),
 +        LintId::of(&ptr::CMP_NULL),
 +        LintId::of(&ptr::PTR_ARG),
 +        LintId::of(&question_mark::QUESTION_MARK),
 +        LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
 +        LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
 +        LintId::of(&regex::TRIVIAL_REGEX),
 +        LintId::of(&returns::NEEDLESS_RETURN),
 +        LintId::of(&returns::UNUSED_UNIT),
 +        LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
 +        LintId::of(&strings::STRING_LIT_AS_BYTES),
 +        LintId::of(&tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
 +        LintId::of(&to_digit_is_some::TO_DIGIT_IS_SOME),
 +        LintId::of(&try_err::TRY_ERR),
 +        LintId::of(&types::FN_TO_NUMERIC_CAST),
 +        LintId::of(&types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
 +        LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
 +        LintId::of(&write::PRINTLN_EMPTY_STRING),
 +        LintId::of(&write::PRINT_LITERAL),
 +        LintId::of(&write::PRINT_WITH_NEWLINE),
 +        LintId::of(&write::WRITELN_EMPTY_STRING),
 +        LintId::of(&write::WRITE_LITERAL),
 +        LintId::of(&write::WRITE_WITH_NEWLINE),
 +    ]);
 +
 +    store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
 +        LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP),
 +        LintId::of(&attrs::DEPRECATED_CFG_ATTR),
 +        LintId::of(&booleans::NONMINIMAL_BOOL),
 +        LintId::of(&double_comparison::DOUBLE_COMPARISONS),
 +        LintId::of(&double_parens::DOUBLE_PARENS),
 +        LintId::of(&duration_subsec::DURATION_SUBSEC),
 +        LintId::of(&eval_order_dependence::DIVERGING_SUB_EXPRESSION),
 +        LintId::of(&eval_order_dependence::EVAL_ORDER_DEPENDENCE),
 +        LintId::of(&explicit_write::EXPLICIT_WRITE),
 +        LintId::of(&format::USELESS_FORMAT),
 +        LintId::of(&functions::TOO_MANY_ARGUMENTS),
 +        LintId::of(&get_last_with_len::GET_LAST_WITH_LEN),
 +        LintId::of(&identity_op::IDENTITY_OP),
 +        LintId::of(&int_plus_one::INT_PLUS_ONE),
 +        LintId::of(&lifetimes::EXTRA_UNUSED_LIFETIMES),
 +        LintId::of(&lifetimes::NEEDLESS_LIFETIMES),
 +        LintId::of(&loops::EXPLICIT_COUNTER_LOOP),
 +        LintId::of(&loops::MUT_RANGE_BOUND),
 +        LintId::of(&loops::WHILE_LET_LOOP),
 +        LintId::of(&map_identity::MAP_IDENTITY),
 +        LintId::of(&map_unit_fn::OPTION_MAP_UNIT_FN),
 +        LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN),
 +        LintId::of(&matches::MATCH_AS_REF),
 +        LintId::of(&matches::MATCH_SINGLE_BINDING),
 +        LintId::of(&matches::WILDCARD_IN_OR_PATTERNS),
 +        LintId::of(&methods::BIND_INSTEAD_OF_MAP),
 +        LintId::of(&methods::CLONE_ON_COPY),
 +        LintId::of(&methods::FILTER_NEXT),
 +        LintId::of(&methods::FLAT_MAP_IDENTITY),
 +        LintId::of(&methods::OPTION_AS_REF_DEREF),
 +        LintId::of(&methods::SEARCH_IS_SOME),
 +        LintId::of(&methods::SKIP_WHILE_NEXT),
 +        LintId::of(&methods::SUSPICIOUS_MAP),
 +        LintId::of(&methods::UNNECESSARY_FILTER_MAP),
 +        LintId::of(&methods::USELESS_ASREF),
 +        LintId::of(&misc::SHORT_CIRCUIT_STATEMENT),
 +        LintId::of(&misc_early::UNNEEDED_WILDCARD_PATTERN),
 +        LintId::of(&misc_early::ZERO_PREFIXED_LITERAL),
 +        LintId::of(&needless_bool::BOOL_COMPARISON),
 +        LintId::of(&needless_bool::NEEDLESS_BOOL),
 +        LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
 +        LintId::of(&needless_update::NEEDLESS_UPDATE),
 +        LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
 +        LintId::of(&no_effect::NO_EFFECT),
 +        LintId::of(&no_effect::UNNECESSARY_OPERATION),
 +        LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
 +        LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL),
 +        LintId::of(&precedence::PRECEDENCE),
 +        LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
 +        LintId::of(&ranges::RANGE_ZIP_WITH_LEN),
++        LintId::of(&redundant_closure_call::REDUNDANT_CLOSURE_CALL),
 +        LintId::of(&reference::DEREF_ADDROF),
 +        LintId::of(&reference::REF_IN_DEREF),
 +        LintId::of(&repeat_once::REPEAT_ONCE),
 +        LintId::of(&swap::MANUAL_SWAP),
 +        LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT),
 +        LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),
 +        LintId::of(&transmute::TRANSMUTE_BYTES_TO_STR),
 +        LintId::of(&transmute::TRANSMUTE_FLOAT_TO_INT),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_BOOL),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_CHAR),
 +        LintId::of(&transmute::TRANSMUTE_INT_TO_FLOAT),
 +        LintId::of(&transmute::TRANSMUTE_PTR_TO_PTR),
 +        LintId::of(&transmute::TRANSMUTE_PTR_TO_REF),
 +        LintId::of(&types::BORROWED_BOX),
 +        LintId::of(&types::CHAR_LIT_AS_U8),
 +        LintId::of(&types::TYPE_COMPLEXITY),
 +        LintId::of(&types::UNIT_ARG),
 +        LintId::of(&types::UNNECESSARY_CAST),
 +        LintId::of(&types::VEC_BOX),
 +        LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
 +        LintId::of(&unwrap::UNNECESSARY_UNWRAP),
 +        LintId::of(&useless_conversion::USELESS_CONVERSION),
 +        LintId::of(&zero_div_zero::ZERO_DIVIDED_BY_ZERO),
 +    ]);
 +
 +    store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
 +        LintId::of(&approx_const::APPROX_CONSTANT),
 +        LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
 +        LintId::of(&attrs::DEPRECATED_SEMVER),
 +        LintId::of(&attrs::MISMATCHED_TARGET_OS),
 +        LintId::of(&attrs::USELESS_ATTRIBUTE),
 +        LintId::of(&bit_mask::BAD_BIT_MASK),
 +        LintId::of(&bit_mask::INEFFECTIVE_BIT_MASK),
 +        LintId::of(&booleans::LOGIC_BUG),
 +        LintId::of(&copies::IFS_SAME_COND),
 +        LintId::of(&copies::IF_SAME_THEN_ELSE),
 +        LintId::of(&derive::DERIVE_HASH_XOR_EQ),
 +        LintId::of(&drop_bounds::DROP_BOUNDS),
 +        LintId::of(&drop_forget_ref::DROP_COPY),
 +        LintId::of(&drop_forget_ref::DROP_REF),
 +        LintId::of(&drop_forget_ref::FORGET_COPY),
 +        LintId::of(&drop_forget_ref::FORGET_REF),
 +        LintId::of(&enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
 +        LintId::of(&eq_op::EQ_OP),
 +        LintId::of(&erasing_op::ERASING_OP),
 +        LintId::of(&formatting::POSSIBLE_MISSING_COMMA),
 +        LintId::of(&functions::NOT_UNSAFE_PTR_ARG_DEREF),
 +        LintId::of(&if_let_mutex::IF_LET_MUTEX),
 +        LintId::of(&indexing_slicing::OUT_OF_BOUNDS_INDEXING),
 +        LintId::of(&infinite_iter::INFINITE_ITER),
 +        LintId::of(&inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
 +        LintId::of(&inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
 +        LintId::of(&let_underscore::LET_UNDERSCORE_LOCK),
 +        LintId::of(&literal_representation::MISTYPED_LITERAL_SUFFIXES),
 +        LintId::of(&loops::FOR_LOOPS_OVER_FALLIBLES),
 +        LintId::of(&loops::ITER_NEXT_LOOP),
 +        LintId::of(&loops::NEVER_LOOP),
 +        LintId::of(&loops::WHILE_IMMUTABLE_CONDITION),
 +        LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
 +        LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
 +        LintId::of(&methods::CLONE_DOUBLE_REF),
 +        LintId::of(&methods::ITERATOR_STEP_BY_ZERO),
 +        LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
 +        LintId::of(&methods::UNINIT_ASSUMED_INIT),
 +        LintId::of(&methods::ZST_OFFSET),
 +        LintId::of(&minmax::MIN_MAX),
 +        LintId::of(&misc::CMP_NAN),
 +        LintId::of(&misc::FLOAT_CMP),
 +        LintId::of(&misc::MODULO_ONE),
 +        LintId::of(&mut_key::MUTABLE_KEY_TYPE),
 +        LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
 +        LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
 +        LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
 +        LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP),
 +        LintId::of(&ptr::MUT_FROM_REF),
 +        LintId::of(&ranges::REVERSED_EMPTY_RANGES),
 +        LintId::of(&regex::INVALID_REGEX),
 +        LintId::of(&serde_api::SERDE_API_MISUSE),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
 +        LintId::of(&swap::ALMOST_SWAPPED),
 +        LintId::of(&transmute::UNSOUND_COLLECTION_TRANSMUTE),
 +        LintId::of(&transmute::WRONG_TRANSMUTE),
 +        LintId::of(&transmuting_null::TRANSMUTING_NULL),
 +        LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
 +        LintId::of(&types::CAST_REF_TO_MUT),
 +        LintId::of(&types::UNIT_CMP),
 +        LintId::of(&unicode::ZERO_WIDTH_SPACE),
++        LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
 +        LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
 +        LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
 +        LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
 +        LintId::of(&unwrap::PANICKING_UNWRAP),
 +        LintId::of(&vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
 +    ]);
 +
 +    store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
 +        LintId::of(&bytecount::NAIVE_BYTECOUNT),
 +        LintId::of(&entry::MAP_ENTRY),
 +        LintId::of(&escape::BOXED_LOCAL),
 +        LintId::of(&large_const_arrays::LARGE_CONST_ARRAYS),
 +        LintId::of(&large_enum_variant::LARGE_ENUM_VARIANT),
 +        LintId::of(&loops::MANUAL_MEMCPY),
 +        LintId::of(&loops::NEEDLESS_COLLECT),
 +        LintId::of(&methods::EXPECT_FUN_CALL),
 +        LintId::of(&methods::ITER_NTH),
 +        LintId::of(&methods::OR_FUN_CALL),
 +        LintId::of(&methods::SINGLE_CHAR_PATTERN),
 +        LintId::of(&misc::CMP_OWNED),
 +        LintId::of(&mutex_atomic::MUTEX_ATOMIC),
 +        LintId::of(&redundant_clone::REDUNDANT_CLONE),
 +        LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
 +        LintId::of(&types::BOX_VEC),
 +        LintId::of(&types::REDUNDANT_ALLOCATION),
 +        LintId::of(&vec::USELESS_VEC),
 +    ]);
 +
 +    store.register_group(true, "clippy::cargo", Some("clippy_cargo"), vec![
 +        LintId::of(&cargo_common_metadata::CARGO_COMMON_METADATA),
 +        LintId::of(&multiple_crate_versions::MULTIPLE_CRATE_VERSIONS),
 +        LintId::of(&wildcard_dependencies::WILDCARD_DEPENDENCIES),
 +    ]);
 +
 +    store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
 +        LintId::of(&attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
 +        LintId::of(&cognitive_complexity::COGNITIVE_COMPLEXITY),
 +        LintId::of(&fallible_impl_from::FALLIBLE_IMPL_FROM),
 +        LintId::of(&floating_point_arithmetic::IMPRECISE_FLOPS),
 +        LintId::of(&floating_point_arithmetic::SUBOPTIMAL_FLOPS),
 +        LintId::of(&future_not_send::FUTURE_NOT_SEND),
 +        LintId::of(&let_if_seq::USELESS_LET_IF_SEQ),
 +        LintId::of(&missing_const_for_fn::MISSING_CONST_FOR_FN),
 +        LintId::of(&mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
 +        LintId::of(&mutex_atomic::MUTEX_INTEGER),
 +        LintId::of(&needless_borrow::NEEDLESS_BORROW),
 +        LintId::of(&path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
 +        LintId::of(&redundant_pub_crate::REDUNDANT_PUB_CRATE),
 +        LintId::of(&transmute::USELESS_TRANSMUTE),
 +        LintId::of(&use_self::USE_SELF),
 +    ]);
 +}
 +
 +#[rustfmt::skip]
 +fn register_removed_non_tool_lints(store: &mut rustc_lint::LintStore) {
 +    store.register_removed(
 +        "should_assert_eq",
 +        "`assert!()` will be more flexible with RFC 2011",
 +    );
 +    store.register_removed(
 +        "extend_from_slice",
 +        "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice",
 +    );
 +    store.register_removed(
 +        "range_step_by_zero",
 +        "`iterator.step_by(0)` panics nowadays",
 +    );
 +    store.register_removed(
 +        "unstable_as_slice",
 +        "`Vec::as_slice` has been stabilized in 1.7",
 +    );
 +    store.register_removed(
 +        "unstable_as_mut_slice",
 +        "`Vec::as_mut_slice` has been stabilized in 1.7",
 +    );
 +    store.register_removed(
 +        "str_to_string",
 +        "using `str::to_string` is common even today and specialization will likely happen soon",
 +    );
 +    store.register_removed(
 +        "string_to_string",
 +        "using `string::to_string` is common even today and specialization will likely happen soon",
 +    );
 +    store.register_removed(
 +        "misaligned_transmute",
 +        "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
 +    );
 +    store.register_removed(
 +        "assign_ops",
 +        "using compound assignment operators (e.g., `+=`) is harmless",
 +    );
 +    store.register_removed(
 +        "if_let_redundant_pattern_matching",
 +        "this lint has been changed to redundant_pattern_matching",
 +    );
 +    store.register_removed(
 +        "unsafe_vector_initialization",
 +        "the replacement suggested by this lint had substantially different behavior",
 +    );
 +    store.register_removed(
 +        "reverse_range_loop",
 +        "this lint is now included in reversed_empty_ranges",
 +    );
 +}
 +
 +/// Register renamed lints.
 +///
 +/// Used in `./src/driver.rs`.
 +pub fn register_renamed(ls: &mut rustc_lint::LintStore) {
 +    ls.register_renamed("clippy::stutter", "clippy::module_name_repetitions");
 +    ls.register_renamed("clippy::new_without_default_derive", "clippy::new_without_default");
 +    ls.register_renamed("clippy::cyclomatic_complexity", "clippy::cognitive_complexity");
 +    ls.register_renamed("clippy::const_static_lifetime", "clippy::redundant_static_lifetimes");
 +    ls.register_renamed("clippy::option_and_then_some", "clippy::bind_instead_of_map");
 +    ls.register_renamed("clippy::block_in_if_condition_expr", "clippy::blocks_in_if_conditions");
 +    ls.register_renamed("clippy::block_in_if_condition_stmt", "clippy::blocks_in_if_conditions");
 +    ls.register_renamed("clippy::option_map_unwrap_or", "clippy::map_unwrap_or");
 +    ls.register_renamed("clippy::option_map_unwrap_or_else", "clippy::map_unwrap_or");
 +    ls.register_renamed("clippy::result_map_unwrap_or_else", "clippy::map_unwrap_or");
 +    ls.register_renamed("clippy::option_unwrap_used", "clippy::unwrap_used");
 +    ls.register_renamed("clippy::result_unwrap_used", "clippy::unwrap_used");
 +    ls.register_renamed("clippy::option_expect_used", "clippy::expect_used");
 +    ls.register_renamed("clippy::result_expect_used", "clippy::expect_used");
 +    ls.register_renamed("clippy::for_loop_over_option", "clippy::for_loops_over_fallibles");
 +    ls.register_renamed("clippy::for_loop_over_result", "clippy::for_loops_over_fallibles");
 +    ls.register_renamed("clippy::identity_conversion", "clippy::useless_conversion");
 +}
 +
 +// only exists to let the dogfood integration test works.
 +// Don't run clippy as an executable directly
 +#[allow(dead_code)]
 +fn main() {
 +    panic!("Please use the cargo-clippy executable");
 +}
index ea6fb9e902576ee17d43ffd250a6b5277fd4fbfe,0000000000000000000000000000000000000000..be879dfe28d7038999be8b2be4f0314eb0457d02
mode 100644,000000..100644
--- /dev/null
@@@ -1,1699 -1,0 +1,1707 @@@
-                 let op_span = op.span.source_callsite();
 +use crate::consts::{constant, miri_to_const, Constant};
 +use crate::utils::paths;
 +use crate::utils::sugg::Sugg;
 +use crate::utils::usage::is_unused;
 +use crate::utils::{
 +    expr_block, get_arg_name, get_parent_expr, in_macro, indent_of, is_allowed, is_expn_of, is_refutable,
 +    is_type_diagnostic_item, is_wild, match_qpath, match_type, match_var, multispan_sugg, remove_blocks, snippet,
 +    snippet_block, snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg,
 +    span_lint_and_then, walk_ptrs_ty,
 +};
 +use if_chain::if_chain;
 +use rustc_ast::ast::LitKind;
 +use rustc_errors::Applicability;
 +use rustc_hir::def::CtorKind;
 +use rustc_hir::{
 +    Arm, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, Guard, Local, MatchSource, Mutability, Node, Pat,
 +    PatKind, QPath, RangeEnd,
 +};
 +use rustc_lint::{LateContext, LateLintPass, LintContext};
 +use rustc_middle::lint::in_external_macro;
 +use rustc_middle::ty::{self, Ty};
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_span::source_map::{Span, Spanned};
 +use std::cmp::Ordering;
 +use std::collections::Bound;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for matches with a single arm where an `if let`
 +    /// will usually suffice.
 +    ///
 +    /// **Why is this bad?** Just readability – `if let` nests less than a `match`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # fn bar(stool: &str) {}
 +    /// # let x = Some("abc");
 +    ///
 +    /// // Bad
 +    /// match x {
 +    ///     Some(ref foo) => bar(foo),
 +    ///     _ => (),
 +    /// }
 +    ///
 +    /// // Good
 +    /// if let Some(ref foo) = x {
 +    ///     bar(foo);
 +    /// }
 +    /// ```
 +    pub SINGLE_MATCH,
 +    style,
 +    "a `match` statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for matches with two arms where an `if let else` will
 +    /// usually suffice.
 +    ///
 +    /// **Why is this bad?** Just readability – `if let` nests less than a `match`.
 +    ///
 +    /// **Known problems:** Personal style preferences may differ.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// Using `match`:
 +    ///
 +    /// ```rust
 +    /// # fn bar(foo: &usize) {}
 +    /// # let other_ref: usize = 1;
 +    /// # let x: Option<&usize> = Some(&1);
 +    /// match x {
 +    ///     Some(ref foo) => bar(foo),
 +    ///     _ => bar(&other_ref),
 +    /// }
 +    /// ```
 +    ///
 +    /// Using `if let` with `else`:
 +    ///
 +    /// ```rust
 +    /// # fn bar(foo: &usize) {}
 +    /// # let other_ref: usize = 1;
 +    /// # let x: Option<&usize> = Some(&1);
 +    /// if let Some(ref foo) = x {
 +    ///     bar(foo);
 +    /// } else {
 +    ///     bar(&other_ref);
 +    /// }
 +    /// ```
 +    pub SINGLE_MATCH_ELSE,
 +    pedantic,
 +    "a `match` statement with two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for matches where all arms match a reference,
 +    /// suggesting to remove the reference and deref the matched expression
 +    /// instead. It also checks for `if let &foo = bar` blocks.
 +    ///
 +    /// **Why is this bad?** It just makes the code less readable. That reference
 +    /// destructuring adds nothing to the code.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust,ignore
 +    /// // Bad
 +    /// match x {
 +    ///     &A(ref y) => foo(y),
 +    ///     &B => bar(),
 +    ///     _ => frob(&x),
 +    /// }
 +    ///
 +    /// // Good
 +    /// match *x {
 +    ///     A(ref y) => foo(y),
 +    ///     B => bar(),
 +    ///     _ => frob(x),
 +    /// }
 +    /// ```
 +    pub MATCH_REF_PATS,
 +    style,
 +    "a `match` or `if let` with all arms prefixed with `&` instead of deref-ing the match expression"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for matches where match expression is a `bool`. It
 +    /// suggests to replace the expression with an `if...else` block.
 +    ///
 +    /// **Why is this bad?** It makes the code less readable.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # fn foo() {}
 +    /// # fn bar() {}
 +    /// let condition: bool = true;
 +    /// match condition {
 +    ///     true => foo(),
 +    ///     false => bar(),
 +    /// }
 +    /// ```
 +    /// Use if/else instead:
 +    /// ```rust
 +    /// # fn foo() {}
 +    /// # fn bar() {}
 +    /// let condition: bool = true;
 +    /// if condition {
 +    ///     foo();
 +    /// } else {
 +    ///     bar();
 +    /// }
 +    /// ```
 +    pub MATCH_BOOL,
 +    pedantic,
 +    "a `match` on a boolean expression instead of an `if..else` block"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for overlapping match arms.
 +    ///
 +    /// **Why is this bad?** It is likely to be an error and if not, makes the code
 +    /// less obvious.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x = 5;
 +    /// match x {
 +    ///     1...10 => println!("1 ... 10"),
 +    ///     5...15 => println!("5 ... 15"),
 +    ///     _ => (),
 +    /// }
 +    /// ```
 +    pub MATCH_OVERLAPPING_ARM,
 +    style,
 +    "a `match` with overlapping arms"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for arm which matches all errors with `Err(_)`
 +    /// and take drastic actions like `panic!`.
 +    ///
 +    /// **Why is this bad?** It is generally a bad practice, similar to
 +    /// catching all exceptions in java with `catch(Exception)`
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x: Result<i32, &str> = Ok(3);
 +    /// match x {
 +    ///     Ok(_) => println!("ok"),
 +    ///     Err(_) => panic!("err"),
 +    /// }
 +    /// ```
 +    pub MATCH_WILD_ERR_ARM,
 +    pedantic,
 +    "a `match` with `Err(_)` arm and take drastic actions"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for match which is used to add a reference to an
 +    /// `Option` value.
 +    ///
 +    /// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x: Option<()> = None;
 +    ///
 +    /// // Bad
 +    /// let r: Option<&()> = match x {
 +    ///     None => None,
 +    ///     Some(ref v) => Some(v),
 +    /// };
 +    ///
 +    /// // Good
 +    /// let r: Option<&()> = x.as_ref();
 +    /// ```
 +    pub MATCH_AS_REF,
 +    complexity,
 +    "a `match` on an Option value instead of using `as_ref()` or `as_mut`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for wildcard enum matches using `_`.
 +    ///
 +    /// **Why is this bad?** New enum variants added by library updates can be missed.
 +    ///
 +    /// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some
 +    /// variants, and also may not use correct path to enum if it's not present in the current scope.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # enum Foo { A(usize), B(usize) }
 +    /// # let x = Foo::B(1);
 +    ///
 +    /// // Bad
 +    /// match x {
 +    ///     Foo::A(_) => {},
 +    ///     _ => {},
 +    /// }
 +    ///
 +    /// // Good
 +    /// match x {
 +    ///     Foo::A(_) => {},
 +    ///     Foo::B(_) => {},
 +    /// }
 +    /// ```
 +    pub WILDCARD_ENUM_MATCH_ARM,
 +    restriction,
 +    "a wildcard enum match arm using `_`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for wildcard enum matches for a single variant.
 +    ///
 +    /// **Why is this bad?** New enum variants added by library updates can be missed.
 +    ///
 +    /// **Known problems:** Suggested replacements may not use correct path to enum
 +    /// if it's not present in the current scope.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # enum Foo { A, B, C }
 +    /// # let x = Foo::B;
 +    /// // Bad
 +    /// match x {
 +    ///     Foo::A => {},
 +    ///     Foo::B => {},
 +    ///     _ => {},
 +    /// }
 +    ///
 +    /// // Good
 +    /// match x {
 +    ///     Foo::A => {},
 +    ///     Foo::B => {},
 +    ///     Foo::C => {},
 +    /// }
 +    /// ```
 +    pub MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
 +    pedantic,
 +    "a wildcard enum match for a single variant"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for wildcard pattern used with others patterns in same match arm.
 +    ///
 +    /// **Why is this bad?** Wildcard pattern already covers any other pattern as it will match anyway.
 +    /// It makes the code less readable, especially to spot wildcard pattern use in match arm.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Bad
 +    /// match "foo" {
 +    ///     "a" => {},
 +    ///     "bar" | _ => {},
 +    /// }
 +    ///
 +    /// // Good
 +    /// match "foo" {
 +    ///     "a" => {},
 +    ///     _ => {},
 +    /// }
 +    /// ```
 +    pub WILDCARD_IN_OR_PATTERNS,
 +    complexity,
 +    "a wildcard pattern used with others patterns in same match arm"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for matches being used to destructure a single-variant enum
 +    /// or tuple struct where a `let` will suffice.
 +    ///
 +    /// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// enum Wrapper {
 +    ///     Data(i32),
 +    /// }
 +    ///
 +    /// let wrapper = Wrapper::Data(42);
 +    ///
 +    /// let data = match wrapper {
 +    ///     Wrapper::Data(i) => i,
 +    /// };
 +    /// ```
 +    ///
 +    /// The correct use would be:
 +    /// ```rust
 +    /// enum Wrapper {
 +    ///     Data(i32),
 +    /// }
 +    ///
 +    /// let wrapper = Wrapper::Data(42);
 +    /// let Wrapper::Data(data) = wrapper;
 +    /// ```
 +    pub INFALLIBLE_DESTRUCTURING_MATCH,
 +    style,
 +    "a `match` statement with a single infallible arm instead of a `let`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for useless match that binds to only one value.
 +    ///
 +    /// **Why is this bad?** Readability and needless complexity.
 +    ///
 +    /// **Known problems:**  Suggested replacements may be incorrect when `match`
 +    /// is actually binding temporary value, bringing a 'dropped while borrowed' error.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let a = 1;
 +    /// # let b = 2;
 +    ///
 +    /// // Bad
 +    /// match (a, b) {
 +    ///     (c, d) => {
 +    ///         // useless match
 +    ///     }
 +    /// }
 +    ///
 +    /// // Good
 +    /// let (c, d) = (a, b);
 +    /// ```
 +    pub MATCH_SINGLE_BINDING,
 +    complexity,
 +    "a match with a single binding instead of using `let` statement"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched.
 +    ///
 +    /// **Why is this bad?** Correctness and readability. It's like having a wildcard pattern after
 +    /// matching all enum variants explicitly.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct A { a: i32 }
 +    /// let a = A { a: 5 };
 +    ///
 +    /// // Bad
 +    /// match a {
 +    ///     A { a: 5, .. } => {},
 +    ///     _ => {},
 +    /// }
 +    ///
 +    /// // Good
 +    /// match a {
 +    ///     A { a: 5 } => {},
 +    ///     _ => {},
 +    /// }
 +    /// ```
 +    pub REST_PAT_IN_FULLY_BOUND_STRUCTS,
 +    restriction,
 +    "a match on a struct that binds all fields but still uses the wildcard pattern"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Lint for redundant pattern matching over `Result` or
 +    /// `Option`
 +    ///
 +    /// **Why is this bad?** It's more concise and clear to just use the proper
 +    /// utility function
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// if let Ok(_) = Ok::<i32, i32>(42) {}
 +    /// if let Err(_) = Err::<i32, i32>(42) {}
 +    /// if let None = None::<()> {}
 +    /// if let Some(_) = Some(42) {}
 +    /// match Ok::<i32, i32>(42) {
 +    ///     Ok(_) => true,
 +    ///     Err(_) => false,
 +    /// };
 +    /// ```
 +    ///
 +    /// The more idiomatic use would be:
 +    ///
 +    /// ```rust
 +    /// if Ok::<i32, i32>(42).is_ok() {}
 +    /// if Err::<i32, i32>(42).is_err() {}
 +    /// if None::<()>.is_none() {}
 +    /// if Some(42).is_some() {}
 +    /// Ok::<i32, i32>(42).is_ok();
 +    /// ```
 +    pub REDUNDANT_PATTERN_MATCHING,
 +    style,
 +    "use the proper utility function avoiding an `if let`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `match`  or `if let` expressions producing a
 +    /// `bool` that could be written using `matches!`
 +    ///
 +    /// **Why is this bad?** Readability and needless complexity.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x = Some(5);
 +    ///
 +    /// // Bad
 +    /// let a = match x {
 +    ///     Some(0) => true,
 +    ///     _ => false,
 +    /// };
 +    ///
 +    /// let a = if let Some(0) = x {
 +    ///     true
 +    /// } else {
 +    ///     false
 +    /// };
 +    ///
 +    /// // Good
 +    /// let a = matches!(x, Some(0));
 +    /// ```
 +    pub MATCH_LIKE_MATCHES_MACRO,
 +    style,
 +    "a match that could be written with the matches! macro"
 +}
 +
 +#[derive(Default)]
 +pub struct Matches {
 +    infallible_destructuring_match_linted: bool,
 +}
 +
 +impl_lint_pass!(Matches => [
 +    SINGLE_MATCH,
 +    MATCH_REF_PATS,
 +    MATCH_BOOL,
 +    SINGLE_MATCH_ELSE,
 +    MATCH_OVERLAPPING_ARM,
 +    MATCH_WILD_ERR_ARM,
 +    MATCH_AS_REF,
 +    WILDCARD_ENUM_MATCH_ARM,
 +    MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
 +    WILDCARD_IN_OR_PATTERNS,
 +    MATCH_SINGLE_BINDING,
 +    INFALLIBLE_DESTRUCTURING_MATCH,
 +    REST_PAT_IN_FULLY_BOUND_STRUCTS,
 +    REDUNDANT_PATTERN_MATCHING,
 +    MATCH_LIKE_MATCHES_MACRO
 +]);
 +
 +impl<'tcx> LateLintPass<'tcx> for Matches {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if in_external_macro(cx.sess(), expr.span) {
 +            return;
 +        }
 +
 +        redundant_pattern_match::check(cx, expr);
 +        check_match_like_matches(cx, expr);
 +
 +        if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind {
 +            check_single_match(cx, ex, arms, expr);
 +            check_match_bool(cx, ex, arms, expr);
 +            check_overlapping_arms(cx, ex, arms);
 +            check_wild_err_arm(cx, ex, arms);
 +            check_wild_enum_match(cx, ex, arms);
 +            check_match_as_ref(cx, ex, arms, expr);
 +            check_wild_in_or_pats(cx, arms);
 +
 +            if self.infallible_destructuring_match_linted {
 +                self.infallible_destructuring_match_linted = false;
 +            } else {
 +                check_match_single_binding(cx, ex, arms, expr);
 +            }
 +        }
 +        if let ExprKind::Match(ref ex, ref arms, _) = expr.kind {
 +            check_match_ref_pats(cx, ex, arms, expr);
 +        }
 +    }
 +
 +    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
 +        if_chain! {
 +            if !in_external_macro(cx.sess(), local.span);
 +            if !in_macro(local.span);
 +            if let Some(ref expr) = local.init;
 +            if let ExprKind::Match(ref target, ref arms, MatchSource::Normal) = expr.kind;
 +            if arms.len() == 1 && arms[0].guard.is_none();
 +            if let PatKind::TupleStruct(
 +                QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pat.kind;
 +            if args.len() == 1;
 +            if let Some(arg) = get_arg_name(&args[0]);
 +            let body = remove_blocks(&arms[0].body);
 +            if match_var(body, arg);
 +
 +            then {
 +                let mut applicability = Applicability::MachineApplicable;
 +                self.infallible_destructuring_match_linted = true;
 +                span_lint_and_sugg(
 +                    cx,
 +                    INFALLIBLE_DESTRUCTURING_MATCH,
 +                    local.span,
 +                    "you seem to be trying to use `match` to destructure a single infallible pattern. \
 +                    Consider using `let`",
 +                    "try this",
 +                    format!(
 +                        "let {}({}) = {};",
 +                        snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
 +                        snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
 +                        snippet_with_applicability(cx, target.span, "..", &mut applicability),
 +                    ),
 +                    applicability,
 +                );
 +            }
 +        }
 +    }
 +
 +    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
 +        if_chain! {
 +            if !in_external_macro(cx.sess(), pat.span);
 +            if !in_macro(pat.span);
 +            if let PatKind::Struct(ref qpath, fields, true) = pat.kind;
 +            if let QPath::Resolved(_, ref path) = qpath;
 +            if let Some(def_id) = path.res.opt_def_id();
 +            let ty = cx.tcx.type_of(def_id);
 +            if let ty::Adt(def, _) = ty.kind;
 +            if def.is_struct() || def.is_union();
 +            if fields.len() == def.non_enum_variant().fields.len();
 +
 +            then {
 +                span_lint_and_help(
 +                    cx,
 +                    REST_PAT_IN_FULLY_BOUND_STRUCTS,
 +                    pat.span,
 +                    "unnecessary use of `..` pattern in struct binding. All fields were already bound",
 +                    None,
 +                    "consider removing `..` from this binding",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +#[rustfmt::skip]
 +fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
 +    if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
 +        if in_macro(expr.span) {
 +            // Don't lint match expressions present in
 +            // macro_rules! block
 +            return;
 +        }
 +        if let PatKind::Or(..) = arms[0].pat.kind {
 +            // don't lint for or patterns for now, this makes
 +            // the lint noisy in unnecessary situations
 +            return;
 +        }
 +        let els = arms[1].body;
 +        let els = if is_unit_expr(remove_blocks(els)) {
 +            None
 +        } else if let ExprKind::Block(Block { stmts, expr: block_expr, .. }, _) = els.kind {
 +            if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() {
 +                // single statement/expr "else" block, don't lint
 +                return;
 +            } else {
 +                // block with 2+ statements or 1 expr and 1+ statement
 +                Some(els)
 +            }
 +        } else {
 +            // not a block, don't lint
 +            return; 
 +        };
 +
 +        let ty = cx.typeck_results().expr_ty(ex);
 +        if ty.kind != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.hir_id) {
 +            check_single_match_single_pattern(cx, ex, arms, expr, els);
 +            check_single_match_opt_like(cx, ex, arms, expr, ty, els);
 +        }
 +    }
 +}
 +
 +fn check_single_match_single_pattern(
 +    cx: &LateContext<'_>,
 +    ex: &Expr<'_>,
 +    arms: &[Arm<'_>],
 +    expr: &Expr<'_>,
 +    els: Option<&Expr<'_>>,
 +) {
 +    if is_wild(&arms[1].pat) {
 +        report_single_match_single_pattern(cx, ex, arms, expr, els);
 +    }
 +}
 +
 +fn report_single_match_single_pattern(
 +    cx: &LateContext<'_>,
 +    ex: &Expr<'_>,
 +    arms: &[Arm<'_>],
 +    expr: &Expr<'_>,
 +    els: Option<&Expr<'_>>,
 +) {
 +    let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH };
 +    let els_str = els.map_or(String::new(), |els| {
 +        format!(" else {}", expr_block(cx, els, None, "..", Some(expr.span)))
 +    });
 +    span_lint_and_sugg(
 +        cx,
 +        lint,
 +        expr.span,
 +        "you seem to be trying to use match for destructuring a single pattern. Consider using `if \
 +         let`",
 +        "try this",
 +        format!(
 +            "if let {} = {} {}{}",
 +            snippet(cx, arms[0].pat.span, ".."),
 +            snippet(cx, ex.span, ".."),
 +            expr_block(cx, &arms[0].body, None, "..", Some(expr.span)),
 +            els_str,
 +        ),
 +        Applicability::HasPlaceholders,
 +    );
 +}
 +
 +fn check_single_match_opt_like(
 +    cx: &LateContext<'_>,
 +    ex: &Expr<'_>,
 +    arms: &[Arm<'_>],
 +    expr: &Expr<'_>,
 +    ty: Ty<'_>,
 +    els: Option<&Expr<'_>>,
 +) {
 +    // list of candidate `Enum`s we know will never get any more members
 +    let candidates = &[
 +        (&paths::COW, "Borrowed"),
 +        (&paths::COW, "Cow::Borrowed"),
 +        (&paths::COW, "Cow::Owned"),
 +        (&paths::COW, "Owned"),
 +        (&paths::OPTION, "None"),
 +        (&paths::RESULT, "Err"),
 +        (&paths::RESULT, "Ok"),
 +    ];
 +
 +    let path = match arms[1].pat.kind {
 +        PatKind::TupleStruct(ref path, ref inner, _) => {
 +            // Contains any non wildcard patterns (e.g., `Err(err)`)?
 +            if !inner.iter().all(is_wild) {
 +                return;
 +            }
 +            rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false))
 +        },
 +        PatKind::Binding(BindingAnnotation::Unannotated, .., ident, None) => ident.to_string(),
 +        PatKind::Path(ref path) => {
 +            rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false))
 +        },
 +        _ => return,
 +    };
 +
 +    for &(ty_path, pat_path) in candidates {
 +        if path == *pat_path && match_type(cx, ty, ty_path) {
 +            report_single_match_single_pattern(cx, ex, arms, expr, els);
 +        }
 +    }
 +}
 +
 +fn check_match_bool(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
 +    // Type of expression is `bool`.
 +    if cx.typeck_results().expr_ty(ex).kind == ty::Bool {
 +        span_lint_and_then(
 +            cx,
 +            MATCH_BOOL,
 +            expr.span,
 +            "you seem to be trying to match on a boolean expression",
 +            move |diag| {
 +                if arms.len() == 2 {
 +                    // no guards
 +                    let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pat.kind {
 +                        if let ExprKind::Lit(ref lit) = arm_bool.kind {
 +                            match lit.node {
 +                                LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
 +                                LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
 +                                _ => None,
 +                            }
 +                        } else {
 +                            None
 +                        }
 +                    } else {
 +                        None
 +                    };
 +
 +                    if let Some((true_expr, false_expr)) = exprs {
 +                        let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
 +                            (false, false) => Some(format!(
 +                                "if {} {} else {}",
 +                                snippet(cx, ex.span, "b"),
 +                                expr_block(cx, true_expr, None, "..", Some(expr.span)),
 +                                expr_block(cx, false_expr, None, "..", Some(expr.span))
 +                            )),
 +                            (false, true) => Some(format!(
 +                                "if {} {}",
 +                                snippet(cx, ex.span, "b"),
 +                                expr_block(cx, true_expr, None, "..", Some(expr.span))
 +                            )),
 +                            (true, false) => {
 +                                let test = Sugg::hir(cx, ex, "..");
 +                                Some(format!(
 +                                    "if {} {}",
 +                                    !test,
 +                                    expr_block(cx, false_expr, None, "..", Some(expr.span))
 +                                ))
 +                            },
 +                            (true, true) => None,
 +                        };
 +
 +                        if let Some(sugg) = sugg {
 +                            diag.span_suggestion(
 +                                expr.span,
 +                                "consider using an `if`/`else` expression",
 +                                sugg,
 +                                Applicability::HasPlaceholders,
 +                            );
 +                        }
 +                    }
 +                }
 +            },
 +        );
 +    }
 +}
 +
 +fn check_overlapping_arms<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
 +    if arms.len() >= 2 && cx.typeck_results().expr_ty(ex).is_integral() {
 +        let ranges = all_ranges(cx, arms, cx.typeck_results().expr_ty(ex));
 +        let type_ranges = type_ranges(&ranges);
 +        if !type_ranges.is_empty() {
 +            if let Some((start, end)) = overlapping(&type_ranges) {
 +                span_lint_and_note(
 +                    cx,
 +                    MATCH_OVERLAPPING_ARM,
 +                    start.span,
 +                    "some ranges overlap",
 +                    Some(end.span),
 +                    "overlaps with this",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +fn check_wild_err_arm(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
 +    let ex_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(ex));
 +    if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) {
 +        for arm in arms {
 +            if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.kind {
 +                let path_str = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false));
 +                if path_str == "Err" {
 +                    let mut matching_wild = inner.iter().any(is_wild);
 +                    let mut ident_bind_name = String::from("_");
 +                    if !matching_wild {
 +                        // Looking for unused bindings (i.e.: `_e`)
 +                        inner.iter().for_each(|pat| {
 +                            if let PatKind::Binding(.., ident, None) = &pat.kind {
 +                                if ident.as_str().starts_with('_') && is_unused(ident, arm.body) {
 +                                    ident_bind_name = (&ident.name.as_str()).to_string();
 +                                    matching_wild = true;
 +                                }
 +                            }
 +                        });
 +                    }
 +                    if_chain! {
 +                        if matching_wild;
 +                        if let ExprKind::Block(ref block, _) = arm.body.kind;
 +                        if is_panic_block(block);
 +                        then {
 +                            // `Err(_)` or `Err(_e)` arm with `panic!` found
 +                            span_lint_and_note(cx,
 +                                MATCH_WILD_ERR_ARM,
 +                                arm.pat.span,
 +                                &format!("`Err({})` matches all errors", &ident_bind_name),
 +                                None,
 +                                "match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable",
 +                            );
 +                        }
 +                    }
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
 +    let ty = cx.typeck_results().expr_ty(ex);
 +    if !ty.is_enum() {
 +        // If there isn't a nice closed set of possible values that can be conveniently enumerated,
 +        // don't complain about not enumerating the mall.
 +        return;
 +    }
 +
 +    // First pass - check for violation, but don't do much book-keeping because this is hopefully
 +    // the uncommon case, and the book-keeping is slightly expensive.
 +    let mut wildcard_span = None;
 +    let mut wildcard_ident = None;
 +    for arm in arms {
 +        if let PatKind::Wild = arm.pat.kind {
 +            wildcard_span = Some(arm.pat.span);
 +        } else if let PatKind::Binding(_, _, ident, None) = arm.pat.kind {
 +            wildcard_span = Some(arm.pat.span);
 +            wildcard_ident = Some(ident);
 +        }
 +    }
 +
 +    if let Some(wildcard_span) = wildcard_span {
 +        // Accumulate the variants which should be put in place of the wildcard because they're not
 +        // already covered.
 +
 +        let mut missing_variants = vec![];
 +        if let ty::Adt(def, _) = ty.kind {
 +            for variant in &def.variants {
 +                missing_variants.push(variant);
 +            }
 +        }
 +
 +        for arm in arms {
 +            if arm.guard.is_some() {
 +                // Guards mean that this case probably isn't exhaustively covered. Technically
 +                // this is incorrect, as we should really check whether each variant is exhaustively
 +                // covered by the set of guards that cover it, but that's really hard to do.
 +                continue;
 +            }
 +            if let PatKind::Path(ref path) = arm.pat.kind {
 +                if let QPath::Resolved(_, p) = path {
 +                    missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
 +                }
 +            } else if let PatKind::TupleStruct(ref path, ref patterns, ..) = arm.pat.kind {
 +                if let QPath::Resolved(_, p) = path {
 +                    // Some simple checks for exhaustive patterns.
 +                    // There is a room for improvements to detect more cases,
 +                    // but it can be more expensive to do so.
 +                    let is_pattern_exhaustive =
 +                        |pat: &&Pat<'_>| matches!(pat.kind, PatKind::Wild | PatKind::Binding(.., None));
 +                    if patterns.iter().all(is_pattern_exhaustive) {
 +                        missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
 +                    }
 +                }
 +            }
 +        }
 +
 +        let mut suggestion: Vec<String> = missing_variants
 +            .iter()
 +            .map(|v| {
 +                let suffix = match v.ctor_kind {
 +                    CtorKind::Fn => "(..)",
 +                    CtorKind::Const | CtorKind::Fictive => "",
 +                };
 +                let ident_str = if let Some(ident) = wildcard_ident {
 +                    format!("{} @ ", ident.name)
 +                } else {
 +                    String::new()
 +                };
 +                // This path assumes that the enum type is imported into scope.
 +                format!("{}{}{}", ident_str, cx.tcx.def_path_str(v.def_id), suffix)
 +            })
 +            .collect();
 +
 +        if suggestion.is_empty() {
 +            return;
 +        }
 +
 +        let mut message = "wildcard match will miss any future added variants";
 +
 +        if let ty::Adt(def, _) = ty.kind {
 +            if def.is_variant_list_non_exhaustive() {
 +                message = "match on non-exhaustive enum doesn't explicitly match all known variants";
 +                suggestion.push(String::from("_"));
 +            }
 +        }
 +
 +        if suggestion.len() == 1 {
 +            // No need to check for non-exhaustive enum as in that case len would be greater than 1
 +            span_lint_and_sugg(
 +                cx,
 +                MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
 +                wildcard_span,
 +                message,
 +                "try this",
 +                suggestion[0].clone(),
 +                Applicability::MaybeIncorrect,
 +            )
 +        };
 +
 +        span_lint_and_sugg(
 +            cx,
 +            WILDCARD_ENUM_MATCH_ARM,
 +            wildcard_span,
 +            message,
 +            "try this",
 +            suggestion.join(" | "),
 +            Applicability::MaybeIncorrect,
 +        )
 +    }
 +}
 +
 +// If the block contains only a `panic!` macro (as expression or statement)
 +fn is_panic_block(block: &Block<'_>) -> bool {
 +    match (&block.expr, block.stmts.len(), block.stmts.first()) {
 +        (&Some(ref exp), 0, _) => {
 +            is_expn_of(exp.span, "panic").is_some() && is_expn_of(exp.span, "unreachable").is_none()
 +        },
 +        (&None, 1, Some(stmt)) => {
 +            is_expn_of(stmt.span, "panic").is_some() && is_expn_of(stmt.span, "unreachable").is_none()
 +        },
 +        _ => false,
 +    }
 +}
 +
 +fn check_match_ref_pats(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
 +    if has_only_ref_pats(arms) {
 +        let mut suggs = Vec::with_capacity(arms.len() + 1);
 +        let (title, msg) = if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = ex.kind {
 +            let span = ex.span.source_callsite();
 +            suggs.push((span, Sugg::hir_with_macro_callsite(cx, inner, "..").to_string()));
 +            (
 +                "you don't need to add `&` to both the expression and the patterns",
 +                "try",
 +            )
 +        } else {
 +            let span = ex.span.source_callsite();
 +            suggs.push((span, Sugg::hir_with_macro_callsite(cx, ex, "..").deref().to_string()));
 +            (
 +                "you don't need to add `&` to all patterns",
 +                "instead of prefixing all patterns with `&`, you can dereference the expression",
 +            )
 +        };
 +
 +        suggs.extend(arms.iter().filter_map(|a| {
 +            if let PatKind::Ref(ref refp, _) = a.pat.kind {
 +                Some((a.pat.span, snippet(cx, refp.span, "..").to_string()))
 +            } else {
 +                None
 +            }
 +        }));
 +
 +        span_lint_and_then(cx, MATCH_REF_PATS, expr.span, title, |diag| {
 +            if !expr.span.from_expansion() {
 +                multispan_sugg(diag, msg, suggs);
 +            }
 +        });
 +    }
 +}
 +
 +fn check_match_as_ref(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
 +    if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
 +        let arm_ref: Option<BindingAnnotation> = if is_none_arm(&arms[0]) {
 +            is_ref_some_arm(&arms[1])
 +        } else if is_none_arm(&arms[1]) {
 +            is_ref_some_arm(&arms[0])
 +        } else {
 +            None
 +        };
 +        if let Some(rb) = arm_ref {
 +            let suggestion = if rb == BindingAnnotation::Ref {
 +                "as_ref"
 +            } else {
 +                "as_mut"
 +            };
 +
 +            let output_ty = cx.typeck_results().expr_ty(expr);
 +            let input_ty = cx.typeck_results().expr_ty(ex);
 +
 +            let cast = if_chain! {
 +                if let ty::Adt(_, substs) = input_ty.kind;
 +                let input_ty = substs.type_at(0);
 +                if let ty::Adt(_, substs) = output_ty.kind;
 +                let output_ty = substs.type_at(0);
 +                if let ty::Ref(_, output_ty, _) = output_ty.kind;
 +                if input_ty != output_ty;
 +                then {
 +                    ".map(|x| x as _)"
 +                } else {
 +                    ""
 +                }
 +            };
 +
 +            let mut applicability = Applicability::MachineApplicable;
 +            span_lint_and_sugg(
 +                cx,
 +                MATCH_AS_REF,
 +                expr.span,
 +                &format!("use `{}()` instead", suggestion),
 +                "try this",
 +                format!(
 +                    "{}.{}(){}",
 +                    snippet_with_applicability(cx, ex.span, "_", &mut applicability),
 +                    suggestion,
 +                    cast,
 +                ),
 +                applicability,
 +            )
 +        }
 +    }
 +}
 +
 +fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
 +    for arm in arms {
 +        if let PatKind::Or(ref fields) = arm.pat.kind {
 +            // look for multiple fields in this arm that contains at least one Wild pattern
 +            if fields.len() > 1 && fields.iter().any(is_wild) {
 +                span_lint_and_help(
 +                    cx,
 +                    WILDCARD_IN_OR_PATTERNS,
 +                    arm.pat.span,
 +                    "wildcard pattern covers any other pattern as it will match anyway.",
 +                    None,
 +                    "Consider handling `_` separately.",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +/// Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!`
 +fn check_match_like_matches<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +    if let ExprKind::Match(ex, arms, ref match_source) = &expr.kind {
 +        match match_source {
 +            MatchSource::Normal => find_matches_sugg(cx, ex, arms, expr, false),
 +            MatchSource::IfLetDesugar { .. } => find_matches_sugg(cx, ex, arms, expr, true),
 +            _ => return,
 +        }
 +    }
 +}
 +
 +/// Lint a `match` or desugared `if let` for replacement by `matches!`
 +fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, desugared: bool) {
 +    if_chain! {
 +        if arms.len() == 2;
 +        if cx.typeck_results().expr_ty(expr).is_bool();
 +        if is_wild(&arms[1].pat);
 +        if let Some(first) = find_bool_lit(&arms[0].body.kind, desugared);
 +        if let Some(second) = find_bool_lit(&arms[1].body.kind, desugared);
 +        if first != second;
 +        then {
 +            let mut applicability = Applicability::MachineApplicable;
 +
 +            let pat_and_guard = if let Some(Guard::If(g)) = arms[0].guard {
 +                format!("{} if {}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), snippet_with_applicability(cx, g.span, "..", &mut applicability))
 +            } else {
 +                format!("{}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability))
 +            };
 +            span_lint_and_sugg(
 +                cx,
 +                MATCH_LIKE_MATCHES_MACRO,
 +                expr.span,
 +                &format!("{} expression looks like `matches!` macro", if desugared { "if let .. else" } else { "match" }),
 +                "try this",
 +                format!(
 +                    "{}matches!({}, {})",
 +                    if first { "" } else { "!" },
 +                    snippet_with_applicability(cx, ex.span, "..", &mut applicability),
 +                    pat_and_guard,
 +                ),
 +                applicability,
 +            )
 +        }
 +    }
 +}
 +
 +/// Extract a `bool` or `{ bool }`
 +fn find_bool_lit(ex: &ExprKind<'_>, desugared: bool) -> Option<bool> {
 +    match ex {
 +        ExprKind::Lit(Spanned {
 +            node: LitKind::Bool(b), ..
 +        }) => Some(*b),
 +        ExprKind::Block(
 +            rustc_hir::Block {
 +                stmts: &[],
 +                expr: Some(exp),
 +                ..
 +            },
 +            _,
 +        ) if desugared => {
 +            if let ExprKind::Lit(Spanned {
 +                node: LitKind::Bool(b), ..
 +            }) = exp.kind
 +            {
 +                Some(b)
 +            } else {
 +                None
 +            }
 +        },
 +        _ => None,
 +    }
 +}
 +
 +fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) {
 +    if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
 +        return;
 +    }
 +    let matched_vars = ex.span;
 +    let bind_names = arms[0].pat.span;
 +    let match_body = remove_blocks(&arms[0].body);
 +    let mut snippet_body = if match_body.span.from_expansion() {
 +        Sugg::hir_with_macro_callsite(cx, match_body, "..").to_string()
 +    } else {
 +        snippet_block(cx, match_body.span, "..", Some(expr.span)).to_string()
 +    };
 +
 +    // Do we need to add ';' to suggestion ?
 +    match match_body.kind {
 +        ExprKind::Block(block, _) => {
 +            // macro + expr_ty(body) == ()
 +            if block.span.from_expansion() && cx.typeck_results().expr_ty(&match_body).is_unit() {
 +                snippet_body.push(';');
 +            }
 +        },
 +        _ => {
 +            // expr_ty(body) == ()
 +            if cx.typeck_results().expr_ty(&match_body).is_unit() {
 +                snippet_body.push(';');
 +            }
 +        },
 +    }
 +
 +    let mut applicability = Applicability::MaybeIncorrect;
 +    match arms[0].pat.kind {
 +        PatKind::Binding(..) | PatKind::Tuple(_, _) | PatKind::Struct(..) => {
 +            // If this match is in a local (`let`) stmt
 +            let (target_span, sugg) = if let Some(parent_let_node) = opt_parent_let(cx, ex) {
 +                (
 +                    parent_let_node.span,
 +                    format!(
 +                        "let {} = {};\n{}let {} = {};",
 +                        snippet_with_applicability(cx, bind_names, "..", &mut applicability),
 +                        snippet_with_applicability(cx, matched_vars, "..", &mut applicability),
 +                        " ".repeat(indent_of(cx, expr.span).unwrap_or(0)),
 +                        snippet_with_applicability(cx, parent_let_node.pat.span, "..", &mut applicability),
 +                        snippet_body
 +                    ),
 +                )
 +            } else {
 +                // If we are in closure, we need curly braces around suggestion
 +                let mut indent = " ".repeat(indent_of(cx, ex.span).unwrap_or(0));
 +                let (mut cbrace_start, mut cbrace_end) = ("".to_string(), "".to_string());
 +                if let Some(parent_expr) = get_parent_expr(cx, expr) {
 +                    if let ExprKind::Closure(..) = parent_expr.kind {
 +                        cbrace_end = format!("\n{}}}", indent);
 +                        // Fix body indent due to the closure
 +                        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
 +                        cbrace_start = format!("{{\n{}", indent);
 +                    }
 +                };
 +                (
 +                    expr.span,
 +                    format!(
 +                        "{}let {} = {};\n{}{}{}",
 +                        cbrace_start,
 +                        snippet_with_applicability(cx, bind_names, "..", &mut applicability),
 +                        snippet_with_applicability(cx, matched_vars, "..", &mut applicability),
 +                        indent,
 +                        snippet_body,
 +                        cbrace_end
 +                    ),
 +                )
 +            };
 +            span_lint_and_sugg(
 +                cx,
 +                MATCH_SINGLE_BINDING,
 +                target_span,
 +                "this match could be written as a `let` statement",
 +                "consider using `let` statement",
 +                sugg,
 +                applicability,
 +            );
 +        },
 +        PatKind::Wild => {
 +            span_lint_and_sugg(
 +                cx,
 +                MATCH_SINGLE_BINDING,
 +                expr.span,
 +                "this match could be replaced by its body itself",
 +                "consider using the match body instead",
 +                snippet_body,
 +                Applicability::MachineApplicable,
 +            );
 +        },
 +        _ => (),
 +    }
 +}
 +
 +/// Returns true if the `ex` match expression is in a local (`let`) statement
 +fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'a>> {
 +    if_chain! {
 +        let map = &cx.tcx.hir();
 +        if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id));
 +        if let Some(Node::Local(parent_let_expr)) = map.find(map.get_parent_node(parent_arm_expr.hir_id));
 +        then {
 +            return Some(parent_let_expr);
 +        }
 +    }
 +    None
 +}
 +
 +/// Gets all arms that are unbounded `PatRange`s.
 +fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) -> Vec<SpannedRange<Constant>> {
 +    arms.iter()
 +        .flat_map(|arm| {
 +            if let Arm {
 +                ref pat, guard: None, ..
 +            } = *arm
 +            {
 +                if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind {
 +                    let lhs = match lhs {
 +                        Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0,
 +                        None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?,
 +                    };
 +                    let rhs = match rhs {
 +                        Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0,
 +                        None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?,
 +                    };
 +                    let rhs = match range_end {
 +                        RangeEnd::Included => Bound::Included(rhs),
 +                        RangeEnd::Excluded => Bound::Excluded(rhs),
 +                    };
 +                    return Some(SpannedRange {
 +                        span: pat.span,
 +                        node: (lhs, rhs),
 +                    });
 +                }
 +
 +                if let PatKind::Lit(ref value) = pat.kind {
 +                    let value = constant(cx, cx.typeck_results(), value)?.0;
 +                    return Some(SpannedRange {
 +                        span: pat.span,
 +                        node: (value.clone(), Bound::Included(value)),
 +                    });
 +                }
 +            }
 +            None
 +        })
 +        .collect()
 +}
 +
 +#[derive(Debug, Eq, PartialEq)]
 +pub struct SpannedRange<T> {
 +    pub span: Span,
 +    pub node: (T, Bound<T>),
 +}
 +
 +type TypedRanges = Vec<SpannedRange<u128>>;
 +
 +/// Gets all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
 +/// and other types than
 +/// `Uint` and `Int` probably don't make sense.
 +fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {
 +    ranges
 +        .iter()
 +        .filter_map(|range| match range.node {
 +            (Constant::Int(start), Bound::Included(Constant::Int(end))) => Some(SpannedRange {
 +                span: range.span,
 +                node: (start, Bound::Included(end)),
 +            }),
 +            (Constant::Int(start), Bound::Excluded(Constant::Int(end))) => Some(SpannedRange {
 +                span: range.span,
 +                node: (start, Bound::Excluded(end)),
 +            }),
 +            (Constant::Int(start), Bound::Unbounded) => Some(SpannedRange {
 +                span: range.span,
 +                node: (start, Bound::Unbounded),
 +            }),
 +            _ => None,
 +        })
 +        .collect()
 +}
 +
 +fn is_unit_expr(expr: &Expr<'_>) -> bool {
 +    match expr.kind {
 +        ExprKind::Tup(ref v) if v.is_empty() => true,
 +        ExprKind::Block(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true,
 +        _ => false,
 +    }
 +}
 +
 +// Checks if arm has the form `None => None`
 +fn is_none_arm(arm: &Arm<'_>) -> bool {
 +    matches!(arm.pat.kind, PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE))
 +}
 +
 +// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
 +fn is_ref_some_arm(arm: &Arm<'_>) -> Option<BindingAnnotation> {
 +    if_chain! {
 +        if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pat.kind;
 +        if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
 +        if let PatKind::Binding(rb, .., ident, _) = pats[0].kind;
 +        if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
 +        if let ExprKind::Call(ref e, ref args) = remove_blocks(&arm.body).kind;
 +        if let ExprKind::Path(ref some_path) = e.kind;
 +        if match_qpath(some_path, &paths::OPTION_SOME) && args.len() == 1;
 +        if let ExprKind::Path(ref qpath) = args[0].kind;
 +        if let &QPath::Resolved(_, ref path2) = qpath;
 +        if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
 +        then {
 +            return Some(rb)
 +        }
 +    }
 +    None
 +}
 +
 +fn has_only_ref_pats(arms: &[Arm<'_>]) -> bool {
 +    let mapped = arms
 +        .iter()
 +        .map(|a| {
 +            match a.pat.kind {
 +                PatKind::Ref(..) => Some(true), // &-patterns
 +                PatKind::Wild => Some(false),   // an "anything" wildcard is also fine
 +                _ => None,                      // any other pattern is not fine
 +            }
 +        })
 +        .collect::<Option<Vec<bool>>>();
 +    // look for Some(v) where there's at least one true element
 +    mapped.map_or(false, |v| v.iter().any(|el| *el))
 +}
 +
 +pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &SpannedRange<T>)>
 +where
 +    T: Copy + Ord,
 +{
 +    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 +    enum Kind<'a, T> {
 +        Start(T, &'a SpannedRange<T>),
 +        End(Bound<T>, &'a SpannedRange<T>),
 +    }
 +
 +    impl<'a, T: Copy> Kind<'a, T> {
 +        fn range(&self) -> &'a SpannedRange<T> {
 +            match *self {
 +                Kind::Start(_, r) | Kind::End(_, r) => r,
 +            }
 +        }
 +
 +        fn value(self) -> Bound<T> {
 +            match self {
 +                Kind::Start(t, _) => Bound::Included(t),
 +                Kind::End(t, _) => t,
 +            }
 +        }
 +    }
 +
 +    impl<'a, T: Copy + Ord> PartialOrd for Kind<'a, T> {
 +        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 +            Some(self.cmp(other))
 +        }
 +    }
 +
 +    impl<'a, T: Copy + Ord> Ord for Kind<'a, T> {
 +        fn cmp(&self, other: &Self) -> Ordering {
 +            match (self.value(), other.value()) {
 +                (Bound::Included(a), Bound::Included(b)) | (Bound::Excluded(a), Bound::Excluded(b)) => a.cmp(&b),
 +                // Range patterns cannot be unbounded (yet)
 +                (Bound::Unbounded, _) | (_, Bound::Unbounded) => unimplemented!(),
 +                (Bound::Included(a), Bound::Excluded(b)) => match a.cmp(&b) {
 +                    Ordering::Equal => Ordering::Greater,
 +                    other => other,
 +                },
 +                (Bound::Excluded(a), Bound::Included(b)) => match a.cmp(&b) {
 +                    Ordering::Equal => Ordering::Less,
 +                    other => other,
 +                },
 +            }
 +        }
 +    }
 +
 +    let mut values = Vec::with_capacity(2 * ranges.len());
 +
 +    for r in ranges {
 +        values.push(Kind::Start(r.node.0, r));
 +        values.push(Kind::End(r.node.1, r));
 +    }
 +
 +    values.sort();
 +
 +    for (a, b) in values.iter().zip(values.iter().skip(1)) {
 +        match (a, b) {
 +            (&Kind::Start(_, ra), &Kind::End(_, rb)) => {
 +                if ra.node != rb.node {
 +                    return Some((ra, rb));
 +                }
 +            },
 +            (&Kind::End(a, _), &Kind::Start(b, _)) if a != Bound::Included(b) => (),
 +            _ => return Some((a.range(), b.range())),
 +        }
 +    }
 +
 +    None
 +}
 +
 +mod redundant_pattern_match {
 +    use super::REDUNDANT_PATTERN_MATCHING;
 +    use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then};
 +    use if_chain::if_chain;
 +    use rustc_ast::ast::LitKind;
 +    use rustc_errors::Applicability;
 +    use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath};
 +    use rustc_lint::LateContext;
 +    use rustc_middle::ty;
 +    use rustc_mir::const_eval::is_const_fn;
 +    use rustc_span::source_map::Symbol;
 +
 +    pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if let ExprKind::Match(op, arms, ref match_source) = &expr.kind {
 +            match match_source {
 +                MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms),
 +                MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"),
 +                MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"),
 +                _ => {},
 +            }
 +        }
 +    }
 +
 +    fn find_sugg_for_if_let<'tcx>(
 +        cx: &LateContext<'tcx>,
 +        expr: &'tcx Expr<'_>,
 +        op: &Expr<'_>,
 +        arms: &[Arm<'_>],
 +        keyword: &'static str,
 +    ) {
 +        fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
 +            if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
 +                return Some("is_ok()");
 +            }
 +            if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") {
 +                return Some("is_err()");
 +            }
 +            if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") {
 +                return Some("is_some()");
 +            }
 +            if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") {
 +                return Some("is_none()");
 +            }
 +            None
 +        }
 +
 +        let hir_id = expr.hir_id;
 +        let good_method = match arms[0].pat.kind {
 +            PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
 +                if let PatKind::Wild = patterns[0].kind {
 +                    find_suggestion(cx, hir_id, path)
 +                } else {
 +                    None
 +                }
 +            },
 +            PatKind::Path(ref path) => find_suggestion(cx, hir_id, path),
 +            _ => None,
 +        };
 +        let good_method = match good_method {
 +            Some(method) => method,
 +            None => return,
 +        };
 +
 +        // check that `while_let_on_iterator` lint does not trigger
 +        if_chain! {
 +            if keyword == "while";
 +            if let ExprKind::MethodCall(method_path, _, _, _) = op.kind;
 +            if method_path.ident.name == sym!(next);
 +            if match_trait_method(cx, op, &paths::ITERATOR);
 +            then {
 +                return;
 +            }
 +        }
 +
++        let result_expr = match &op.kind {
++            ExprKind::AddrOf(_, _, borrowed) => borrowed,
++            _ => op,
++        };
 +        span_lint_and_then(
 +            cx,
 +            REDUNDANT_PATTERN_MATCHING,
 +            arms[0].pat.span,
 +            &format!("redundant pattern matching, consider using `{}`", good_method),
 +            |diag| {
 +                // while let ... = ... { ... }
 +                // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +                let expr_span = expr.span;
 +
 +                // while let ... = ... { ... }
 +                //                 ^^^
-                         let span = expr.span.to(op.span);
++                let op_span = result_expr.span.source_callsite();
 +
 +                // while let ... = ... { ... }
 +                // ^^^^^^^^^^^^^^^^^^^
 +                let span = expr_span.until(op_span.shrink_to_hi());
 +                diag.span_suggestion(
 +                    span,
 +                    "try this",
 +                    format!("{} {}.{}", keyword, snippet(cx, op_span, "_"), good_method),
 +                    Applicability::MachineApplicable, // snippet
 +                );
 +            },
 +        );
 +    }
 +
 +    fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {
 +        if arms.len() == 2 {
 +            let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
 +
 +            let hir_id = expr.hir_id;
 +            let found_good_method = match node_pair {
 +                (
 +                    PatKind::TupleStruct(ref path_left, ref patterns_left, _),
 +                    PatKind::TupleStruct(ref path_right, ref patterns_right, _),
 +                ) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
 +                    if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
 +                        find_good_method_for_match(
 +                            arms,
 +                            path_left,
 +                            path_right,
 +                            &paths::RESULT_OK,
 +                            &paths::RESULT_ERR,
 +                            "is_ok()",
 +                            "is_err()",
 +                            || can_suggest(cx, hir_id, sym!(result_type), "is_ok"),
 +                            || can_suggest(cx, hir_id, sym!(result_type), "is_err"),
 +                        )
 +                    } else {
 +                        None
 +                    }
 +                },
 +                (PatKind::TupleStruct(ref path_left, ref patterns, _), PatKind::Path(ref path_right))
 +                | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, ref patterns, _))
 +                    if patterns.len() == 1 =>
 +                {
 +                    if let PatKind::Wild = patterns[0].kind {
 +                        find_good_method_for_match(
 +                            arms,
 +                            path_left,
 +                            path_right,
 +                            &paths::OPTION_SOME,
 +                            &paths::OPTION_NONE,
 +                            "is_some()",
 +                            "is_none()",
 +                            || can_suggest(cx, hir_id, sym!(option_type), "is_some"),
 +                            || can_suggest(cx, hir_id, sym!(option_type), "is_none"),
 +                        )
 +                    } else {
 +                        None
 +                    }
 +                },
 +                _ => None,
 +            };
 +
 +            if let Some(good_method) = found_good_method {
++                let span = expr.span.to(op.span);
++                let result_expr = match &op.kind {
++                    ExprKind::AddrOf(_, _, borrowed) => borrowed,
++                    _ => op,
++                };
 +                span_lint_and_then(
 +                    cx,
 +                    REDUNDANT_PATTERN_MATCHING,
 +                    expr.span,
 +                    &format!("redundant pattern matching, consider using `{}`", good_method),
 +                    |diag| {
-                             format!("{}.{}", snippet(cx, op.span, "_"), good_method),
 +                        diag.span_suggestion(
 +                            span,
 +                            "try this",
++                            format!("{}.{}", snippet(cx, result_expr.span, "_"), good_method),
 +                            Applicability::MaybeIncorrect, // snippet
 +                        );
 +                    },
 +                );
 +            }
 +        }
 +    }
 +
 +    #[allow(clippy::too_many_arguments)]
 +    fn find_good_method_for_match<'a>(
 +        arms: &[Arm<'_>],
 +        path_left: &QPath<'_>,
 +        path_right: &QPath<'_>,
 +        expected_left: &[&str],
 +        expected_right: &[&str],
 +        should_be_left: &'a str,
 +        should_be_right: &'a str,
 +        can_suggest_left: impl Fn() -> bool,
 +        can_suggest_right: impl Fn() -> bool,
 +    ) -> Option<&'a str> {
 +        let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
 +            (&(*arms[0].body).kind, &(*arms[1].body).kind)
 +        } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) {
 +            (&(*arms[1].body).kind, &(*arms[0].body).kind)
 +        } else {
 +            return None;
 +        };
 +
 +        match body_node_pair {
 +            (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) {
 +                (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left),
 +                (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right),
 +                _ => None,
 +            },
 +            _ => None,
 +        }
 +    }
 +
 +    fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool {
 +        if !in_constant(cx, hir_id) {
 +            return true;
 +        }
 +
 +        // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697.
 +        cx.tcx
 +            .get_diagnostic_item(diag_item)
 +            .and_then(|def_id| {
 +                cx.tcx.inherent_impls(def_id).iter().find_map(|imp| {
 +                    cx.tcx
 +                        .associated_items(*imp)
 +                        .in_definition_order()
 +                        .find_map(|item| match item.kind {
 +                            ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id),
 +                            _ => None,
 +                        })
 +                })
 +            })
 +            .map_or(false, |def_id| is_const_fn(cx.tcx, def_id))
 +    }
 +}
 +
 +#[test]
 +fn test_overlapping() {
 +    use rustc_span::source_map::DUMMY_SP;
 +
 +    let sp = |s, e| SpannedRange {
 +        span: DUMMY_SP,
 +        node: (s, e),
 +    };
 +
 +    assert_eq!(None, overlapping::<u8>(&[]));
 +    assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))]));
 +    assert_eq!(
 +        None,
 +        overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))])
 +    );
 +    assert_eq!(
 +        None,
 +        overlapping(&[
 +            sp(1, Bound::Included(4)),
 +            sp(5, Bound::Included(6)),
 +            sp(10, Bound::Included(11))
 +        ],)
 +    );
 +    assert_eq!(
 +        Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))),
 +        overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))])
 +    );
 +    assert_eq!(
 +        Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))),
 +        overlapping(&[
 +            sp(1, Bound::Included(4)),
 +            sp(5, Bound::Included(6)),
 +            sp(6, Bound::Included(11))
 +        ],)
 +    );
 +}
index 4877556a49e37daaf59173ede295f148af2d4895,0000000000000000000000000000000000000000..97cc58023f55e61d62d01d4685e139d909e55c28
mode 100644,000000..100644
--- /dev/null
@@@ -1,3631 -1,0 +1,3636 @@@
-                 "called `.nth(0)` on a `std::iter::Iterator`",
-                 "try calling",
 +mod bind_instead_of_map;
 +mod inefficient_to_string;
 +mod manual_saturating_arithmetic;
 +mod option_map_unwrap_or;
 +mod unnecessary_filter_map;
 +
 +use std::borrow::Cow;
 +use std::fmt;
 +use std::iter;
 +
 +use bind_instead_of_map::BindInsteadOfMap;
 +use if_chain::if_chain;
 +use rustc_ast::ast;
 +use rustc_errors::Applicability;
 +use rustc_hir as hir;
 +use rustc_hir::intravisit::{self, Visitor};
 +use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
 +use rustc_middle::hir::map::Map;
 +use rustc_middle::lint::in_external_macro;
 +use rustc_middle::ty::subst::GenericArgKind;
 +use rustc_middle::ty::{self, Ty, TyS};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +use rustc_span::symbol::{sym, SymbolStr};
 +
 +use crate::consts::{constant, Constant};
 +use crate::utils::usage::mutated_variables;
 +use crate::utils::{
 +    get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, in_macro, is_copy,
 +    is_ctor_or_promotable_const_function, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment,
 +    match_def_path, match_qpath, match_trait_method, match_type, match_var, method_calls, method_chain_args, paths,
 +    remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite,
 +    span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty,
 +    walk_ptrs_ty_depth, SpanlessEq,
 +};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `.unwrap()` calls on `Option`s and on `Result`s.
 +    ///
 +    /// **Why is this bad?** It is better to handle the `None` or `Err` case,
 +    /// or at least call `.expect(_)` with a more helpful message. Still, for a lot of
 +    /// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is
 +    /// `Allow` by default.
 +    ///
 +    /// `result.unwrap()` will let the thread panic on `Err` values.
 +    /// Normally, you want to implement more sophisticated error handling,
 +    /// and propagate errors upwards with `?` operator.
 +    ///
 +    /// Even if you want to panic on errors, not all `Error`s implement good
 +    /// messages on display. Therefore, it may be beneficial to look at the places
 +    /// where they may get displayed. Activate this lint to do just that.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Examples:**
 +    /// ```rust
 +    /// # let opt = Some(1);
 +    ///
 +    /// // Bad
 +    /// opt.unwrap();
 +    ///
 +    /// // Good
 +    /// opt.expect("more helpful message");
 +    /// ```
 +    ///
 +    /// // or
 +    ///
 +    /// ```rust
 +    /// # let res: Result<usize, ()> = Ok(1);
 +    ///
 +    /// // Bad
 +    /// res.unwrap();
 +    ///
 +    /// // Good
 +    /// res.expect("more helpful message");
 +    /// ```
 +    pub UNWRAP_USED,
 +    restriction,
 +    "using `.unwrap()` on `Result` or `Option`, which should at least get a better message using `expect()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `.expect()` calls on `Option`s and `Result`s.
 +    ///
 +    /// **Why is this bad?** Usually it is better to handle the `None` or `Err` case.
 +    /// Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why
 +    /// this lint is `Allow` by default.
 +    ///
 +    /// `result.expect()` will let the thread panic on `Err`
 +    /// values. Normally, you want to implement more sophisticated error handling,
 +    /// and propagate errors upwards with `?` operator.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Examples:**
 +    /// ```rust,ignore
 +    /// # let opt = Some(1);
 +    ///
 +    /// // Bad
 +    /// opt.expect("one");
 +    ///
 +    /// // Good
 +    /// let opt = Some(1);
 +    /// opt?;
 +    /// ```
 +    ///
 +    /// // or
 +    ///
 +    /// ```rust
 +    /// # let res: Result<usize, ()> = Ok(1);
 +    ///
 +    /// // Bad
 +    /// res.expect("one");
 +    ///
 +    /// // Good
 +    /// res?;
 +    /// # Ok::<(), ()>(())
 +    /// ```
 +    pub EXPECT_USED,
 +    restriction,
 +    "using `.expect()` on `Result` or `Option`, which might be better handled"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for methods that should live in a trait
 +    /// implementation of a `std` trait (see [llogiq's blog
 +    /// post](http://llogiq.github.io/2015/07/30/traits.html) for further
 +    /// information) instead of an inherent implementation.
 +    ///
 +    /// **Why is this bad?** Implementing the traits improve ergonomics for users of
 +    /// the code, often with very little cost. Also people seeing a `mul(...)`
 +    /// method
 +    /// may expect `*` to work equally, so you should have good reason to disappoint
 +    /// them.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// struct X;
 +    /// impl X {
 +    ///     fn add(&self, other: &X) -> X {
 +    ///         // ..
 +    /// # X
 +    ///     }
 +    /// }
 +    /// ```
 +    pub SHOULD_IMPLEMENT_TRAIT,
 +    style,
 +    "defining a method that should be implementing a std trait"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for methods with certain name prefixes and which
 +    /// doesn't match how self is taken. The actual rules are:
 +    ///
 +    /// |Prefix |`self` taken          |
 +    /// |-------|----------------------|
 +    /// |`as_`  |`&self` or `&mut self`|
 +    /// |`from_`| none                 |
 +    /// |`into_`|`self`                |
 +    /// |`is_`  |`&self` or none       |
 +    /// |`to_`  |`&self`               |
 +    ///
 +    /// **Why is this bad?** Consistency breeds readability. If you follow the
 +    /// conventions, your users won't be surprised that they, e.g., need to supply a
 +    /// mutable reference to a `as_..` function.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct X;
 +    /// impl X {
 +    ///     fn as_str(self) -> &'static str {
 +    ///         // ..
 +    /// # ""
 +    ///     }
 +    /// }
 +    /// ```
 +    pub WRONG_SELF_CONVENTION,
 +    style,
 +    "defining a method named with an established prefix (like \"into_\") that takes `self` with the wrong convention"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** This is the same as
 +    /// [`wrong_self_convention`](#wrong_self_convention), but for public items.
 +    ///
 +    /// **Why is this bad?** See [`wrong_self_convention`](#wrong_self_convention).
 +    ///
 +    /// **Known problems:** Actually *renaming* the function may break clients if
 +    /// the function is part of the public interface. In that case, be mindful of
 +    /// the stability guarantees you've given your users.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct X;
 +    /// impl<'a> X {
 +    ///     pub fn as_str(self) -> &'a str {
 +    ///         "foo"
 +    ///     }
 +    /// }
 +    /// ```
 +    pub WRONG_PUB_SELF_CONVENTION,
 +    restriction,
 +    "defining a public method named with an established prefix (like \"into_\") that takes `self` with the wrong convention"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `ok().expect(..)`.
 +    ///
 +    /// **Why is this bad?** Because you usually call `expect()` on the `Result`
 +    /// directly to get a better error message.
 +    ///
 +    /// **Known problems:** The error type needs to implement `Debug`
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let x = Ok::<_, ()>(());
 +    ///
 +    /// // Bad
 +    /// x.ok().expect("why did I do this again?");
 +    ///
 +    /// // Good
 +    /// x.expect("why did I do this again?");
 +    /// ```
 +    pub OK_EXPECT,
 +    style,
 +    "using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or
 +    /// `result.map(_).unwrap_or_else(_)`.
 +    ///
 +    /// **Why is this bad?** Readability, these can be written more concisely (resp.) as
 +    /// `option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`.
 +    ///
 +    /// **Known problems:** The order of the arguments is not in execution order
 +    ///
 +    /// **Examples:**
 +    /// ```rust
 +    /// # let x = Some(1);
 +    ///
 +    /// // Bad
 +    /// x.map(|a| a + 1).unwrap_or(0);
 +    ///
 +    /// // Good
 +    /// x.map_or(0, |a| a + 1);
 +    /// ```
 +    ///
 +    /// // or
 +    ///
 +    /// ```rust
 +    /// # let x: Result<usize, ()> = Ok(1);
 +    /// # fn some_function(foo: ()) -> usize { 1 }
 +    ///
 +    /// // Bad
 +    /// x.map(|a| a + 1).unwrap_or_else(some_function);
 +    ///
 +    /// // Good
 +    /// x.map_or_else(some_function, |a| a + 1);
 +    /// ```
 +    pub MAP_UNWRAP_OR,
 +    pedantic,
 +    "using `.map(f).unwrap_or(a)` or `.map(f).unwrap_or_else(func)`, which are more succinctly expressed as `map_or(a, f)` or `map_or_else(a, f)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.map_or(None, _)`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.and_then(_)`.
 +    ///
 +    /// **Known problems:** The order of the arguments is not in execution order.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let opt = Some(1);
 +    ///
 +    /// // Bad
 +    /// opt.map_or(None, |a| Some(a + 1));
 +    ///
 +    /// // Good
 +    /// opt.and_then(|a| Some(a + 1));
 +    /// ```
 +    pub OPTION_MAP_OR_NONE,
 +    style,
 +    "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.map_or(None, Some)`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.ok()`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// Bad:
 +    /// ```rust
 +    /// # let r: Result<u32, &str> = Ok(1);
 +    /// assert_eq!(Some(1), r.map_or(None, Some));
 +    /// ```
 +    ///
 +    /// Good:
 +    /// ```rust
 +    /// # let r: Result<u32, &str> = Ok(1);
 +    /// assert_eq!(Some(1), r.ok());
 +    /// ```
 +    pub RESULT_MAP_OR_INTO_OPTION,
 +    style,
 +    "using `Result.map_or(None, Some)`, which is more succinctly expressed as `ok()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or
 +    /// `_.or_else(|x| Err(y))`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.map(|x| y)` or `_.map_err(|x| y)`.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # fn opt() -> Option<&'static str> { Some("42") }
 +    /// # fn res() -> Result<&'static str, &'static str> { Ok("42") }
 +    /// let _ = opt().and_then(|s| Some(s.len()));
 +    /// let _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });
 +    /// let _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });
 +    /// ```
 +    ///
 +    /// The correct use would be:
 +    ///
 +    /// ```rust
 +    /// # fn opt() -> Option<&'static str> { Some("42") }
 +    /// # fn res() -> Result<&'static str, &'static str> { Ok("42") }
 +    /// let _ = opt().map(|s| s.len());
 +    /// let _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });
 +    /// let _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });
 +    /// ```
 +    pub BIND_INSTEAD_OF_MAP,
 +    complexity,
 +    "using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.filter(_).next()`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.find(_)`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().filter(|x| **x == 0).next();
 +    /// ```
 +    /// Could be written as
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().find(|x| **x == 0);
 +    /// ```
 +    pub FILTER_NEXT,
 +    complexity,
 +    "using `filter(p).next()`, which is more succinctly expressed as `.find(p)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.skip_while(condition).next()`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.find(!condition)`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().skip_while(|x| **x == 0).next();
 +    /// ```
 +    /// Could be written as
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().find(|x| **x != 0);
 +    /// ```
 +    pub SKIP_WHILE_NEXT,
 +    complexity,
 +    "using `skip_while(p).next()`, which is more succinctly expressed as `.find(!p)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.map(_).flatten(_)`,
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as a
 +    /// single method call using `_.flat_map(_)`
 +    ///
 +    /// **Known problems:**
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let vec = vec![vec![1]];
 +    ///
 +    /// // Bad
 +    /// vec.iter().map(|x| x.iter()).flatten();
 +    ///
 +    /// // Good
 +    /// vec.iter().flat_map(|x| x.iter());
 +    /// ```
 +    pub MAP_FLATTEN,
 +    pedantic,
 +    "using combinations of `flatten` and `map` which can usually be written as a single method call"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.filter(_).map(_)`,
 +    /// `_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as a
 +    /// single method call.
 +    ///
 +    /// **Known problems:** Often requires a condition + Option/Iterator creation
 +    /// inside the closure.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let vec = vec![1];
 +    ///
 +    /// // Bad
 +    /// vec.iter().filter(|x| **x == 0).map(|x| *x * 2);
 +    ///
 +    /// // Good
 +    /// vec.iter().filter_map(|x| if *x == 0 {
 +    ///     Some(*x * 2)
 +    /// } else {
 +    ///     None
 +    /// });
 +    /// ```
 +    pub FILTER_MAP,
 +    pedantic,
 +    "using combinations of `filter`, `map`, `filter_map` and `flat_map` which can usually be written as a single method call"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.filter_map(_).next()`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as a
 +    /// single method call.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    ///  (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next();
 +    /// ```
 +    /// Can be written as
 +    ///
 +    /// ```rust
 +    ///  (0..3).find_map(|x| if x == 2 { Some(x) } else { None });
 +    /// ```
 +    pub FILTER_MAP_NEXT,
 +    pedantic,
 +    "using combination of `filter_map` and `next` which can usually be written as a single method call"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `flat_map(|x| x)`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely by using `flatten`.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let iter = vec![vec![0]].into_iter();
 +    /// iter.flat_map(|x| x);
 +    /// ```
 +    /// Can be written as
 +    /// ```rust
 +    /// # let iter = vec![vec![0]].into_iter();
 +    /// iter.flatten();
 +    /// ```
 +    pub FLAT_MAP_IDENTITY,
 +    complexity,
 +    "call to `flat_map` where `flatten` is sufficient"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.find(_).map(_)`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as a
 +    /// single method call.
 +    ///
 +    /// **Known problems:** Often requires a condition + Option/Iterator creation
 +    /// inside the closure.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    ///  (0..3).find(|x| *x == 2).map(|x| x * 2);
 +    /// ```
 +    /// Can be written as
 +    /// ```rust
 +    ///  (0..3).find_map(|x| if x == 2 { Some(x * 2) } else { None });
 +    /// ```
 +    pub FIND_MAP,
 +    pedantic,
 +    "using a combination of `find` and `map` can usually be written as a single method call"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for an iterator search (such as `find()`,
 +    /// `position()`, or `rposition()`) followed by a call to `is_some()`.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.any(_)`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().find(|x| **x == 0).is_some();
 +    /// ```
 +    /// Could be written as
 +    /// ```rust
 +    /// # let vec = vec![1];
 +    /// vec.iter().any(|x| *x == 0);
 +    /// ```
 +    pub SEARCH_IS_SOME,
 +    complexity,
 +    "using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.chars().next()` on a `str` to check
 +    /// if it starts with a given char.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.starts_with(_)`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let name = "foo";
 +    /// if name.chars().next() == Some('_') {};
 +    /// ```
 +    /// Could be written as
 +    /// ```rust
 +    /// let name = "foo";
 +    /// if name.starts_with('_') {};
 +    /// ```
 +    pub CHARS_NEXT_CMP,
 +    style,
 +    "using `.chars().next()` to check if a string starts with a char"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,
 +    /// etc., and suggests to use `or_else`, `unwrap_or_else`, etc., or
 +    /// `unwrap_or_default` instead.
 +    ///
 +    /// **Why is this bad?** The function will always be called and potentially
 +    /// allocate an object acting as the default.
 +    ///
 +    /// **Known problems:** If the function has side-effects, not calling it will
 +    /// change the semantic of the program, but you shouldn't rely on that anyway.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// foo.unwrap_or(String::new());
 +    /// ```
 +    /// this can instead be written:
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// foo.unwrap_or_else(String::new);
 +    /// ```
 +    /// or
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// foo.unwrap_or_default();
 +    /// ```
 +    pub OR_FUN_CALL,
 +    perf,
 +    "using any `*or` method with a function call, which suggests `*or_else`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,
 +    /// etc., and suggests to use `unwrap_or_else` instead
 +    ///
 +    /// **Why is this bad?** The function will always be called.
 +    ///
 +    /// **Known problems:** If the function has side-effects, not calling it will
 +    /// change the semantics of the program, but you shouldn't rely on that anyway.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// # let err_code = "418";
 +    /// # let err_msg = "I'm a teapot";
 +    /// foo.expect(&format!("Err {}: {}", err_code, err_msg));
 +    /// ```
 +    /// or
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// # let err_code = "418";
 +    /// # let err_msg = "I'm a teapot";
 +    /// foo.expect(format!("Err {}: {}", err_code, err_msg).as_str());
 +    /// ```
 +    /// this can instead be written:
 +    /// ```rust
 +    /// # let foo = Some(String::new());
 +    /// # let err_code = "418";
 +    /// # let err_msg = "I'm a teapot";
 +    /// foo.unwrap_or_else(|| panic!("Err {}: {}", err_code, err_msg));
 +    /// ```
 +    pub EXPECT_FUN_CALL,
 +    perf,
 +    "using any `expect` method with a function call"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.clone()` on a `Copy` type.
 +    ///
 +    /// **Why is this bad?** The only reason `Copy` types implement `Clone` is for
 +    /// generics, not for using the `clone` method on a concrete type.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// 42u64.clone();
 +    /// ```
 +    pub CLONE_ON_COPY,
 +    complexity,
 +    "using `clone` on a `Copy` type"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer,
 +    /// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
 +    /// function syntax instead (e.g., `Rc::clone(foo)`).
 +    ///
 +    /// **Why is this bad?** Calling '.clone()' on an Rc, Arc, or Weak
 +    /// can obscure the fact that only the pointer is being cloned, not the underlying
 +    /// data.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # use std::rc::Rc;
 +    /// let x = Rc::new(1);
 +    ///
 +    /// // Bad
 +    /// x.clone();
 +    ///
 +    /// // Good
 +    /// Rc::clone(&x);
 +    /// ```
 +    pub CLONE_ON_REF_PTR,
 +    restriction,
 +    "using 'clone' on a ref-counted pointer"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.clone()` on an `&&T`.
 +    ///
 +    /// **Why is this bad?** Cloning an `&&T` copies the inner `&T`, instead of
 +    /// cloning the underlying `T`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// fn main() {
 +    ///     let x = vec![1];
 +    ///     let y = &&x;
 +    ///     let z = y.clone();
 +    ///     println!("{:p} {:p}", *y, z); // prints out the same pointer
 +    /// }
 +    /// ```
 +    pub CLONE_DOUBLE_REF,
 +    correctness,
 +    "using `clone` on `&&T`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.to_string()` on an `&&T` where
 +    /// `T` implements `ToString` directly (like `&&str` or `&&String`).
 +    ///
 +    /// **Why is this bad?** This bypasses the specialized implementation of
 +    /// `ToString` and instead goes through the more expensive string formatting
 +    /// facilities.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Generic implementation for `T: Display` is used (slow)
 +    /// ["foo", "bar"].iter().map(|s| s.to_string());
 +    ///
 +    /// // OK, the specialized impl is used
 +    /// ["foo", "bar"].iter().map(|&s| s.to_string());
 +    /// ```
 +    pub INEFFICIENT_TO_STRING,
 +    pedantic,
 +    "using `to_string` on `&&T` where `T: ToString`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `new` not returning a type that contains `Self`.
 +    ///
 +    /// **Why is this bad?** As a convention, `new` methods are used to make a new
 +    /// instance of a type.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct Foo;
 +    /// # struct NotAFoo;
 +    /// impl Foo {
 +    ///     fn new() -> NotAFoo {
 +    /// # NotAFoo
 +    ///     }
 +    /// }
 +    /// ```
 +    ///
 +    /// ```rust
 +    /// # struct Foo;
 +    /// # struct FooError;
 +    /// impl Foo {
 +    ///     // Good. Return type contains `Self`
 +    ///     fn new() -> Result<Foo, FooError> {
 +    ///         # Ok(Foo)
 +    ///     }
 +    /// }
 +    /// ```
 +    ///
 +    /// ```rust
 +    /// # struct Foo;
 +    /// struct Bar(Foo);
 +    /// impl Foo {
 +    ///     // Bad. The type name must contain `Self`.
 +    ///     fn new() -> Bar {
 +    ///         # Bar(Foo)
 +    ///     }
 +    /// }
 +    /// ```
 +    pub NEW_RET_NO_SELF,
 +    style,
 +    "not returning type containing `Self` in a `new` method"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for string methods that receive a single-character
 +    /// `str` as an argument, e.g., `_.split("x")`.
 +    ///
 +    /// **Why is this bad?** Performing these methods using a `char` is faster than
 +    /// using a `str`.
 +    ///
 +    /// **Known problems:** Does not catch multi-byte unicode characters.
 +    ///
 +    /// **Example:**
 +    /// ```rust,ignore
 +    /// // Bad
 +    /// _.split("x");
 +    ///
 +    /// // Good
 +    /// _.split('x');
 +    pub SINGLE_CHAR_PATTERN,
 +    perf,
 +    "using a single-character str where a char could be used, e.g., `_.split(\"x\")`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for getting the inner pointer of a temporary
 +    /// `CString`.
 +    ///
 +    /// **Why is this bad?** The inner pointer of a `CString` is only valid as long
 +    /// as the `CString` is alive.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # use std::ffi::CString;
 +    /// # fn call_some_ffi_func(_: *const i8) {}
 +    /// #
 +    /// let c_str = CString::new("foo").unwrap().as_ptr();
 +    /// unsafe {
 +    ///     call_some_ffi_func(c_str);
 +    /// }
 +    /// ```
 +    /// Here `c_str` point to a freed address. The correct use would be:
 +    /// ```rust
 +    /// # use std::ffi::CString;
 +    /// # fn call_some_ffi_func(_: *const i8) {}
 +    /// #
 +    /// let c_str = CString::new("foo").unwrap();
 +    /// unsafe {
 +    ///     call_some_ffi_func(c_str.as_ptr());
 +    /// }
 +    /// ```
 +    pub TEMPORARY_CSTRING_AS_PTR,
 +    correctness,
 +    "getting the inner pointer of a temporary `CString`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for calling `.step_by(0)` on iterators which panics.
 +    ///
 +    /// **Why is this bad?** This very much looks like an oversight. Use `panic!()` instead if you
 +    /// actually intend to panic.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust,should_panic
 +    /// for x in (0..100).step_by(0) {
 +    ///     //..
 +    /// }
 +    /// ```
 +    pub ITERATOR_STEP_BY_ZERO,
 +    correctness,
 +    "using `Iterator::step_by(0)`, which will panic at runtime"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for the use of `iter.nth(0)`.
 +    ///
 +    /// **Why is this bad?** `iter.next()` is equivalent to
 +    /// `iter.nth(0)`, as they both consume the next element,
 +    ///  but is more readable.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # use std::collections::HashSet;
 +    /// // Bad
 +    /// # let mut s = HashSet::new();
 +    /// # s.insert(1);
 +    /// let x = s.iter().nth(0);
 +    ///
 +    /// // Good
 +    /// # let mut s = HashSet::new();
 +    /// # s.insert(1);
 +    /// let x = s.iter().next();
 +    /// ```
 +    pub ITER_NTH_ZERO,
 +    style,
 +    "replace `iter.nth(0)` with `iter.next()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for use of `.iter().nth()` (and the related
 +    /// `.iter_mut().nth()`) on standard library types with O(1) element access.
 +    ///
 +    /// **Why is this bad?** `.get()` and `.get_mut()` are more efficient and more
 +    /// readable.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let some_vec = vec![0, 1, 2, 3];
 +    /// let bad_vec = some_vec.iter().nth(3);
 +    /// let bad_slice = &some_vec[..].iter().nth(3);
 +    /// ```
 +    /// The correct use would be:
 +    /// ```rust
 +    /// let some_vec = vec![0, 1, 2, 3];
 +    /// let bad_vec = some_vec.get(3);
 +    /// let bad_slice = &some_vec[..].get(3);
 +    /// ```
 +    pub ITER_NTH,
 +    perf,
 +    "using `.iter().nth()` on a standard library type with O(1) element access"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for use of `.skip(x).next()` on iterators.
 +    ///
 +    /// **Why is this bad?** `.nth(x)` is cleaner
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let some_vec = vec![0, 1, 2, 3];
 +    /// let bad_vec = some_vec.iter().skip(3).next();
 +    /// let bad_slice = &some_vec[..].iter().skip(3).next();
 +    /// ```
 +    /// The correct use would be:
 +    /// ```rust
 +    /// let some_vec = vec![0, 1, 2, 3];
 +    /// let bad_vec = some_vec.iter().nth(3);
 +    /// let bad_slice = &some_vec[..].iter().nth(3);
 +    /// ```
 +    pub ITER_SKIP_NEXT,
 +    style,
 +    "using `.skip(x).next()` on an iterator"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for use of `.get().unwrap()` (or
 +    /// `.get_mut().unwrap`) on a standard library type which implements `Index`
 +    ///
 +    /// **Why is this bad?** Using the Index trait (`[]`) is more clear and more
 +    /// concise.
 +    ///
 +    /// **Known problems:** Not a replacement for error handling: Using either
 +    /// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`
 +    /// if the value being accessed is `None`. If the use of `.get().unwrap()` is a
 +    /// temporary placeholder for dealing with the `Option` type, then this does
 +    /// not mitigate the need for error handling. If there is a chance that `.get()`
 +    /// will be `None` in your program, then it is advisable that the `None` case
 +    /// is handled in a future refactor instead of using `.unwrap()` or the Index
 +    /// trait.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let mut some_vec = vec![0, 1, 2, 3];
 +    /// let last = some_vec.get(3).unwrap();
 +    /// *some_vec.get_mut(0).unwrap() = 1;
 +    /// ```
 +    /// The correct use would be:
 +    /// ```rust
 +    /// let mut some_vec = vec![0, 1, 2, 3];
 +    /// let last = some_vec[3];
 +    /// some_vec[0] = 1;
 +    /// ```
 +    pub GET_UNWRAP,
 +    restriction,
 +    "using `.get().unwrap()` or `.get_mut().unwrap()` when using `[]` would work instead"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for the use of `.extend(s.chars())` where s is a
 +    /// `&str` or `String`.
 +    ///
 +    /// **Why is this bad?** `.push_str(s)` is clearer
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let abc = "abc";
 +    /// let def = String::from("def");
 +    /// let mut s = String::new();
 +    /// s.extend(abc.chars());
 +    /// s.extend(def.chars());
 +    /// ```
 +    /// The correct use would be:
 +    /// ```rust
 +    /// let abc = "abc";
 +    /// let def = String::from("def");
 +    /// let mut s = String::new();
 +    /// s.push_str(abc);
 +    /// s.push_str(&def);
 +    /// ```
 +    pub STRING_EXTEND_CHARS,
 +    style,
 +    "using `x.extend(s.chars())` where s is a `&str` or `String`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for the use of `.cloned().collect()` on slice to
 +    /// create a `Vec`.
 +    ///
 +    /// **Why is this bad?** `.to_vec()` is clearer
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let s = [1, 2, 3, 4, 5];
 +    /// let s2: Vec<isize> = s[..].iter().cloned().collect();
 +    /// ```
 +    /// The better use would be:
 +    /// ```rust
 +    /// let s = [1, 2, 3, 4, 5];
 +    /// let s2: Vec<isize> = s.to_vec();
 +    /// ```
 +    pub ITER_CLONED_COLLECT,
 +    style,
 +    "using `.cloned().collect()` on slice to create a `Vec`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.chars().last()` or
 +    /// `_.chars().next_back()` on a `str` to check if it ends with a given char.
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as
 +    /// `_.ends_with(_)`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let name = "_";
 +    ///
 +    /// // Bad
 +    /// name.chars().last() == Some('_') || name.chars().next_back() == Some('-');
 +    ///
 +    /// // Good
 +    /// name.ends_with('_') || name.ends_with('-');
 +    /// ```
 +    pub CHARS_LAST_CMP,
 +    style,
 +    "using `.chars().last()` or `.chars().next_back()` to check if a string ends with a char"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `.as_ref()` or `.as_mut()` where the
 +    /// types before and after the call are the same.
 +    ///
 +    /// **Why is this bad?** The call is unnecessary.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # fn do_stuff(x: &[i32]) {}
 +    /// let x: &[i32] = &[1, 2, 3, 4, 5];
 +    /// do_stuff(x.as_ref());
 +    /// ```
 +    /// The correct use would be:
 +    /// ```rust
 +    /// # fn do_stuff(x: &[i32]) {}
 +    /// let x: &[i32] = &[1, 2, 3, 4, 5];
 +    /// do_stuff(x);
 +    /// ```
 +    pub USELESS_ASREF,
 +    complexity,
 +    "using `as_ref` where the types before and after the call are the same"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for using `fold` when a more succinct alternative exists.
 +    /// Specifically, this checks for `fold`s which could be replaced by `any`, `all`,
 +    /// `sum` or `product`.
 +    ///
 +    /// **Why is this bad?** Readability.
 +    ///
 +    /// **Known problems:** False positive in pattern guards. Will be resolved once
 +    /// non-lexical lifetimes are stable.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let _ = (0..3).fold(false, |acc, x| acc || x > 2);
 +    /// ```
 +    /// This could be written as:
 +    /// ```rust
 +    /// let _ = (0..3).any(|x| x > 2);
 +    /// ```
 +    pub UNNECESSARY_FOLD,
 +    style,
 +    "using `fold` when a more succinct alternative exists"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `filter_map` calls which could be replaced by `filter` or `map`.
 +    /// More specifically it checks if the closure provided is only performing one of the
 +    /// filter or map operations and suggests the appropriate option.
 +    ///
 +    /// **Why is this bad?** Complexity. The intent is also clearer if only a single
 +    /// operation is being performed.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None });
 +    ///
 +    /// // As there is no transformation of the argument this could be written as:
 +    /// let _ = (0..3).filter(|&x| x > 2);
 +    /// ```
 +    ///
 +    /// ```rust
 +    /// let _ = (0..4).filter_map(|x| Some(x + 1));
 +    ///
 +    /// // As there is no conditional check on the argument this could be written as:
 +    /// let _ = (0..4).map(|x| x + 1);
 +    /// ```
 +    pub UNNECESSARY_FILTER_MAP,
 +    complexity,
 +    "using `filter_map` when a more succinct alternative exists"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `into_iter` calls on references which should be replaced by `iter`
 +    /// or `iter_mut`.
 +    ///
 +    /// **Why is this bad?** Readability. Calling `into_iter` on a reference will not move out its
 +    /// content into the resulting iterator, which is confusing. It is better just call `iter` or
 +    /// `iter_mut` directly.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// // Bad
 +    /// let _ = (&vec![3, 4, 5]).into_iter();
 +    ///
 +    /// // Good
 +    /// let _ = (&vec![3, 4, 5]).iter();
 +    /// ```
 +    pub INTO_ITER_ON_REF,
 +    style,
 +    "using `.into_iter()` on a reference"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for calls to `map` followed by a `count`.
 +    ///
 +    /// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`.
 +    /// If the `map` call is intentional, this should be rewritten. Or, if you intend to
 +    /// drive the iterator to completion, you can just use `for_each` instead.
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// let _ = (0..3).map(|x| x + 2).count();
 +    /// ```
 +    pub SUSPICIOUS_MAP,
 +    complexity,
 +    "suspicious usage of map"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `MaybeUninit::uninit().assume_init()`.
 +    ///
 +    /// **Why is this bad?** For most types, this is undefined behavior.
 +    ///
 +    /// **Known problems:** For now, we accept empty tuples and tuples / arrays
 +    /// of `MaybeUninit`. There may be other types that allow uninitialized
 +    /// data, but those are not yet rigorously defined.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// // Beware the UB
 +    /// use std::mem::MaybeUninit;
 +    ///
 +    /// let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
 +    /// ```
 +    ///
 +    /// Note that the following is OK:
 +    ///
 +    /// ```rust
 +    /// use std::mem::MaybeUninit;
 +    ///
 +    /// let _: [MaybeUninit<bool>; 5] = unsafe {
 +    ///     MaybeUninit::uninit().assume_init()
 +    /// };
 +    /// ```
 +    pub UNINIT_ASSUMED_INIT,
 +    correctness,
 +    "`MaybeUninit::uninit().assume_init()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`.
 +    ///
 +    /// **Why is this bad?** These can be written simply with `saturating_add/sub` methods.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # let y: u32 = 0;
 +    /// # let x: u32 = 100;
 +    /// let add = x.checked_add(y).unwrap_or(u32::MAX);
 +    /// let sub = x.checked_sub(y).unwrap_or(u32::MIN);
 +    /// ```
 +    ///
 +    /// can be written using dedicated methods for saturating addition/subtraction as:
 +    ///
 +    /// ```rust
 +    /// # let y: u32 = 0;
 +    /// # let x: u32 = 100;
 +    /// let add = x.saturating_add(y);
 +    /// let sub = x.saturating_sub(y);
 +    /// ```
 +    pub MANUAL_SATURATING_ARITHMETIC,
 +    style,
 +    "`.chcked_add/sub(x).unwrap_or(MAX/MIN)`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
 +    /// zero-sized types
 +    ///
 +    /// **Why is this bad?** This is a no-op, and likely unintended
 +    ///
 +    /// **Known problems:** None
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// unsafe { (&() as *const ()).offset(1) };
 +    /// ```
 +    pub ZST_OFFSET,
 +    correctness,
 +    "Check for offset calculations on raw pointers to zero-sized types"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `FileType::is_file()`.
 +    ///
 +    /// **Why is this bad?** When people testing a file type with `FileType::is_file`
 +    /// they are testing whether a path is something they can get bytes from. But
 +    /// `is_file` doesn't cover special file types in unix-like systems, and doesn't cover
 +    /// symlink in windows. Using `!FileType::is_dir()` is a better way to that intention.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # || {
 +    /// let metadata = std::fs::metadata("foo.txt")?;
 +    /// let filetype = metadata.file_type();
 +    ///
 +    /// if filetype.is_file() {
 +    ///     // read file
 +    /// }
 +    /// # Ok::<_, std::io::Error>(())
 +    /// # };
 +    /// ```
 +    ///
 +    /// should be written as:
 +    ///
 +    /// ```rust
 +    /// # || {
 +    /// let metadata = std::fs::metadata("foo.txt")?;
 +    /// let filetype = metadata.file_type();
 +    ///
 +    /// if !filetype.is_dir() {
 +    ///     // read file
 +    /// }
 +    /// # Ok::<_, std::io::Error>(())
 +    /// # };
 +    /// ```
 +    pub FILETYPE_IS_FILE,
 +    restriction,
 +    "`FileType::is_file` is not recommended to test for readable file type"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str).
 +    ///
 +    /// **Why is this bad?** Readability, this can be written more concisely as a
 +    /// single method call.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let opt = Some("".to_string());
 +    /// opt.as_ref().map(String::as_str)
 +    /// # ;
 +    /// ```
 +    /// Can be written as
 +    /// ```rust
 +    /// # let opt = Some("".to_string());
 +    /// opt.as_deref()
 +    /// # ;
 +    /// ```
 +    pub OPTION_AS_REF_DEREF,
 +    complexity,
 +    "using `as_ref().map(Deref::deref)`, which is more succinctly expressed as `as_deref()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `iter().next()` on a Slice or an Array
 +    ///
 +    /// **Why is this bad?** These can be shortened into `.get()`
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let a = [1, 2, 3];
 +    /// # let b = vec![1, 2, 3];
 +    /// a[2..].iter().next();
 +    /// b.iter().next();
 +    /// ```
 +    /// should be written as:
 +    /// ```rust
 +    /// # let a = [1, 2, 3];
 +    /// # let b = vec![1, 2, 3];
 +    /// a.get(2);
 +    /// b.get(0);
 +    /// ```
 +    pub ITER_NEXT_SLICE,
 +    style,
 +    "using `.iter().next()` on a sliced array, which can be shortened to just `.get()`"
 +}
 +
 +declare_lint_pass!(Methods => [
 +    UNWRAP_USED,
 +    EXPECT_USED,
 +    SHOULD_IMPLEMENT_TRAIT,
 +    WRONG_SELF_CONVENTION,
 +    WRONG_PUB_SELF_CONVENTION,
 +    OK_EXPECT,
 +    MAP_UNWRAP_OR,
 +    RESULT_MAP_OR_INTO_OPTION,
 +    OPTION_MAP_OR_NONE,
 +    BIND_INSTEAD_OF_MAP,
 +    OR_FUN_CALL,
 +    EXPECT_FUN_CALL,
 +    CHARS_NEXT_CMP,
 +    CHARS_LAST_CMP,
 +    CLONE_ON_COPY,
 +    CLONE_ON_REF_PTR,
 +    CLONE_DOUBLE_REF,
 +    INEFFICIENT_TO_STRING,
 +    NEW_RET_NO_SELF,
 +    SINGLE_CHAR_PATTERN,
 +    SEARCH_IS_SOME,
 +    TEMPORARY_CSTRING_AS_PTR,
 +    FILTER_NEXT,
 +    SKIP_WHILE_NEXT,
 +    FILTER_MAP,
 +    FILTER_MAP_NEXT,
 +    FLAT_MAP_IDENTITY,
 +    FIND_MAP,
 +    MAP_FLATTEN,
 +    ITERATOR_STEP_BY_ZERO,
 +    ITER_NEXT_SLICE,
 +    ITER_NTH,
 +    ITER_NTH_ZERO,
 +    ITER_SKIP_NEXT,
 +    GET_UNWRAP,
 +    STRING_EXTEND_CHARS,
 +    ITER_CLONED_COLLECT,
 +    USELESS_ASREF,
 +    UNNECESSARY_FOLD,
 +    UNNECESSARY_FILTER_MAP,
 +    INTO_ITER_ON_REF,
 +    SUSPICIOUS_MAP,
 +    UNINIT_ASSUMED_INIT,
 +    MANUAL_SATURATING_ARITHMETIC,
 +    ZST_OFFSET,
 +    FILETYPE_IS_FILE,
 +    OPTION_AS_REF_DEREF,
 +]);
 +
 +impl<'tcx> LateLintPass<'tcx> for Methods {
 +    #[allow(clippy::too_many_lines)]
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
 +        if in_macro(expr.span) {
 +            return;
 +        }
 +
 +        let (method_names, arg_lists, method_spans) = method_calls(expr, 2);
 +        let method_names: Vec<SymbolStr> = method_names.iter().map(|s| s.as_str()).collect();
 +        let method_names: Vec<&str> = method_names.iter().map(|s| &**s).collect();
 +
 +        match method_names.as_slice() {
 +            ["unwrap", "get"] => lint_get_unwrap(cx, expr, arg_lists[1], false),
 +            ["unwrap", "get_mut"] => lint_get_unwrap(cx, expr, arg_lists[1], true),
 +            ["unwrap", ..] => lint_unwrap(cx, expr, arg_lists[0]),
 +            ["expect", "ok"] => lint_ok_expect(cx, expr, arg_lists[1]),
 +            ["expect", ..] => lint_expect(cx, expr, arg_lists[0]),
 +            ["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]),
 +            ["unwrap_or_else", "map"] => lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]),
 +            ["and_then", ..] => {
 +                bind_instead_of_map::OptionAndThenSome::lint(cx, expr, arg_lists[0]);
 +                bind_instead_of_map::ResultAndThenOk::lint(cx, expr, arg_lists[0]);
 +            },
 +            ["or_else", ..] => {
 +                bind_instead_of_map::ResultOrElseErrInfo::lint(cx, expr, arg_lists[0]);
 +            },
 +            ["next", "filter"] => lint_filter_next(cx, expr, arg_lists[1]),
 +            ["next", "skip_while"] => lint_skip_while_next(cx, expr, arg_lists[1]),
 +            ["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]),
 +            ["map", "filter"] => lint_filter_map(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1]),
 +            ["map", "find"] => lint_find_map(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
 +            ["flat_map", ..] => lint_flat_map_identity(cx, expr, arg_lists[0], method_spans[0]),
 +            ["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]),
 +            ["is_some", "find"] => lint_search_is_some(cx, expr, "find", arg_lists[1], arg_lists[0], method_spans[1]),
 +            ["is_some", "position"] => {
 +                lint_search_is_some(cx, expr, "position", arg_lists[1], arg_lists[0], method_spans[1])
 +            },
 +            ["is_some", "rposition"] => {
 +                lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
 +            },
 +            ["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
 +            ["as_ptr", "unwrap" | "expect"] => lint_cstring_as_ptr(cx, expr, &arg_lists[1][0], &arg_lists[0][0]),
 +            ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
 +            ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
 +            ["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
 +            ["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
 +            ["next", "skip"] => lint_iter_skip_next(cx, expr),
 +            ["collect", "cloned"] => lint_iter_cloned_collect(cx, expr, arg_lists[1]),
 +            ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]),
 +            ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]),
 +            ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]),
 +            ["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]),
 +            ["count", "map"] => lint_suspicious_map(cx, expr),
 +            ["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr),
 +            ["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => {
 +                manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..])
 +            },
 +            ["add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub"] => {
 +                check_pointer_offset(cx, expr, arg_lists[0])
 +            },
 +            ["is_file", ..] => lint_filetype_is_file(cx, expr, arg_lists[0]),
 +            ["map", "as_ref"] => lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], false),
 +            ["map", "as_mut"] => lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], true),
 +            _ => {},
 +        }
 +
 +        match expr.kind {
 +            hir::ExprKind::MethodCall(ref method_call, ref method_span, ref args, _) => {
 +                lint_or_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
 +                lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
 +
 +                let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
 +                if args.len() == 1 && method_call.ident.name == sym!(clone) {
 +                    lint_clone_on_copy(cx, expr, &args[0], self_ty);
 +                    lint_clone_on_ref_ptr(cx, expr, &args[0]);
 +                }
 +                if args.len() == 1 && method_call.ident.name == sym!(to_string) {
 +                    inefficient_to_string::lint(cx, expr, &args[0], self_ty);
 +                }
 +
 +                match self_ty.kind {
 +                    ty::Ref(_, ty, _) if ty.kind == ty::Str => {
 +                        for &(method, pos) in &PATTERN_METHODS {
 +                            if method_call.ident.name.as_str() == method && args.len() > pos {
 +                                lint_single_char_pattern(cx, expr, &args[pos]);
 +                            }
 +                        }
 +                    },
 +                    ty::Ref(..) if method_call.ident.name == sym!(into_iter) => {
 +                        lint_into_iter(cx, expr, self_ty, *method_span);
 +                    },
 +                    _ => (),
 +                }
 +            },
 +            hir::ExprKind::Binary(op, ref lhs, ref rhs)
 +                if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne =>
 +            {
 +                let mut info = BinaryExprInfo {
 +                    expr,
 +                    chain: lhs,
 +                    other: rhs,
 +                    eq: op.node == hir::BinOpKind::Eq,
 +                };
 +                lint_binary_expr_with_method_call(cx, &mut info);
 +            }
 +            _ => (),
 +        }
 +    }
 +
 +    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
 +        if in_external_macro(cx.sess(), impl_item.span) {
 +            return;
 +        }
 +        let name = impl_item.ident.name.as_str();
 +        let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id);
 +        let item = cx.tcx.hir().expect_item(parent);
 +        let def_id = cx.tcx.hir().local_def_id(item.hir_id);
 +        let self_ty = cx.tcx.type_of(def_id);
 +        if_chain! {
 +            if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind;
 +            if let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir().body(id)).next();
 +            if let hir::ItemKind::Impl{ of_trait: None, .. } = item.kind;
 +
 +            let method_def_id = cx.tcx.hir().local_def_id(impl_item.hir_id);
 +            let method_sig = cx.tcx.fn_sig(method_def_id);
 +            let method_sig = cx.tcx.erase_late_bound_regions(&method_sig);
 +
 +            let first_arg_ty = &method_sig.inputs().iter().next();
 +
 +            // check conventions w.r.t. conversion method names and predicates
 +            if let Some(first_arg_ty) = first_arg_ty;
 +
 +            then {
 +                if cx.access_levels.is_exported(impl_item.hir_id) {
 +                // check missing trait implementations
 +                    for &(method_name, n_args, fn_header, self_kind, out_type, trait_name) in &TRAIT_METHODS {
 +                        if name == method_name &&
 +                            sig.decl.inputs.len() == n_args &&
 +                            out_type.matches(cx, &sig.decl.output) &&
 +                            self_kind.matches(cx, self_ty, first_arg_ty) &&
 +                            fn_header_equals(*fn_header, sig.header) {
 +                            span_lint(cx, SHOULD_IMPLEMENT_TRAIT, impl_item.span, &format!(
 +                                "defining a method called `{}` on this type; consider implementing \
 +                                the `{}` trait or choosing a less ambiguous name", name, trait_name));
 +                        }
 +                    }
 +                }
 +
 +                if let Some((ref conv, self_kinds)) = &CONVENTIONS
 +                    .iter()
 +                    .find(|(ref conv, _)| conv.check(&name))
 +                {
 +                    if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) {
 +                        let lint = if item.vis.node.is_pub() {
 +                            WRONG_PUB_SELF_CONVENTION
 +                        } else {
 +                            WRONG_SELF_CONVENTION
 +                        };
 +
 +                        span_lint(
 +                            cx,
 +                            lint,
 +                            first_arg.pat.span,
 +                            &format!("methods called `{}` usually take {}; consider choosing a less ambiguous name",
 +                                conv,
 +                                &self_kinds
 +                                    .iter()
 +                                    .map(|k| k.description())
 +                                    .collect::<Vec<_>>()
 +                                    .join(" or ")
 +                            ),
 +                        );
 +                    }
 +                }
 +            }
 +        }
 +
 +        if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
 +            let ret_ty = return_ty(cx, impl_item.hir_id);
 +
 +            let contains_self_ty = |ty: Ty<'tcx>| {
 +                ty.walk().any(|inner| match inner.unpack() {
 +                    GenericArgKind::Type(inner_ty) => TyS::same_type(self_ty, inner_ty),
 +
 +                    GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
 +                })
 +            };
 +
 +            // walk the return type and check for Self (this does not check associated types)
 +            if contains_self_ty(ret_ty) {
 +                return;
 +            }
 +
 +            // if return type is impl trait, check the associated types
 +            if let ty::Opaque(def_id, _) = ret_ty.kind {
 +                // one of the associated types must be Self
 +                for predicate in cx.tcx.predicates_of(def_id).predicates {
 +                    if let ty::PredicateKind::Projection(poly_projection_predicate) = predicate.0.kind() {
 +                        let binder = poly_projection_predicate.ty();
 +                        let associated_type = binder.skip_binder();
 +
 +                        // walk the associated type and check for Self
 +                        if contains_self_ty(associated_type) {
 +                            return;
 +                        }
 +                    }
 +                }
 +            }
 +
 +            if name == "new" && !TyS::same_type(ret_ty, self_ty) {
 +                span_lint(
 +                    cx,
 +                    NEW_RET_NO_SELF,
 +                    impl_item.span,
 +                    "methods called `new` usually return `Self`",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +/// Checks for the `OR_FUN_CALL` lint.
 +#[allow(clippy::too_many_lines)]
 +fn lint_or_fun_call<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &hir::Expr<'_>,
 +    method_span: Span,
 +    name: &str,
 +    args: &'tcx [hir::Expr<'_>],
 +) {
 +    // Searches an expression for method calls or function calls that aren't ctors
 +    struct FunCallFinder<'a, 'tcx> {
 +        cx: &'a LateContext<'tcx>,
 +        found: bool,
 +    }
 +
 +    impl<'a, 'tcx> intravisit::Visitor<'tcx> for FunCallFinder<'a, 'tcx> {
 +        type Map = Map<'tcx>;
 +
 +        fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
 +            let call_found = match &expr.kind {
 +                // ignore enum and struct constructors
 +                hir::ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr),
 +                hir::ExprKind::MethodCall(..) => true,
 +                _ => false,
 +            };
 +
 +            if call_found {
 +                self.found |= true;
 +            }
 +
 +            if !self.found {
 +                intravisit::walk_expr(self, expr);
 +            }
 +        }
 +
 +        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
 +            intravisit::NestedVisitorMap::None
 +        }
 +    }
 +
 +    /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
 +    fn check_unwrap_or_default(
 +        cx: &LateContext<'_>,
 +        name: &str,
 +        fun: &hir::Expr<'_>,
 +        self_expr: &hir::Expr<'_>,
 +        arg: &hir::Expr<'_>,
 +        or_has_args: bool,
 +        span: Span,
 +    ) -> bool {
 +        if_chain! {
 +            if !or_has_args;
 +            if name == "unwrap_or";
 +            if let hir::ExprKind::Path(ref qpath) = fun.kind;
 +            let path = &*last_path_segment(qpath).ident.as_str();
 +            if ["default", "new"].contains(&path);
 +            let arg_ty = cx.typeck_results().expr_ty(arg);
 +            if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT);
 +            if implements_trait(cx, arg_ty, default_trait_id, &[]);
 +
 +            then {
 +                let mut applicability = Applicability::MachineApplicable;
 +                span_lint_and_sugg(
 +                    cx,
 +                    OR_FUN_CALL,
 +                    span,
 +                    &format!("use of `{}` followed by a call to `{}`", name, path),
 +                    "try this",
 +                    format!(
 +                        "{}.unwrap_or_default()",
 +                        snippet_with_applicability(cx, self_expr.span, "_", &mut applicability)
 +                    ),
 +                    applicability,
 +                );
 +
 +                true
 +            } else {
 +                false
 +            }
 +        }
 +    }
 +
 +    /// Checks for `*or(foo())`.
 +    #[allow(clippy::too_many_arguments)]
 +    fn check_general_case<'tcx>(
 +        cx: &LateContext<'tcx>,
 +        name: &str,
 +        method_span: Span,
 +        fun_span: Span,
 +        self_expr: &hir::Expr<'_>,
 +        arg: &'tcx hir::Expr<'_>,
 +        or_has_args: bool,
 +        span: Span,
 +    ) {
 +        if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind {
 +            if path.ident.as_str() == "len" {
 +                let ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&args[0]));
 +
 +                match ty.kind {
 +                    ty::Slice(_) | ty::Array(_, _) => return,
 +                    _ => (),
 +                }
 +
 +                if match_type(cx, ty, &paths::VEC) {
 +                    return;
 +                }
 +            }
 +        }
 +
 +        // (path, fn_has_argument, methods, suffix)
 +        let know_types: &[(&[_], _, &[_], _)] = &[
 +            (&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"),
 +            (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"),
 +            (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"),
 +            (&paths::RESULT, true, &["or", "unwrap_or"], "else"),
 +        ];
 +
 +        if_chain! {
 +            if know_types.iter().any(|k| k.2.contains(&name));
 +
 +            let mut finder = FunCallFinder { cx: &cx, found: false };
 +            if { finder.visit_expr(&arg); finder.found };
 +            if !contains_return(&arg);
 +
 +            let self_ty = cx.typeck_results().expr_ty(self_expr);
 +
 +            if let Some(&(_, fn_has_arguments, poss, suffix)) =
 +                know_types.iter().find(|&&i| match_type(cx, self_ty, i.0));
 +
 +            if poss.contains(&name);
 +
 +            then {
 +                let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
 +                    (true, _) => format!("|_| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
 +                    (false, false) => format!("|| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
 +                    (false, true) => snippet_with_macro_callsite(cx, fun_span, ".."),
 +                };
 +                let span_replace_word = method_span.with_hi(span.hi());
 +                span_lint_and_sugg(
 +                    cx,
 +                    OR_FUN_CALL,
 +                    span_replace_word,
 +                    &format!("use of `{}` followed by a function call", name),
 +                    "try this",
 +                    format!("{}_{}({})", name, suffix, sugg),
 +                    Applicability::HasPlaceholders,
 +                );
 +            }
 +        }
 +    }
 +
 +    if args.len() == 2 {
 +        match args[1].kind {
 +            hir::ExprKind::Call(ref fun, ref or_args) => {
 +                let or_has_args = !or_args.is_empty();
 +                if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) {
 +                    check_general_case(
 +                        cx,
 +                        name,
 +                        method_span,
 +                        fun.span,
 +                        &args[0],
 +                        &args[1],
 +                        or_has_args,
 +                        expr.span,
 +                    );
 +                }
 +            },
 +            hir::ExprKind::MethodCall(_, span, ref or_args, _) => check_general_case(
 +                cx,
 +                name,
 +                method_span,
 +                span,
 +                &args[0],
 +                &args[1],
 +                !or_args.is_empty(),
 +                expr.span,
 +            ),
 +            _ => {},
 +        }
 +    }
 +}
 +
 +/// Checks for the `EXPECT_FUN_CALL` lint.
 +#[allow(clippy::too_many_lines)]
 +fn lint_expect_fun_call(
 +    cx: &LateContext<'_>,
 +    expr: &hir::Expr<'_>,
 +    method_span: Span,
 +    name: &str,
 +    args: &[hir::Expr<'_>],
 +) {
 +    // Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or
 +    // `&str`
 +    fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 +        let mut arg_root = arg;
 +        loop {
 +            arg_root = match &arg_root.kind {
 +                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr,
 +                hir::ExprKind::MethodCall(method_name, _, call_args, _) => {
 +                    if call_args.len() == 1
 +                        && (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref))
 +                        && {
 +                            let arg_type = cx.typeck_results().expr_ty(&call_args[0]);
 +                            let base_type = walk_ptrs_ty(arg_type);
 +                            base_type.kind == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type))
 +                        }
 +                    {
 +                        &call_args[0]
 +                    } else {
 +                        break;
 +                    }
 +                },
 +                _ => break,
 +            };
 +        }
 +        arg_root
 +    }
 +
 +    // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be
 +    // converted to string.
 +    fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
 +        let arg_ty = cx.typeck_results().expr_ty(arg);
 +        if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) {
 +            return false;
 +        }
 +        if let ty::Ref(_, ty, ..) = arg_ty.kind {
 +            if ty.kind == ty::Str && can_be_static_str(cx, arg) {
 +                return false;
 +            }
 +        };
 +        true
 +    }
 +
 +    // Check if an expression could have type `&'static str`, knowing that it
 +    // has type `&str` for some lifetime.
 +    fn can_be_static_str(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
 +        match arg.kind {
 +            hir::ExprKind::Lit(_) => true,
 +            hir::ExprKind::Call(fun, _) => {
 +                if let hir::ExprKind::Path(ref p) = fun.kind {
 +                    match cx.qpath_res(p, fun.hir_id) {
 +                        hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
 +                            cx.tcx.fn_sig(def_id).output().skip_binder().kind,
 +                            ty::Ref(ty::ReStatic, ..)
 +                        ),
 +                        _ => false,
 +                    }
 +                } else {
 +                    false
 +                }
 +            },
 +            hir::ExprKind::MethodCall(..) => {
 +                cx.typeck_results()
 +                    .type_dependent_def_id(arg.hir_id)
 +                    .map_or(false, |method_id| {
 +                        matches!(
 +                            cx.tcx.fn_sig(method_id).output().skip_binder().kind,
 +                            ty::Ref(ty::ReStatic, ..)
 +                        )
 +                    })
 +            },
 +            hir::ExprKind::Path(ref p) => matches!(
 +                cx.qpath_res(p, arg.hir_id),
 +                hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _)
 +            ),
 +            _ => false,
 +        }
 +    }
 +
 +    fn generate_format_arg_snippet(
 +        cx: &LateContext<'_>,
 +        a: &hir::Expr<'_>,
 +        applicability: &mut Applicability,
 +    ) -> Vec<String> {
 +        if_chain! {
 +            if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref format_arg) = a.kind;
 +            if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.kind;
 +            if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.kind;
 +
 +            then {
 +                format_arg_expr_tup
 +                    .iter()
 +                    .map(|a| snippet_with_applicability(cx, a.span, "..", applicability).into_owned())
 +                    .collect()
 +            } else {
 +                unreachable!()
 +            }
 +        }
 +    }
 +
 +    fn is_call(node: &hir::ExprKind<'_>) -> bool {
 +        match node {
 +            hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => {
 +                is_call(&expr.kind)
 +            },
 +            hir::ExprKind::Call(..)
 +            | hir::ExprKind::MethodCall(..)
 +            // These variants are debatable or require further examination
 +            | hir::ExprKind::Match(..)
 +            | hir::ExprKind::Block{ .. } => true,
 +            _ => false,
 +        }
 +    }
 +
 +    if args.len() != 2 || name != "expect" || !is_call(&args[1].kind) {
 +        return;
 +    }
 +
 +    let receiver_type = cx.typeck_results().expr_ty_adjusted(&args[0]);
 +    let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym!(option_type)) {
 +        "||"
 +    } else if is_type_diagnostic_item(cx, receiver_type, sym!(result_type)) {
 +        "|_|"
 +    } else {
 +        return;
 +    };
 +
 +    let arg_root = get_arg_root(cx, &args[1]);
 +
 +    let span_replace_word = method_span.with_hi(expr.span.hi());
 +
 +    let mut applicability = Applicability::MachineApplicable;
 +
 +    //Special handling for `format!` as arg_root
 +    if_chain! {
 +        if let hir::ExprKind::Block(block, None) = &arg_root.kind;
 +        if block.stmts.len() == 1;
 +        if let hir::StmtKind::Local(local) = &block.stmts[0].kind;
 +        if let Some(arg_root) = &local.init;
 +        if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg_root.kind;
 +        if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1;
 +        if let hir::ExprKind::Call(_, format_args) = &inner_args[0].kind;
 +        then {
 +            let fmt_spec = &format_args[0];
 +            let fmt_args = &format_args[1];
 +
 +            let mut args = vec![snippet(cx, fmt_spec.span, "..").into_owned()];
 +
 +            args.extend(generate_format_arg_snippet(cx, fmt_args, &mut applicability));
 +
 +            let sugg = args.join(", ");
 +
 +            span_lint_and_sugg(
 +                cx,
 +                EXPECT_FUN_CALL,
 +                span_replace_word,
 +                &format!("use of `{}` followed by a function call", name),
 +                "try this",
 +                format!("unwrap_or_else({} panic!({}))", closure_args, sugg),
 +                applicability,
 +            );
 +
 +            return;
 +        }
 +    }
 +
 +    let mut arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, "..", &mut applicability);
 +    if requires_to_string(cx, arg_root) {
 +        arg_root_snippet.to_mut().push_str(".to_string()");
 +    }
 +
 +    span_lint_and_sugg(
 +        cx,
 +        EXPECT_FUN_CALL,
 +        span_replace_word,
 +        &format!("use of `{}` followed by a function call", name),
 +        "try this",
 +        format!("unwrap_or_else({} {{ panic!({}) }})", closure_args, arg_root_snippet),
 +        applicability,
 +    );
 +}
 +
 +/// Checks for the `CLONE_ON_COPY` lint.
 +fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) {
 +    let ty = cx.typeck_results().expr_ty(expr);
 +    if let ty::Ref(_, inner, _) = arg_ty.kind {
 +        if let ty::Ref(_, innermost, _) = inner.kind {
 +            span_lint_and_then(
 +                cx,
 +                CLONE_DOUBLE_REF,
 +                expr.span,
 +                "using `clone` on a double-reference; \
 +                this will copy the reference instead of cloning the inner type",
 +                |diag| {
 +                    if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
 +                        let mut ty = innermost;
 +                        let mut n = 0;
 +                        while let ty::Ref(_, inner, _) = ty.kind {
 +                            ty = inner;
 +                            n += 1;
 +                        }
 +                        let refs: String = iter::repeat('&').take(n + 1).collect();
 +                        let derefs: String = iter::repeat('*').take(n).collect();
 +                        let explicit = format!("<{}{}>::clone({})", refs, ty, snip);
 +                        diag.span_suggestion(
 +                            expr.span,
 +                            "try dereferencing it",
 +                            format!("{}({}{}).clone()", refs, derefs, snip.deref()),
 +                            Applicability::MaybeIncorrect,
 +                        );
 +                        diag.span_suggestion(
 +                            expr.span,
 +                            "or try being explicit if you are sure, that you want to clone a reference",
 +                            explicit,
 +                            Applicability::MaybeIncorrect,
 +                        );
 +                    }
 +                },
 +            );
 +            return; // don't report clone_on_copy
 +        }
 +    }
 +
 +    if is_copy(cx, ty) {
 +        let snip;
 +        if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) {
 +            let parent = cx.tcx.hir().get_parent_node(expr.hir_id);
 +            match &cx.tcx.hir().get(parent) {
 +                hir::Node::Expr(parent) => match parent.kind {
 +                    // &*x is a nop, &x.clone() is not
 +                    hir::ExprKind::AddrOf(..) => return,
 +                    // (*x).func() is useless, x.clone().func() can work in case func borrows mutably
 +                    hir::ExprKind::MethodCall(_, _, parent_args, _) if expr.hir_id == parent_args[0].hir_id => {
 +                        return;
 +                    },
 +
 +                    _ => {},
 +                },
 +                hir::Node::Stmt(stmt) => {
 +                    if let hir::StmtKind::Local(ref loc) = stmt.kind {
 +                        if let hir::PatKind::Ref(..) = loc.pat.kind {
 +                            // let ref y = *x borrows x, let ref y = x.clone() does not
 +                            return;
 +                        }
 +                    }
 +                },
 +                _ => {},
 +            }
 +
 +            // x.clone() might have dereferenced x, possibly through Deref impls
 +            if cx.typeck_results().expr_ty(arg) == ty {
 +                snip = Some(("try removing the `clone` call", format!("{}", snippet)));
 +            } else {
 +                let deref_count = cx
 +                    .typeck_results()
 +                    .expr_adjustments(arg)
 +                    .iter()
 +                    .filter(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_)))
 +                    .count();
 +                let derefs: String = iter::repeat('*').take(deref_count).collect();
 +                snip = Some(("try dereferencing it", format!("{}{}", derefs, snippet)));
 +            }
 +        } else {
 +            snip = None;
 +        }
 +        span_lint_and_then(cx, CLONE_ON_COPY, expr.span, "using `clone` on a `Copy` type", |diag| {
 +            if let Some((text, snip)) = snip {
 +                diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable);
 +            }
 +        });
 +    }
 +}
 +
 +fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
 +    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(arg));
 +
 +    if let ty::Adt(_, subst) = obj_ty.kind {
 +        let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
 +            "Rc"
 +        } else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
 +            "Arc"
 +        } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
 +            "Weak"
 +        } else {
 +            return;
 +        };
 +
 +        span_lint_and_sugg(
 +            cx,
 +            CLONE_ON_REF_PTR,
 +            expr.span,
 +            "using `.clone()` on a ref-counted pointer",
 +            "try this",
 +            format!(
 +                "{}::<{}>::clone(&{})",
 +                caller_type,
 +                subst.type_at(0),
 +                snippet(cx, arg.span, "_")
 +            ),
 +            Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
 +        );
 +    }
 +}
 +
 +fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
 +    let arg = &args[1];
 +    if let Some(arglists) = method_chain_args(arg, &["chars"]) {
 +        let target = &arglists[0][0];
 +        let self_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(target));
 +        let ref_str = if self_ty.kind == ty::Str {
 +            ""
 +        } else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
 +            "&"
 +        } else {
 +            return;
 +        };
 +
 +        let mut applicability = Applicability::MachineApplicable;
 +        span_lint_and_sugg(
 +            cx,
 +            STRING_EXTEND_CHARS,
 +            expr.span,
 +            "calling `.extend(_.chars())`",
 +            "try this",
 +            format!(
 +                "{}.push_str({}{})",
 +                snippet_with_applicability(cx, args[0].span, "_", &mut applicability),
 +                ref_str,
 +                snippet_with_applicability(cx, target.span, "_", &mut applicability)
 +            ),
 +            applicability,
 +        );
 +    }
 +}
 +
 +fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
 +    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&args[0]));
 +    if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) {
 +        lint_string_extend(cx, expr, args);
 +    }
 +}
 +
 +fn lint_cstring_as_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) {
 +    if_chain! {
 +        let source_type = cx.typeck_results().expr_ty(source);
 +        if let ty::Adt(def, substs) = source_type.kind;
 +        if cx.tcx.is_diagnostic_item(sym!(result_type), def.did);
 +        if match_type(cx, substs.type_at(0), &paths::CSTRING);
 +        then {
 +            span_lint_and_then(
 +                cx,
 +                TEMPORARY_CSTRING_AS_PTR,
 +                expr.span,
 +                "you are getting the inner pointer of a temporary `CString`",
 +                |diag| {
 +                    diag.note("that pointer will be invalid outside this expression");
 +                    diag.span_help(unwrap.span, "assign the `CString` to a variable to extend its lifetime");
 +                });
 +        }
 +    }
 +}
 +
 +fn lint_iter_cloned_collect<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
 +    if_chain! {
 +        if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym!(vec_type));
 +        if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0]));
 +        if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite());
 +
 +        then {
 +            span_lint_and_sugg(
 +                cx,
 +                ITER_CLONED_COLLECT,
 +                to_replace,
 +                "called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \
 +                more readable",
 +                "try",
 +                ".to_vec()".to_string(),
 +                Applicability::MachineApplicable,
 +            );
 +        }
 +    }
 +}
 +
 +fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) {
 +    fn check_fold_with_op(
 +        cx: &LateContext<'_>,
 +        expr: &hir::Expr<'_>,
 +        fold_args: &[hir::Expr<'_>],
 +        fold_span: Span,
 +        op: hir::BinOpKind,
 +        replacement_method_name: &str,
 +        replacement_has_args: bool,
 +    ) {
 +        if_chain! {
 +            // Extract the body of the closure passed to fold
 +            if let hir::ExprKind::Closure(_, _, body_id, _, _) = fold_args[2].kind;
 +            let closure_body = cx.tcx.hir().body(body_id);
 +            let closure_expr = remove_blocks(&closure_body.value);
 +
 +            // Check if the closure body is of the form `acc <op> some_expr(x)`
 +            if let hir::ExprKind::Binary(ref bin_op, ref left_expr, ref right_expr) = closure_expr.kind;
 +            if bin_op.node == op;
 +
 +            // Extract the names of the two arguments to the closure
 +            if let Some(first_arg_ident) = get_arg_name(&closure_body.params[0].pat);
 +            if let Some(second_arg_ident) = get_arg_name(&closure_body.params[1].pat);
 +
 +            if match_var(&*left_expr, first_arg_ident);
 +            if replacement_has_args || match_var(&*right_expr, second_arg_ident);
 +
 +            then {
 +                let mut applicability = Applicability::MachineApplicable;
 +                let sugg = if replacement_has_args {
 +                    format!(
 +                        "{replacement}(|{s}| {r})",
 +                        replacement = replacement_method_name,
 +                        s = second_arg_ident,
 +                        r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability),
 +                    )
 +                } else {
 +                    format!(
 +                        "{replacement}()",
 +                        replacement = replacement_method_name,
 +                    )
 +                };
 +
 +                span_lint_and_sugg(
 +                    cx,
 +                    UNNECESSARY_FOLD,
 +                    fold_span.with_hi(expr.span.hi()),
 +                    // TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f)
 +                    "this `.fold` can be written more succinctly using another method",
 +                    "try",
 +                    sugg,
 +                    applicability,
 +                );
 +            }
 +        }
 +    }
 +
 +    // Check that this is a call to Iterator::fold rather than just some function called fold
 +    if !match_trait_method(cx, expr, &paths::ITERATOR) {
 +        return;
 +    }
 +
 +    assert!(
 +        fold_args.len() == 3,
 +        "Expected fold_args to have three entries - the receiver, the initial value and the closure"
 +    );
 +
 +    // Check if the first argument to .fold is a suitable literal
 +    if let hir::ExprKind::Lit(ref lit) = fold_args[1].kind {
 +        match lit.node {
 +            ast::LitKind::Bool(false) => {
 +                check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Or, "any", true)
 +            },
 +            ast::LitKind::Bool(true) => {
 +                check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::And, "all", true)
 +            },
 +            ast::LitKind::Int(0, _) => {
 +                check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Add, "sum", false)
 +            },
 +            ast::LitKind::Int(1, _) => {
 +                check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Mul, "product", false)
 +            },
 +            _ => (),
 +        }
 +    }
 +}
 +
 +fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) {
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &args[1]) {
 +            span_lint(
 +                cx,
 +                ITERATOR_STEP_BY_ZERO,
 +                expr.span,
 +                "Iterator::step_by(0) will panic at runtime",
 +            );
 +        }
 +    }
 +}
 +
 +fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
 +    let caller_expr = &iter_args[0];
 +
 +    // Skip lint if the `iter().next()` expression is a for loop argument,
 +    // since it is already covered by `&loops::ITER_NEXT_LOOP`
 +    let mut parent_expr_opt = get_parent_expr(cx, expr);
 +    while let Some(parent_expr) = parent_expr_opt {
 +        if higher::for_loop(parent_expr).is_some() {
 +            return;
 +        }
 +        parent_expr_opt = get_parent_expr(cx, parent_expr);
 +    }
 +
 +    if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
 +        // caller is a Slice
 +        if_chain! {
 +            if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind;
 +            if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
 +                = higher::range(cx, index_expr);
 +            if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind;
 +            if let ast::LitKind::Int(start_idx, _) = start_lit.node;
 +            then {
 +                let mut applicability = Applicability::MachineApplicable;
 +                span_lint_and_sugg(
 +                    cx,
 +                    ITER_NEXT_SLICE,
 +                    expr.span,
 +                    "Using `.iter().next()` on a Slice without end index.",
 +                    "try calling",
 +                    format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx),
 +                    applicability,
 +                );
 +            }
 +        }
 +    } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(caller_expr), sym!(vec_type))
 +        || matches!(
 +            &walk_ptrs_ty(cx.typeck_results().expr_ty(caller_expr)).kind,
 +            ty::Array(_, _)
 +        )
 +    {
 +        // caller is a Vec or an Array
 +        let mut applicability = Applicability::MachineApplicable;
 +        span_lint_and_sugg(
 +            cx,
 +            ITER_NEXT_SLICE,
 +            expr.span,
 +            "Using `.iter().next()` on an array",
 +            "try calling",
 +            format!(
 +                "{}.get(0)",
 +                snippet_with_applicability(cx, caller_expr.span, "..", &mut applicability)
 +            ),
 +            applicability,
 +        );
 +    }
 +}
 +
 +fn lint_iter_nth<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &hir::Expr<'_>,
 +    nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]],
 +    is_mut: bool,
 +) {
 +    let iter_args = nth_and_iter_args[1];
 +    let mut_str = if is_mut { "_mut" } else { "" };
 +    let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() {
 +        "slice"
 +    } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vec_type)) {
 +        "Vec"
 +    } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) {
 +        "VecDeque"
 +    } else {
 +        let nth_args = nth_and_iter_args[0];
 +        lint_iter_nth_zero(cx, expr, &nth_args);
 +        return; // caller is not a type that we want to lint
 +    };
 +
 +    span_lint_and_help(
 +        cx,
 +        ITER_NTH,
 +        expr.span,
 +        &format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type),
 +        None,
 +        &format!("calling `.get{}()` is both faster and more readable", mut_str),
 +    );
 +}
 +
 +fn lint_iter_nth_zero<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) {
 +    if_chain! {
 +        if match_trait_method(cx, expr, &paths::ITERATOR);
 +        if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &nth_args[1]);
 +        then {
 +            let mut applicability = Applicability::MachineApplicable;
 +            span_lint_and_sugg(
 +                cx,
 +                ITER_NTH_ZERO,
 +                expr.span,
-                         let adj = cx.typeck_results().expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::<Box<[_]>>();
++                "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent",
++                "try calling `.next()` instead of `.nth(0)`",
 +                format!("{}.next()", snippet_with_applicability(cx, nth_args[0].span, "..", &mut applicability)),
 +                applicability,
 +            );
 +        }
 +    }
 +}
 +
 +fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: &'tcx [hir::Expr<'_>], is_mut: bool) {
 +    // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`,
 +    // because they do not implement `IndexMut`
 +    let mut applicability = Applicability::MachineApplicable;
 +    let expr_ty = cx.typeck_results().expr_ty(&get_args[0]);
 +    let get_args_str = if get_args.len() > 1 {
 +        snippet_with_applicability(cx, get_args[1].span, "_", &mut applicability)
 +    } else {
 +        return; // not linting on a .get().unwrap() chain or variant
 +    };
 +    let mut needs_ref;
 +    let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
 +        needs_ref = get_args_str.parse::<usize>().is_ok();
 +        "slice"
 +    } else if is_type_diagnostic_item(cx, expr_ty, sym!(vec_type)) {
 +        needs_ref = get_args_str.parse::<usize>().is_ok();
 +        "Vec"
 +    } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) {
 +        needs_ref = get_args_str.parse::<usize>().is_ok();
 +        "VecDeque"
 +    } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) {
 +        needs_ref = true;
 +        "HashMap"
 +    } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) {
 +        needs_ref = true;
 +        "BTreeMap"
 +    } else {
 +        return; // caller is not a type that we want to lint
 +    };
 +
 +    let mut span = expr.span;
 +
 +    // Handle the case where the result is immediately dereferenced
 +    // by not requiring ref and pulling the dereference into the
 +    // suggestion.
 +    if_chain! {
 +        if needs_ref;
 +        if let Some(parent) = get_parent_expr(cx, expr);
 +        if let hir::ExprKind::Unary(hir::UnOp::UnDeref, _) = parent.kind;
 +        then {
 +            needs_ref = false;
 +            span = parent.span;
 +        }
 +    }
 +
 +    let mut_str = if is_mut { "_mut" } else { "" };
 +    let borrow_str = if !needs_ref {
 +        ""
 +    } else if is_mut {
 +        "&mut "
 +    } else {
 +        "&"
 +    };
 +
 +    span_lint_and_sugg(
 +        cx,
 +        GET_UNWRAP,
 +        span,
 +        &format!(
 +            "called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise",
 +            mut_str, caller_type
 +        ),
 +        "try this",
 +        format!(
 +            "{}{}[{}]",
 +            borrow_str,
 +            snippet_with_applicability(cx, get_args[0].span, "_", &mut applicability),
 +            get_args_str
 +        ),
 +        applicability,
 +    );
 +}
 +
 +fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
 +    // lint if caller of skip is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        span_lint_and_help(
 +            cx,
 +            ITER_SKIP_NEXT,
 +            expr.span,
 +            "called `skip(x).next()` on an iterator",
 +            None,
 +            "this is more succinctly expressed by calling `nth(x)`",
 +        );
 +    }
 +}
 +
 +fn derefs_to_slice<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'tcx>,
 +    ty: Ty<'tcx>,
 +) -> Option<&'tcx hir::Expr<'tcx>> {
 +    fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
 +        match ty.kind {
 +            ty::Slice(_) => true,
 +            ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
 +            ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym!(vec_type)),
 +            ty::Array(_, size) => size
 +                .try_eval_usize(cx.tcx, cx.param_env)
 +                .map_or(false, |size| size < 32),
 +            ty::Ref(_, inner, _) => may_slice(cx, inner),
 +            _ => false,
 +        }
 +    }
 +
 +    if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind {
 +        if path.ident.name == sym!(iter) && may_slice(cx, cx.typeck_results().expr_ty(&args[0])) {
 +            Some(&args[0])
 +        } else {
 +            None
 +        }
 +    } else {
 +        match ty.kind {
 +            ty::Slice(_) => Some(expr),
 +            ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr),
 +            ty::Ref(_, inner, _) => {
 +                if may_slice(cx, inner) {
 +                    Some(expr)
 +                } else {
 +                    None
 +                }
 +            },
 +            _ => None,
 +        }
 +    }
 +}
 +
 +/// lint use of `unwrap()` for `Option`s and `Result`s
 +fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) {
 +    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&unwrap_args[0]));
 +
 +    let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
 +        Some((UNWRAP_USED, "an Option", "None"))
 +    } else if is_type_diagnostic_item(cx, obj_ty, sym!(result_type)) {
 +        Some((UNWRAP_USED, "a Result", "Err"))
 +    } else {
 +        None
 +    };
 +
 +    if let Some((lint, kind, none_value)) = mess {
 +        span_lint_and_help(
 +            cx,
 +            lint,
 +            expr.span,
 +            &format!("used `unwrap()` on `{}` value", kind,),
 +            None,
 +            &format!(
 +                "if you don't want to handle the `{}` case gracefully, consider \
 +                using `expect()` to provide a better panic message",
 +                none_value,
 +            ),
 +        );
 +    }
 +}
 +
 +/// lint use of `expect()` for `Option`s and `Result`s
 +fn lint_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
 +    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&expect_args[0]));
 +
 +    let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
 +        Some((EXPECT_USED, "an Option", "None"))
 +    } else if is_type_diagnostic_item(cx, obj_ty, sym!(result_type)) {
 +        Some((EXPECT_USED, "a Result", "Err"))
 +    } else {
 +        None
 +    };
 +
 +    if let Some((lint, kind, none_value)) = mess {
 +        span_lint_and_help(
 +            cx,
 +            lint,
 +            expr.span,
 +            &format!("used `expect()` on `{}` value", kind,),
 +            None,
 +            &format!("if this value is an `{}`, it will panic", none_value,),
 +        );
 +    }
 +}
 +
 +/// lint use of `ok().expect()` for `Result`s
 +fn lint_ok_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) {
 +    if_chain! {
 +        // lint if the caller of `ok()` is a `Result`
 +        if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&ok_args[0]), sym!(result_type));
 +        let result_type = cx.typeck_results().expr_ty(&ok_args[0]);
 +        if let Some(error_type) = get_error_type(cx, result_type);
 +        if has_debug_impl(error_type, cx);
 +
 +        then {
 +            span_lint_and_help(
 +                cx,
 +                OK_EXPECT,
 +                expr.span,
 +                "called `ok().expect()` on a `Result` value",
 +                None,
 +                "you can call `expect()` directly on the `Result`",
 +            );
 +        }
 +    }
 +}
 +
 +/// lint use of `map().flatten()` for `Iterators` and 'Options'
 +fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) {
 +    // lint if caller of `.map().flatten()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `map(..).flatten()` on an `Iterator`. \
 +                    This is more succinctly expressed by calling `.flat_map(..)`";
 +        let self_snippet = snippet(cx, map_args[0].span, "..");
 +        let func_snippet = snippet(cx, map_args[1].span, "..");
 +        let hint = format!("{0}.flat_map({1})", self_snippet, func_snippet);
 +        span_lint_and_sugg(
 +            cx,
 +            MAP_FLATTEN,
 +            expr.span,
 +            msg,
 +            "try using `flat_map` instead",
 +            hint,
 +            Applicability::MachineApplicable,
 +        );
 +    }
 +
 +    // lint if caller of `.map().flatten()` is an Option
 +    if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym!(option_type)) {
 +        let msg = "called `map(..).flatten()` on an `Option`. \
 +                    This is more succinctly expressed by calling `.and_then(..)`";
 +        let self_snippet = snippet(cx, map_args[0].span, "..");
 +        let func_snippet = snippet(cx, map_args[1].span, "..");
 +        let hint = format!("{0}.and_then({1})", self_snippet, func_snippet);
 +        span_lint_and_sugg(
 +            cx,
 +            MAP_FLATTEN,
 +            expr.span,
 +            msg,
 +            "try using `and_then` instead",
 +            hint,
 +            Applicability::MachineApplicable,
 +        );
 +    }
 +}
 +
 +/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s
 +fn lint_map_unwrap_or_else<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    map_args: &'tcx [hir::Expr<'_>],
 +    unwrap_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if the caller of `map()` is an `Option`
 +    let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym!(option_type));
 +    let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym!(result_type));
 +
 +    if is_option || is_result {
 +        // Don't make a suggestion that may fail to compile due to mutably borrowing
 +        // the same variable twice.
 +        let map_mutated_vars = mutated_variables(&map_args[0], cx);
 +        let unwrap_mutated_vars = mutated_variables(&unwrap_args[1], cx);
 +        if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) {
 +            if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() {
 +                return;
 +            }
 +        } else {
 +            return;
 +        }
 +
 +        // lint message
 +        let msg = if is_option {
 +            "called `map(f).unwrap_or_else(g)` on an `Option` value. This can be done more directly by calling \
 +            `map_or_else(g, f)` instead"
 +        } else {
 +            "called `map(f).unwrap_or_else(g)` on a `Result` value. This can be done more directly by calling \
 +            `.map_or_else(g, f)` instead"
 +        };
 +        // get snippets for args to map() and unwrap_or_else()
 +        let map_snippet = snippet(cx, map_args[1].span, "..");
 +        let unwrap_snippet = snippet(cx, unwrap_args[1].span, "..");
 +        // lint, with note if neither arg is > 1 line and both map() and
 +        // unwrap_or_else() have the same span
 +        let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1;
 +        let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt();
 +        if same_span && !multiline {
 +            span_lint_and_note(
 +                cx,
 +                MAP_UNWRAP_OR,
 +                expr.span,
 +                msg,
 +                None,
 +                &format!(
 +                    "replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`",
 +                    map_snippet, unwrap_snippet,
 +                ),
 +            );
 +        } else if same_span && multiline {
 +            span_lint(cx, MAP_UNWRAP_OR, expr.span, msg);
 +        };
 +    }
 +}
 +
 +/// lint use of `_.map_or(None, _)` for `Option`s and `Result`s
 +fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_or_args: &'tcx [hir::Expr<'_>]) {
 +    let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym!(option_type));
 +    let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym!(result_type));
 +
 +    // There are two variants of this `map_or` lint:
 +    // (1) using `map_or` as an adapter from `Result<T,E>` to `Option<T>`
 +    // (2) using `map_or` as a combinator instead of `and_then`
 +    //
 +    // (For this lint) we don't care if any other type calls `map_or`
 +    if !is_option && !is_result {
 +        return;
 +    }
 +
 +    let (lint_name, msg, instead, hint) = {
 +        let default_arg_is_none = if let hir::ExprKind::Path(ref qpath) = map_or_args[1].kind {
 +            match_qpath(qpath, &paths::OPTION_NONE)
 +        } else {
 +            return;
 +        };
 +
 +        if !default_arg_is_none {
 +            // nothing to lint!
 +            return;
 +        }
 +
 +        let f_arg_is_some = if let hir::ExprKind::Path(ref qpath) = map_or_args[2].kind {
 +            match_qpath(qpath, &paths::OPTION_SOME)
 +        } else {
 +            false
 +        };
 +
 +        if is_option {
 +            let self_snippet = snippet(cx, map_or_args[0].span, "..");
 +            let func_snippet = snippet(cx, map_or_args[2].span, "..");
 +            let msg = "called `map_or(None, f)` on an `Option` value. This can be done more directly by calling \
 +                       `and_then(f)` instead";
 +            (
 +                OPTION_MAP_OR_NONE,
 +                msg,
 +                "try using `and_then` instead",
 +                format!("{0}.and_then({1})", self_snippet, func_snippet),
 +            )
 +        } else if f_arg_is_some {
 +            let msg = "called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling \
 +                       `ok()` instead";
 +            let self_snippet = snippet(cx, map_or_args[0].span, "..");
 +            (
 +                RESULT_MAP_OR_INTO_OPTION,
 +                msg,
 +                "try using `ok` instead",
 +                format!("{0}.ok()", self_snippet),
 +            )
 +        } else {
 +            // nothing to lint!
 +            return;
 +        }
 +    };
 +
 +    span_lint_and_sugg(
 +        cx,
 +        lint_name,
 +        expr.span,
 +        msg,
 +        instead,
 +        hint,
 +        Applicability::MachineApplicable,
 +    );
 +}
 +
 +/// lint use of `filter().next()` for `Iterators`
 +fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) {
 +    // lint if caller of `.filter().next()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling \
 +                   `.find(p)` instead.";
 +        let filter_snippet = snippet(cx, filter_args[1].span, "..");
 +        if filter_snippet.lines().count() <= 1 {
 +            // add note if not multi-line
 +            span_lint_and_note(
 +                cx,
 +                FILTER_NEXT,
 +                expr.span,
 +                msg,
 +                None,
 +                &format!("replace `filter({0}).next()` with `find({0})`", filter_snippet),
 +            );
 +        } else {
 +            span_lint(cx, FILTER_NEXT, expr.span, msg);
 +        }
 +    }
 +}
 +
 +/// lint use of `skip_while().next()` for `Iterators`
 +fn lint_skip_while_next<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _skip_while_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.skip_while().next()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        span_lint_and_help(
 +            cx,
 +            SKIP_WHILE_NEXT,
 +            expr.span,
 +            "called `skip_while(p).next()` on an `Iterator`",
 +            None,
 +            "this is more succinctly expressed by calling `.find(!p)` instead",
 +        );
 +    }
 +}
 +
 +/// lint use of `filter().map()` for `Iterators`
 +fn lint_filter_map<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _filter_args: &'tcx [hir::Expr<'_>],
 +    _map_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.filter().map()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter(p).map(q)` on an `Iterator`";
 +        let hint = "this is more succinctly expressed by calling `.filter_map(..)` instead";
 +        span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint);
 +    }
 +}
 +
 +/// lint use of `filter_map().next()` for `Iterators`
 +fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) {
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter_map(p).next()` on an `Iterator`. This is more succinctly expressed by calling \
 +                   `.find_map(p)` instead.";
 +        let filter_snippet = snippet(cx, filter_args[1].span, "..");
 +        if filter_snippet.lines().count() <= 1 {
 +            span_lint_and_note(
 +                cx,
 +                FILTER_MAP_NEXT,
 +                expr.span,
 +                msg,
 +                None,
 +                &format!("replace `filter_map({0}).next()` with `find_map({0})`", filter_snippet),
 +            );
 +        } else {
 +            span_lint(cx, FILTER_MAP_NEXT, expr.span, msg);
 +        }
 +    }
 +}
 +
 +/// lint use of `find().map()` for `Iterators`
 +fn lint_find_map<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _find_args: &'tcx [hir::Expr<'_>],
 +    map_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.filter().map()` is an Iterator
 +    if match_trait_method(cx, &map_args[0], &paths::ITERATOR) {
 +        let msg = "called `find(p).map(q)` on an `Iterator`";
 +        let hint = "this is more succinctly expressed by calling `.find_map(..)` instead";
 +        span_lint_and_help(cx, FIND_MAP, expr.span, msg, None, hint);
 +    }
 +}
 +
 +/// lint use of `filter_map().map()` for `Iterators`
 +fn lint_filter_map_map<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _filter_args: &'tcx [hir::Expr<'_>],
 +    _map_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.filter().map()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter_map(p).map(q)` on an `Iterator`";
 +        let hint = "this is more succinctly expressed by only calling `.filter_map(..)` instead";
 +        span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint);
 +    }
 +}
 +
 +/// lint use of `filter().flat_map()` for `Iterators`
 +fn lint_filter_flat_map<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _filter_args: &'tcx [hir::Expr<'_>],
 +    _map_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.filter().flat_map()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter(p).flat_map(q)` on an `Iterator`";
 +        let hint = "this is more succinctly expressed by calling `.flat_map(..)` \
 +                    and filtering by returning `iter::empty()`";
 +        span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint);
 +    }
 +}
 +
 +/// lint use of `filter_map().flat_map()` for `Iterators`
 +fn lint_filter_map_flat_map<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    _filter_args: &'tcx [hir::Expr<'_>],
 +    _map_args: &'tcx [hir::Expr<'_>],
 +) {
 +    // lint if caller of `.filter_map().flat_map()` is an Iterator
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let msg = "called `filter_map(p).flat_map(q)` on an `Iterator`";
 +        let hint = "this is more succinctly expressed by calling `.flat_map(..)` \
 +                    and filtering by returning `iter::empty()`";
 +        span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint);
 +    }
 +}
 +
 +/// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient
 +fn lint_flat_map_identity<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    flat_map_args: &'tcx [hir::Expr<'_>],
 +    flat_map_span: Span,
 +) {
 +    if match_trait_method(cx, expr, &paths::ITERATOR) {
 +        let arg_node = &flat_map_args[1].kind;
 +
 +        let apply_lint = |message: &str| {
 +            span_lint_and_sugg(
 +                cx,
 +                FLAT_MAP_IDENTITY,
 +                flat_map_span.with_hi(expr.span.hi()),
 +                message,
 +                "try",
 +                "flatten()".to_string(),
 +                Applicability::MachineApplicable,
 +            );
 +        };
 +
 +        if_chain! {
 +            if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
 +            let body = cx.tcx.hir().body(*body_id);
 +
 +            if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
 +            if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.kind;
 +
 +            if path.segments.len() == 1;
 +            if path.segments[0].ident.as_str() == binding_ident.as_str();
 +
 +            then {
 +                apply_lint("called `flat_map(|x| x)` on an `Iterator`");
 +            }
 +        }
 +
 +        if_chain! {
 +            if let hir::ExprKind::Path(ref qpath) = arg_node;
 +
 +            if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
 +
 +            then {
 +                apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
 +            }
 +        }
 +    }
 +}
 +
 +/// lint searching an Iterator followed by `is_some()`
 +fn lint_search_is_some<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx hir::Expr<'_>,
 +    search_method: &str,
 +    search_args: &'tcx [hir::Expr<'_>],
 +    is_some_args: &'tcx [hir::Expr<'_>],
 +    method_span: Span,
 +) {
 +    // lint if caller of search is an Iterator
 +    if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) {
 +        let msg = format!(
 +            "called `is_some()` after searching an `Iterator` with {}. This is more succinctly \
 +             expressed by calling `any()`.",
 +            search_method
 +        );
 +        let search_snippet = snippet(cx, search_args[1].span, "..");
 +        if search_snippet.lines().count() <= 1 {
 +            // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()`
 +            // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()`
 +            let any_search_snippet = if_chain! {
 +                if search_method == "find";
 +                if let hir::ExprKind::Closure(_, _, body_id, ..) = search_args[1].kind;
 +                let closure_body = cx.tcx.hir().body(body_id);
 +                if let Some(closure_arg) = closure_body.params.get(0);
 +                then {
 +                    if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
 +                        Some(search_snippet.replacen('&', "", 1))
 +                    } else if let Some(name) = get_arg_name(&closure_arg.pat) {
 +                        Some(search_snippet.replace(&format!("*{}", name), &name.as_str()))
 +                    } else {
 +                        None
 +                    }
 +                } else {
 +                    None
 +                }
 +            };
 +            // add note if not multi-line
 +            span_lint_and_sugg(
 +                cx,
 +                SEARCH_IS_SOME,
 +                method_span.with_hi(expr.span.hi()),
 +                &msg,
 +                "try this",
 +                format!(
 +                    "any({})",
 +                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
 +                ),
 +                Applicability::MachineApplicable,
 +            );
 +        } else {
 +            span_lint(cx, SEARCH_IS_SOME, expr.span, &msg);
 +        }
 +    }
 +}
 +
 +/// Used for `lint_binary_expr_with_method_call`.
 +#[derive(Copy, Clone)]
 +struct BinaryExprInfo<'a> {
 +    expr: &'a hir::Expr<'a>,
 +    chain: &'a hir::Expr<'a>,
 +    other: &'a hir::Expr<'a>,
 +    eq: bool,
 +}
 +
 +/// Checks for the `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints.
 +fn lint_binary_expr_with_method_call(cx: &LateContext<'_>, info: &mut BinaryExprInfo<'_>) {
 +    macro_rules! lint_with_both_lhs_and_rhs {
 +        ($func:ident, $cx:expr, $info:ident) => {
 +            if !$func($cx, $info) {
 +                ::std::mem::swap(&mut $info.chain, &mut $info.other);
 +                if $func($cx, $info) {
 +                    return;
 +                }
 +            }
 +        };
 +    }
 +
 +    lint_with_both_lhs_and_rhs!(lint_chars_next_cmp, cx, info);
 +    lint_with_both_lhs_and_rhs!(lint_chars_last_cmp, cx, info);
 +    lint_with_both_lhs_and_rhs!(lint_chars_next_cmp_with_unwrap, cx, info);
 +    lint_with_both_lhs_and_rhs!(lint_chars_last_cmp_with_unwrap, cx, info);
 +}
 +
 +/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints.
 +fn lint_chars_cmp(
 +    cx: &LateContext<'_>,
 +    info: &BinaryExprInfo<'_>,
 +    chain_methods: &[&str],
 +    lint: &'static Lint,
 +    suggest: &str,
 +) -> bool {
 +    if_chain! {
 +        if let Some(args) = method_chain_args(info.chain, chain_methods);
 +        if let hir::ExprKind::Call(ref fun, ref arg_char) = info.other.kind;
 +        if arg_char.len() == 1;
 +        if let hir::ExprKind::Path(ref qpath) = fun.kind;
 +        if let Some(segment) = single_segment_path(qpath);
 +        if segment.ident.name == sym!(Some);
 +        then {
 +            let mut applicability = Applicability::MachineApplicable;
 +            let self_ty = walk_ptrs_ty(cx.typeck_results().expr_ty_adjusted(&args[0][0]));
 +
 +            if self_ty.kind != ty::Str {
 +                return false;
 +            }
 +
 +            span_lint_and_sugg(
 +                cx,
 +                lint,
 +                info.expr.span,
 +                &format!("you should use the `{}` method", suggest),
 +                "like this",
 +                format!("{}{}.{}({})",
 +                        if info.eq { "" } else { "!" },
 +                        snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability),
 +                        suggest,
 +                        snippet_with_applicability(cx, arg_char[0].span, "_", &mut applicability)),
 +                applicability,
 +            );
 +
 +            return true;
 +        }
 +    }
 +
 +    false
 +}
 +
 +/// Checks for the `CHARS_NEXT_CMP` lint.
 +fn lint_chars_next_cmp<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool {
 +    lint_chars_cmp(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with")
 +}
 +
 +/// Checks for the `CHARS_LAST_CMP` lint.
 +fn lint_chars_last_cmp<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool {
 +    if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
 +        true
 +    } else {
 +        lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with")
 +    }
 +}
 +
 +/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.
 +fn lint_chars_cmp_with_unwrap<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    info: &BinaryExprInfo<'_>,
 +    chain_methods: &[&str],
 +    lint: &'static Lint,
 +    suggest: &str,
 +) -> bool {
 +    if_chain! {
 +        if let Some(args) = method_chain_args(info.chain, chain_methods);
 +        if let hir::ExprKind::Lit(ref lit) = info.other.kind;
 +        if let ast::LitKind::Char(c) = lit.node;
 +        then {
 +            let mut applicability = Applicability::MachineApplicable;
 +            span_lint_and_sugg(
 +                cx,
 +                lint,
 +                info.expr.span,
 +                &format!("you should use the `{}` method", suggest),
 +                "like this",
 +                format!("{}{}.{}('{}')",
 +                        if info.eq { "" } else { "!" },
 +                        snippet_with_applicability(cx, args[0][0].span, "_", &mut applicability),
 +                        suggest,
 +                        c),
 +                applicability,
 +            );
 +
 +            true
 +        } else {
 +            false
 +        }
 +    }
 +}
 +
 +/// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`.
 +fn lint_chars_next_cmp_with_unwrap<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool {
 +    lint_chars_cmp_with_unwrap(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with")
 +}
 +
 +/// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`.
 +fn lint_chars_last_cmp_with_unwrap<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool {
 +    if lint_chars_cmp_with_unwrap(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") {
 +        true
 +    } else {
 +        lint_chars_cmp_with_unwrap(cx, info, &["chars", "next_back", "unwrap"], CHARS_LAST_CMP, "ends_with")
 +    }
 +}
 +
 +/// lint for length-1 `str`s for methods in `PATTERN_METHODS`
 +fn lint_single_char_pattern<'tcx>(cx: &LateContext<'tcx>, _expr: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>) {
 +    if_chain! {
 +        if let hir::ExprKind::Lit(lit) = &arg.kind;
 +        if let ast::LitKind::Str(r, style) = lit.node;
 +        if r.as_str().len() == 1;
 +        then {
 +            let mut applicability = Applicability::MachineApplicable;
 +            let snip = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
 +            let ch = if let ast::StrStyle::Raw(nhash) = style {
 +                let nhash = nhash as usize;
 +                // for raw string: r##"a"##
 +                &snip[(nhash + 2)..(snip.len() - 1 - nhash)]
 +            } else {
 +                // for regular string: "a"
 +                &snip[1..(snip.len() - 1)]
 +            };
 +            let hint = format!("'{}'", if ch == "'" { "\\'" } else { ch });
 +            span_lint_and_sugg(
 +                cx,
 +                SINGLE_CHAR_PATTERN,
 +                arg.span,
 +                "single-character string constant used as pattern",
 +                "try using a `char` instead",
 +                hint,
 +                applicability,
 +            );
 +        }
 +    }
 +}
 +
 +/// Checks for the `USELESS_ASREF` lint.
 +fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) {
 +    // when we get here, we've already checked that the call name is "as_ref" or "as_mut"
 +    // check if the call is to the actual `AsRef` or `AsMut` trait
 +    if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) {
 +        // check if the type after `as_ref` or `as_mut` is the same as before
 +        let recvr = &as_ref_args[0];
 +        let rcv_ty = cx.typeck_results().expr_ty(recvr);
 +        let res_ty = cx.typeck_results().expr_ty(expr);
 +        let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
 +        let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
 +        if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
 +            // allow the `as_ref` or `as_mut` if it is followed by another method call
 +            if_chain! {
 +                if let Some(parent) = get_parent_expr(cx, expr);
 +                if let hir::ExprKind::MethodCall(_, ref span, _, _) = parent.kind;
 +                if span != &expr.span;
 +                then {
 +                    return;
 +                }
 +            }
 +
 +            let mut applicability = Applicability::MachineApplicable;
 +            span_lint_and_sugg(
 +                cx,
 +                USELESS_ASREF,
 +                expr.span,
 +                &format!("this call to `{}` does nothing", call_name),
 +                "try this",
 +                snippet_with_applicability(cx, recvr.span, "_", &mut applicability).to_string(),
 +                applicability,
 +            );
 +        }
 +    }
 +}
 +
 +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> {
 +    has_iter_method(cx, self_ref_ty).map(|ty_name| {
 +        let mutbl = match self_ref_ty.kind {
 +            ty::Ref(_, _, mutbl) => mutbl,
 +            _ => unreachable!(),
 +        };
 +        let method_name = match mutbl {
 +            hir::Mutability::Not => "iter",
 +            hir::Mutability::Mut => "iter_mut",
 +        };
 +        (ty_name, method_name)
 +    })
 +}
 +
 +fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) {
 +    if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) {
 +        return;
 +    }
 +    if let Some((kind, method_name)) = ty_has_iter_method(cx, self_ref_ty) {
 +        span_lint_and_sugg(
 +            cx,
 +            INTO_ITER_ON_REF,
 +            method_span,
 +            &format!(
 +                "this `.into_iter()` call is equivalent to `.{}()` and will not move the `{}`",
 +                method_name, kind,
 +            ),
 +            "call directly",
 +            method_name.to_string(),
 +            Applicability::MachineApplicable,
 +        );
 +    }
 +}
 +
 +/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter)
 +fn lint_maybe_uninit(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) {
 +    if_chain! {
 +        if let hir::ExprKind::Call(ref callee, ref args) = expr.kind;
 +        if args.is_empty();
 +        if let hir::ExprKind::Path(ref path) = callee.kind;
 +        if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT);
 +        if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(outer));
 +        then {
 +            span_lint(
 +                cx,
 +                UNINIT_ASSUMED_INIT,
 +                outer.span,
 +                "this call for this type may be undefined behavior"
 +            );
 +        }
 +    }
 +}
 +
 +fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
 +    match ty.kind {
 +        ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component),
 +        ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)),
 +        ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT),
 +        _ => false,
 +    }
 +}
 +
 +fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
 +    span_lint_and_help(
 +        cx,
 +        SUSPICIOUS_MAP,
 +        expr.span,
 +        "this call to `map()` won't have an effect on the call to `count()`",
 +        None,
 +        "make sure you did not confuse `map` with `filter` or `for_each`",
 +    );
 +}
 +
 +/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s
 +fn lint_option_as_ref_deref<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &hir::Expr<'_>,
 +    as_ref_args: &[hir::Expr<'_>],
 +    map_args: &[hir::Expr<'_>],
 +    is_mut: bool,
 +) {
 +    let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not);
 +
 +    let option_ty = cx.typeck_results().expr_ty(&as_ref_args[0]);
 +    if !is_type_diagnostic_item(cx, option_ty, sym!(option_type)) {
 +        return;
 +    }
 +
 +    let deref_aliases: [&[&str]; 9] = [
 +        &paths::DEREF_TRAIT_METHOD,
 +        &paths::DEREF_MUT_TRAIT_METHOD,
 +        &paths::CSTRING_AS_C_STR,
 +        &paths::OS_STRING_AS_OS_STR,
 +        &paths::PATH_BUF_AS_PATH,
 +        &paths::STRING_AS_STR,
 +        &paths::STRING_AS_MUT_STR,
 +        &paths::VEC_AS_SLICE,
 +        &paths::VEC_AS_MUT_SLICE,
 +    ];
 +
 +    let is_deref = match map_args[1].kind {
 +        hir::ExprKind::Path(ref expr_qpath) => deref_aliases.iter().any(|path| match_qpath(expr_qpath, path)),
 +        hir::ExprKind::Closure(_, _, body_id, _, _) => {
 +            let closure_body = cx.tcx.hir().body(body_id);
 +            let closure_expr = remove_blocks(&closure_body.value);
 +
 +            match &closure_expr.kind {
 +                hir::ExprKind::MethodCall(_, _, args, _) => {
 +                    if_chain! {
 +                        if args.len() == 1;
 +                        if let hir::ExprKind::Path(qpath) = &args[0].kind;
 +                        if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, args[0].hir_id);
 +                        if closure_body.params[0].pat.hir_id == local_id;
++                        let adj = cx
++                            .typeck_results()
++                            .expr_adjustments(&args[0])
++                            .iter()
++                            .map(|x| &x.kind)
++                            .collect::<Box<[_]>>();
 +                        if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj;
 +                        then {
 +                            let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap();
 +                            deref_aliases.iter().any(|path| match_def_path(cx, method_did, path))
 +                        } else {
 +                            false
 +                        }
 +                    }
 +                },
 +                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, ref inner) if same_mutability(m) => {
 +                    if_chain! {
 +                        if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner1) = inner.kind;
 +                        if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner2) = inner1.kind;
 +                        if let hir::ExprKind::Path(ref qpath) = inner2.kind;
 +                        if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, inner2.hir_id);
 +                        then {
 +                            closure_body.params[0].pat.hir_id == local_id
 +                        } else {
 +                            false
 +                        }
 +                    }
 +                },
 +                _ => false,
 +            }
 +        },
 +        _ => false,
 +    };
 +
 +    if is_deref {
 +        let current_method = if is_mut {
 +            format!(".as_mut().map({})", snippet(cx, map_args[1].span, ".."))
 +        } else {
 +            format!(".as_ref().map({})", snippet(cx, map_args[1].span, ".."))
 +        };
 +        let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" };
 +        let hint = format!("{}.{}()", snippet(cx, as_ref_args[0].span, ".."), method_hint);
 +        let suggestion = format!("try using {} instead", method_hint);
 +
 +        let msg = format!(
 +            "called `{0}` on an Option value. This can be done more directly \
 +            by calling `{1}` instead",
 +            current_method, hint
 +        );
 +        span_lint_and_sugg(
 +            cx,
 +            OPTION_AS_REF_DEREF,
 +            expr.span,
 +            &msg,
 +            &suggestion,
 +            hint,
 +            Applicability::MachineApplicable,
 +        );
 +    }
 +}
 +
 +/// Given a `Result<T, E>` type, return its error type (`E`).
 +fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
 +    match ty.kind {
 +        ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym!(result_type)) => substs.types().nth(1),
 +        _ => None,
 +    }
 +}
 +
 +/// This checks whether a given type is known to implement Debug.
 +fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool {
 +    cx.tcx
 +        .get_diagnostic_item(sym::debug_trait)
 +        .map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
 +}
 +
 +enum Convention {
 +    Eq(&'static str),
 +    StartsWith(&'static str),
 +}
 +
 +#[rustfmt::skip]
 +const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
 +    (Convention::Eq("new"), &[SelfKind::No]),
 +    (Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]),
 +    (Convention::StartsWith("from_"), &[SelfKind::No]),
 +    (Convention::StartsWith("into_"), &[SelfKind::Value]),
 +    (Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]),
 +    (Convention::Eq("to_mut"), &[SelfKind::RefMut]),
 +    (Convention::StartsWith("to_"), &[SelfKind::Ref]),
 +];
 +
 +const FN_HEADER: hir::FnHeader = hir::FnHeader {
 +    unsafety: hir::Unsafety::Normal,
 +    constness: hir::Constness::NotConst,
 +    asyncness: hir::IsAsync::NotAsync,
 +    abi: rustc_target::spec::abi::Abi::Rust,
 +};
 +
 +#[rustfmt::skip]
 +const TRAIT_METHODS: [(&str, usize, &hir::FnHeader, SelfKind, OutType, &str); 30] = [
 +    ("add", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Add"),
 +    ("as_mut", 1, &FN_HEADER, SelfKind::RefMut, OutType::Ref, "std::convert::AsMut"),
 +    ("as_ref", 1, &FN_HEADER, SelfKind::Ref, OutType::Ref, "std::convert::AsRef"),
 +    ("bitand", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::BitAnd"),
 +    ("bitor", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::BitOr"),
 +    ("bitxor", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::BitXor"),
 +    ("borrow", 1, &FN_HEADER, SelfKind::Ref, OutType::Ref, "std::borrow::Borrow"),
 +    ("borrow_mut", 1, &FN_HEADER, SelfKind::RefMut, OutType::Ref, "std::borrow::BorrowMut"),
 +    ("clone", 1, &FN_HEADER, SelfKind::Ref, OutType::Any, "std::clone::Clone"),
 +    ("cmp", 2, &FN_HEADER, SelfKind::Ref, OutType::Any, "std::cmp::Ord"),
 +    ("default", 0, &FN_HEADER, SelfKind::No, OutType::Any, "std::default::Default"),
 +    ("deref", 1, &FN_HEADER, SelfKind::Ref, OutType::Ref, "std::ops::Deref"),
 +    ("deref_mut", 1, &FN_HEADER, SelfKind::RefMut, OutType::Ref, "std::ops::DerefMut"),
 +    ("div", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Div"),
 +    ("drop", 1, &FN_HEADER, SelfKind::RefMut, OutType::Unit, "std::ops::Drop"),
 +    ("eq", 2, &FN_HEADER, SelfKind::Ref, OutType::Bool, "std::cmp::PartialEq"),
 +    ("from_iter", 1, &FN_HEADER, SelfKind::No, OutType::Any, "std::iter::FromIterator"),
 +    ("from_str", 1, &FN_HEADER, SelfKind::No, OutType::Any, "std::str::FromStr"),
 +    ("hash", 2, &FN_HEADER, SelfKind::Ref, OutType::Unit, "std::hash::Hash"),
 +    ("index", 2, &FN_HEADER, SelfKind::Ref, OutType::Ref, "std::ops::Index"),
 +    ("index_mut", 2, &FN_HEADER, SelfKind::RefMut, OutType::Ref, "std::ops::IndexMut"),
 +    ("into_iter", 1, &FN_HEADER, SelfKind::Value, OutType::Any, "std::iter::IntoIterator"),
 +    ("mul", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Mul"),
 +    ("neg", 1, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Neg"),
 +    ("next", 1, &FN_HEADER, SelfKind::RefMut, OutType::Any, "std::iter::Iterator"),
 +    ("not", 1, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Not"),
 +    ("rem", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Rem"),
 +    ("shl", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Shl"),
 +    ("shr", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Shr"),
 +    ("sub", 2, &FN_HEADER, SelfKind::Value, OutType::Any, "std::ops::Sub"),
 +];
 +
 +#[rustfmt::skip]
 +const PATTERN_METHODS: [(&str, usize); 17] = [
 +    ("contains", 1),
 +    ("starts_with", 1),
 +    ("ends_with", 1),
 +    ("find", 1),
 +    ("rfind", 1),
 +    ("split", 1),
 +    ("rsplit", 1),
 +    ("split_terminator", 1),
 +    ("rsplit_terminator", 1),
 +    ("splitn", 2),
 +    ("rsplitn", 2),
 +    ("matches", 1),
 +    ("rmatches", 1),
 +    ("match_indices", 1),
 +    ("rmatch_indices", 1),
 +    ("trim_start_matches", 1),
 +    ("trim_end_matches", 1),
 +];
 +
 +#[derive(Clone, Copy, PartialEq, Debug)]
 +enum SelfKind {
 +    Value,
 +    Ref,
 +    RefMut,
 +    No,
 +}
 +
 +impl SelfKind {
 +    fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
 +        fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'_>, ty: Ty<'_>) -> bool {
 +            if ty == parent_ty {
 +                true
 +            } else if ty.is_box() {
 +                ty.boxed_ty() == parent_ty
 +            } else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
 +                if let ty::Adt(_, substs) = ty.kind {
 +                    substs.types().next().map_or(false, |t| t == parent_ty)
 +                } else {
 +                    false
 +                }
 +            } else {
 +                false
 +            }
 +        }
 +
 +        fn matches_ref<'a>(cx: &LateContext<'a>, mutability: hir::Mutability, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
 +            if let ty::Ref(_, t, m) = ty.kind {
 +                return m == mutability && t == parent_ty;
 +            }
 +
 +            let trait_path = match mutability {
 +                hir::Mutability::Not => &paths::ASREF_TRAIT,
 +                hir::Mutability::Mut => &paths::ASMUT_TRAIT,
 +            };
 +
 +            let trait_def_id = match get_trait_def_id(cx, trait_path) {
 +                Some(did) => did,
 +                None => return false,
 +            };
 +            implements_trait(cx, ty, trait_def_id, &[parent_ty.into()])
 +        }
 +
 +        match self {
 +            Self::Value => matches_value(cx, parent_ty, ty),
 +            Self::Ref => matches_ref(cx, hir::Mutability::Not, parent_ty, ty) || ty == parent_ty && is_copy(cx, ty),
 +            Self::RefMut => matches_ref(cx, hir::Mutability::Mut, parent_ty, ty),
 +            Self::No => ty != parent_ty,
 +        }
 +    }
 +
 +    #[must_use]
 +    fn description(self) -> &'static str {
 +        match self {
 +            Self::Value => "self by value",
 +            Self::Ref => "self by reference",
 +            Self::RefMut => "self by mutable reference",
 +            Self::No => "no self",
 +        }
 +    }
 +}
 +
 +impl Convention {
 +    #[must_use]
 +    fn check(&self, other: &str) -> bool {
 +        match *self {
 +            Self::Eq(this) => this == other,
 +            Self::StartsWith(this) => other.starts_with(this) && this != other,
 +        }
 +    }
 +}
 +
 +impl fmt::Display for Convention {
 +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
 +        match *self {
 +            Self::Eq(this) => this.fmt(f),
 +            Self::StartsWith(this) => this.fmt(f).and_then(|_| '*'.fmt(f)),
 +        }
 +    }
 +}
 +
 +#[derive(Clone, Copy)]
 +enum OutType {
 +    Unit,
 +    Bool,
 +    Any,
 +    Ref,
 +}
 +
 +impl OutType {
 +    fn matches(self, cx: &LateContext<'_>, ty: &hir::FnRetTy<'_>) -> bool {
 +        let is_unit = |ty: &hir::Ty<'_>| SpanlessEq::new(cx).eq_ty_kind(&ty.kind, &hir::TyKind::Tup(&[]));
 +        match (self, ty) {
 +            (Self::Unit, &hir::FnRetTy::DefaultReturn(_)) => true,
 +            (Self::Unit, &hir::FnRetTy::Return(ref ty)) if is_unit(ty) => true,
 +            (Self::Bool, &hir::FnRetTy::Return(ref ty)) if is_bool(ty) => true,
 +            (Self::Any, &hir::FnRetTy::Return(ref ty)) if !is_unit(ty) => true,
 +            (Self::Ref, &hir::FnRetTy::Return(ref ty)) => matches!(ty.kind, hir::TyKind::Rptr(_, _)),
 +            _ => false,
 +        }
 +    }
 +}
 +
 +fn is_bool(ty: &hir::Ty<'_>) -> bool {
 +    if let hir::TyKind::Path(ref p) = ty.kind {
 +        match_qpath(p, &["bool"])
 +    } else {
 +        false
 +    }
 +}
 +
 +// Returns `true` if `expr` contains a return expression
 +fn contains_return(expr: &hir::Expr<'_>) -> bool {
 +    struct RetCallFinder {
 +        found: bool,
 +    }
 +
 +    impl<'tcx> intravisit::Visitor<'tcx> for RetCallFinder {
 +        type Map = Map<'tcx>;
 +
 +        fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
 +            if self.found {
 +                return;
 +            }
 +            if let hir::ExprKind::Ret(..) = &expr.kind {
 +                self.found = true;
 +            } else {
 +                intravisit::walk_expr(self, expr);
 +            }
 +        }
 +
 +        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
 +            intravisit::NestedVisitorMap::None
 +        }
 +    }
 +
 +    let mut visitor = RetCallFinder { found: false };
 +    visitor.visit_expr(expr);
 +    visitor.found
 +}
 +
 +fn check_pointer_offset(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
 +    if_chain! {
 +        if args.len() == 2;
 +        if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.typeck_results().expr_ty(&args[0]).kind;
 +        if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
 +        if layout.is_zst();
 +        then {
 +            span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value");
 +        }
 +    }
 +}
 +
 +fn lint_filetype_is_file(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
 +    let ty = cx.typeck_results().expr_ty(&args[0]);
 +
 +    if !match_type(cx, ty, &paths::FILE_TYPE) {
 +        return;
 +    }
 +
 +    let span: Span;
 +    let verb: &str;
 +    let lint_unary: &str;
 +    let help_unary: &str;
 +    if_chain! {
 +        if let Some(parent) = get_parent_expr(cx, expr);
 +        if let hir::ExprKind::Unary(op, _) = parent.kind;
 +        if op == hir::UnOp::UnNot;
 +        then {
 +            lint_unary = "!";
 +            verb = "denies";
 +            help_unary = "";
 +            span = parent.span;
 +        } else {
 +            lint_unary = "";
 +            verb = "covers";
 +            help_unary = "!";
 +            span = expr.span;
 +        }
 +    }
 +    let lint_msg = format!("`{}FileType::is_file()` only {} regular files", lint_unary, verb);
 +    let help_msg = format!("use `{}FileType::is_dir()` instead", help_unary);
 +    span_lint_and_help(cx, FILETYPE_IS_FILE, span, &lint_msg, None, &help_msg);
 +}
 +
 +fn fn_header_equals(expected: hir::FnHeader, actual: hir::FnHeader) -> bool {
 +    expected.constness == actual.constness
 +        && expected.unsafety == actual.unsafety
 +        && expected.asyncness == actual.asyncness
 +}
index fc10e5077b8391c429a958d91fed858aab8f88f2,0000000000000000000000000000000000000000..26a1c32b6b3ac229f43aa7e4dff4604a96fd361e
mode 100644,000000..100644
--- /dev/null
@@@ -1,735 -1,0 +1,739 @@@
-     /// let error = 0.01f64; // Use an epsilon for comparison
 +use if_chain::if_chain;
 +use rustc_ast::ast::LitKind;
 +use rustc_errors::Applicability;
 +use rustc_hir::intravisit::FnKind;
 +use rustc_hir::{
 +    self as hir, def, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind, Stmt,
 +    StmtKind, TyKind, UnOp,
 +};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::ty::{self, Ty};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::hygiene::DesugaringKind;
 +use rustc_span::source_map::{ExpnKind, Span};
 +
 +use crate::consts::{constant, Constant};
 +use crate::utils::sugg::Sugg;
 +use crate::utils::{
 +    get_item_name, get_parent_expr, higher, implements_trait, in_constant, is_integer_const, iter_input_pats,
 +    last_path_segment, match_qpath, match_trait_method, paths, snippet, snippet_opt, span_lint, span_lint_and_sugg,
 +    span_lint_and_then, span_lint_hir_and_then, walk_ptrs_ty, SpanlessEq,
 +};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for function arguments and let bindings denoted as
 +    /// `ref`.
 +    ///
 +    /// **Why is this bad?** The `ref` declaration makes the function take an owned
 +    /// value, but turns the argument into a reference (which means that the value
 +    /// is destroyed when exiting the function). This adds not much value: either
 +    /// take a reference type, or take an owned value and create references in the
 +    /// body.
 +    ///
 +    /// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The
 +    /// type of `x` is more obvious with the former.
 +    ///
 +    /// **Known problems:** If the argument is dereferenced within the function,
 +    /// removing the `ref` will lead to errors. This can be fixed by removing the
 +    /// dereferences, e.g., changing `*x` to `x` within the function.
 +    ///
 +    /// **Example:**
 +    /// ```rust,ignore
 +    /// // Bad
 +    /// fn foo(ref x: u8) -> bool {
 +    ///     true
 +    /// }
 +    ///
 +    /// // Good
 +    /// fn foo(x: &u8) -> bool {
 +    ///     true
 +    /// }
 +    /// ```
 +    pub TOPLEVEL_REF_ARG,
 +    style,
 +    "an entire binding declared as `ref`, in a function argument or a `let` statement"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for comparisons to NaN.
 +    ///
 +    /// **Why is this bad?** NaN does not compare meaningfully to anything – not
 +    /// even itself – so those comparisons are simply wrong.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let x = 1.0;
 +    ///
 +    /// // Bad
 +    /// if x == f32::NAN { }
 +    ///
 +    /// // Good
 +    /// if x.is_nan() { }
 +    /// ```
 +    pub CMP_NAN,
 +    correctness,
 +    "comparisons to `NAN`, which will always return false, probably not intended"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for (in-)equality comparisons on floating-point
 +    /// values (apart from zero), except in functions called `*eq*` (which probably
 +    /// implement equality for a type involving floats).
 +    ///
 +    /// **Why is this bad?** Floating point calculations are usually imprecise, so
 +    /// asking if two values are *exactly* equal is asking for trouble. For a good
 +    /// guide on what to do, see [the floating point
 +    /// guide](http://www.floating-point-gui.de/errors/comparison).
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x = 1.2331f64;
 +    /// let y = 1.2332f64;
 +    ///
 +    /// // Bad
 +    /// if y == 1.23f64 { }
 +    /// if y != x {} // where both are floats
 +    ///
 +    /// // Good
-     /// if x == ONE { }  // where both are floats
++    /// let error = f64::EPSILON; // Use an epsilon for comparison
++    /// // Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
++    /// // let error = std::f64::EPSILON;
 +    /// if (y - 1.23f64).abs() < error { }
 +    /// if (y - x).abs() > error { }
 +    /// ```
 +    pub FLOAT_CMP,
 +    correctness,
 +    "using `==` or `!=` on float values instead of comparing difference with an epsilon"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for conversions to owned values just for the sake
 +    /// of a comparison.
 +    ///
 +    /// **Why is this bad?** The comparison can operate on a reference, so creating
 +    /// an owned value effectively throws it away directly afterwards, which is
 +    /// needlessly consuming code and heap space.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let x = "foo";
 +    /// # let y = String::from("foo");
 +    /// if x.to_owned() == y {}
 +    /// ```
 +    /// Could be written as
 +    /// ```rust
 +    /// # let x = "foo";
 +    /// # let y = String::from("foo");
 +    /// if x == y {}
 +    /// ```
 +    pub CMP_OWNED,
 +    perf,
 +    "creating owned instances for comparing with others, e.g., `x == \"foo\".to_string()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for getting the remainder of a division by one.
 +    ///
 +    /// **Why is this bad?** The result can only ever be zero. No one will write
 +    /// such code deliberately, unless trying to win an Underhanded Rust
 +    /// Contest. Even for that contest, it's probably a bad idea. Use something more
 +    /// underhanded.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let x = 1;
 +    /// let a = x % 1;
 +    /// ```
 +    pub MODULO_ONE,
 +    correctness,
 +    "taking a number modulo 1, which always returns 0"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for the use of bindings with a single leading
 +    /// underscore.
 +    ///
 +    /// **Why is this bad?** A single leading underscore is usually used to indicate
 +    /// that a binding will not be used. Using such a binding breaks this
 +    /// expectation.
 +    ///
 +    /// **Known problems:** The lint does not work properly with desugaring and
 +    /// macro, it has been allowed in the mean time.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let _x = 0;
 +    /// let y = _x + 1; // Here we are using `_x`, even though it has a leading
 +    ///                 // underscore. We should rename `_x` to `x`
 +    /// ```
 +    pub USED_UNDERSCORE_BINDING,
 +    pedantic,
 +    "using a binding which is prefixed with an underscore"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for the use of short circuit boolean conditions as
 +    /// a
 +    /// statement.
 +    ///
 +    /// **Why is this bad?** Using a short circuit boolean condition as a statement
 +    /// may hide the fact that the second part is executed or not depending on the
 +    /// outcome of the first part.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust,ignore
 +    /// f() && g(); // We should write `if f() { g(); }`.
 +    /// ```
 +    pub SHORT_CIRCUIT_STATEMENT,
 +    complexity,
 +    "using a short circuit boolean condition as a statement"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Catch casts from `0` to some pointer type
 +    ///
 +    /// **Why is this bad?** This generally means `null` and is better expressed as
 +    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// // Bad
 +    /// let a = 0 as *const u32;
 +    ///
 +    /// // Good
 +    /// let a = std::ptr::null::<u32>();
 +    /// ```
 +    pub ZERO_PTR,
 +    style,
 +    "using `0 as *{const, mut} T`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for (in-)equality comparisons on floating-point
 +    /// value and constant, except in functions called `*eq*` (which probably
 +    /// implement equality for a type involving floats).
 +    ///
 +    /// **Why is this bad?** Floating point calculations are usually imprecise, so
 +    /// asking if two values are *exactly* equal is asking for trouble. For a good
 +    /// guide on what to do, see [the floating point
 +    /// guide](http://www.floating-point-gui.de/errors/comparison).
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x: f64 = 1.0;
 +    /// const ONE: f64 = 1.00;
 +    ///
 +    /// // Bad
-     /// let error = 0.1f64; // Use an epsilon for comparison
++    /// if x == ONE { } // where both are floats
 +    ///
 +    /// // Good
++    /// let error = f64::EPSILON; // Use an epsilon for comparison
++    /// // Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
++    /// // let error = std::f64::EPSILON;
 +    /// if (x - ONE).abs() < error { }
 +    /// ```
 +    pub FLOAT_CMP_CONST,
 +    restriction,
 +    "using `==` or `!=` on float constants instead of comparing difference with an epsilon"
 +}
 +
 +declare_lint_pass!(MiscLints => [
 +    TOPLEVEL_REF_ARG,
 +    CMP_NAN,
 +    FLOAT_CMP,
 +    CMP_OWNED,
 +    MODULO_ONE,
 +    USED_UNDERSCORE_BINDING,
 +    SHORT_CIRCUIT_STATEMENT,
 +    ZERO_PTR,
 +    FLOAT_CMP_CONST
 +]);
 +
 +impl<'tcx> LateLintPass<'tcx> for MiscLints {
 +    fn check_fn(
 +        &mut self,
 +        cx: &LateContext<'tcx>,
 +        k: FnKind<'tcx>,
 +        decl: &'tcx FnDecl<'_>,
 +        body: &'tcx Body<'_>,
 +        _: Span,
 +        _: HirId,
 +    ) {
 +        if let FnKind::Closure(_) = k {
 +            // Does not apply to closures
 +            return;
 +        }
 +        for arg in iter_input_pats(decl, body) {
 +            if let PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..) = arg.pat.kind {
 +                span_lint(
 +                    cx,
 +                    TOPLEVEL_REF_ARG,
 +                    arg.pat.span,
 +                    "`ref` directly on a function argument is ignored. \
 +                    Consider using a reference type instead.",
 +                );
 +            }
 +        }
 +    }
 +
 +    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
 +        if_chain! {
 +            if let StmtKind::Local(ref local) = stmt.kind;
 +            if let PatKind::Binding(an, .., name, None) = local.pat.kind;
 +            if let Some(ref init) = local.init;
 +            if !higher::is_from_for_desugar(local);
 +            then {
 +                if an == BindingAnnotation::Ref || an == BindingAnnotation::RefMut {
 +                    let sugg_init = if init.span.from_expansion() {
 +                        Sugg::hir_with_macro_callsite(cx, init, "..")
 +                    } else {
 +                        Sugg::hir(cx, init, "..")
 +                    };
 +                    let (mutopt, initref) = if an == BindingAnnotation::RefMut {
 +                        ("mut ", sugg_init.mut_addr())
 +                    } else {
 +                        ("", sugg_init.addr())
 +                    };
 +                    let tyopt = if let Some(ref ty) = local.ty {
 +                        format!(": &{mutopt}{ty}", mutopt=mutopt, ty=snippet(cx, ty.span, "_"))
 +                    } else {
 +                        String::new()
 +                    };
 +                    span_lint_hir_and_then(
 +                        cx,
 +                        TOPLEVEL_REF_ARG,
 +                        init.hir_id,
 +                        local.pat.span,
 +                        "`ref` on an entire `let` pattern is discouraged, take a reference with `&` instead",
 +                        |diag| {
 +                            diag.span_suggestion(
 +                                stmt.span,
 +                                "try",
 +                                format!(
 +                                    "let {name}{tyopt} = {initref};",
 +                                    name=snippet(cx, name.span, "_"),
 +                                    tyopt=tyopt,
 +                                    initref=initref,
 +                                ),
 +                                Applicability::MachineApplicable,
 +                            );
 +                        }
 +                    );
 +                }
 +            }
 +        };
 +        if_chain! {
 +            if let StmtKind::Semi(ref expr) = stmt.kind;
 +            if let ExprKind::Binary(ref binop, ref a, ref b) = expr.kind;
 +            if binop.node == BinOpKind::And || binop.node == BinOpKind::Or;
 +            if let Some(sugg) = Sugg::hir_opt(cx, a);
 +            then {
 +                span_lint_and_then(cx,
 +                    SHORT_CIRCUIT_STATEMENT,
 +                    stmt.span,
 +                    "boolean short circuit operator in statement may be clearer using an explicit test",
 +                    |diag| {
 +                        let sugg = if binop.node == BinOpKind::Or { !sugg } else { sugg };
 +                        diag.span_suggestion(
 +                            stmt.span,
 +                            "replace it with",
 +                            format!(
 +                                "if {} {{ {}; }}",
 +                                sugg,
 +                                &snippet(cx, b.span, ".."),
 +                            ),
 +                            Applicability::MachineApplicable, // snippet
 +                        );
 +                    });
 +            }
 +        };
 +    }
 +
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        match expr.kind {
 +            ExprKind::Cast(ref e, ref ty) => {
 +                check_cast(cx, expr.span, e, ty);
 +                return;
 +            },
 +            ExprKind::Binary(ref cmp, ref left, ref right) => {
 +                let op = cmp.node;
 +                if op.is_comparison() {
 +                    check_nan(cx, left, expr);
 +                    check_nan(cx, right, expr);
 +                    check_to_owned(cx, left, right, true);
 +                    check_to_owned(cx, right, left, false);
 +                }
 +                if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) {
 +                    if is_allowed(cx, left) || is_allowed(cx, right) {
 +                        return;
 +                    }
 +
 +                    // Allow comparing the results of signum()
 +                    if is_signum(cx, left) && is_signum(cx, right) {
 +                        return;
 +                    }
 +
 +                    if let Some(name) = get_item_name(cx, expr) {
 +                        let name = name.as_str();
 +                        if name == "eq"
 +                            || name == "ne"
 +                            || name == "is_nan"
 +                            || name.starts_with("eq_")
 +                            || name.ends_with("_eq")
 +                        {
 +                            return;
 +                        }
 +                    }
 +                    let is_comparing_arrays = is_array(cx, left) || is_array(cx, right);
 +                    let (lint, msg) = get_lint_and_message(
 +                        is_named_constant(cx, left) || is_named_constant(cx, right),
 +                        is_comparing_arrays,
 +                    );
 +                    span_lint_and_then(cx, lint, expr.span, msg, |diag| {
 +                        let lhs = Sugg::hir(cx, left, "..");
 +                        let rhs = Sugg::hir(cx, right, "..");
 +
 +                        if !is_comparing_arrays {
 +                            diag.span_suggestion(
 +                                expr.span,
 +                                "consider comparing them within some error",
 +                                format!(
 +                                    "({}).abs() {} error",
 +                                    lhs - rhs,
 +                                    if op == BinOpKind::Eq { '<' } else { '>' }
 +                                ),
 +                                Applicability::HasPlaceholders, // snippet
 +                            );
 +                        }
 +                        diag.note("`f32::EPSILON` and `f64::EPSILON` are available for the `error`");
 +                    });
 +                } else if op == BinOpKind::Rem && is_integer_const(cx, right, 1) {
 +                    span_lint(cx, MODULO_ONE, expr.span, "any number modulo 1 will be 0");
 +                }
 +            },
 +            _ => {},
 +        }
 +        if in_attributes_expansion(expr) || expr.span.is_desugaring(DesugaringKind::Await) {
 +            // Don't lint things expanded by #[derive(...)], etc or `await` desugaring
 +            return;
 +        }
 +        let binding = match expr.kind {
 +            ExprKind::Path(ref qpath) => {
 +                let binding = last_path_segment(qpath).ident.as_str();
 +                if binding.starts_with('_') &&
 +                    !binding.starts_with("__") &&
 +                    binding != "_result" && // FIXME: #944
 +                    is_used(cx, expr) &&
 +                    // don't lint if the declaration is in a macro
 +                    non_macro_local(cx, cx.qpath_res(qpath, expr.hir_id))
 +                {
 +                    Some(binding)
 +                } else {
 +                    None
 +                }
 +            },
 +            ExprKind::Field(_, ident) => {
 +                let name = ident.as_str();
 +                if name.starts_with('_') && !name.starts_with("__") {
 +                    Some(name)
 +                } else {
 +                    None
 +                }
 +            },
 +            _ => None,
 +        };
 +        if let Some(binding) = binding {
 +            span_lint(
 +                cx,
 +                USED_UNDERSCORE_BINDING,
 +                expr.span,
 +                &format!(
 +                    "used binding `{}` which is prefixed with an underscore. A leading \
 +                     underscore signals that a binding will not be used.",
 +                    binding
 +                ),
 +            );
 +        }
 +    }
 +}
 +
 +fn get_lint_and_message(
 +    is_comparing_constants: bool,
 +    is_comparing_arrays: bool,
 +) -> (&'static rustc_lint::Lint, &'static str) {
 +    if is_comparing_constants {
 +        (
 +            FLOAT_CMP_CONST,
 +            if is_comparing_arrays {
 +                "strict comparison of `f32` or `f64` constant arrays"
 +            } else {
 +                "strict comparison of `f32` or `f64` constant"
 +            },
 +        )
 +    } else {
 +        (
 +            FLOAT_CMP,
 +            if is_comparing_arrays {
 +                "strict comparison of `f32` or `f64` arrays"
 +            } else {
 +                "strict comparison of `f32` or `f64`"
 +            },
 +        )
 +    }
 +}
 +
 +fn check_nan(cx: &LateContext<'_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) {
 +    if_chain! {
 +        if !in_constant(cx, cmp_expr.hir_id);
 +        if let Some((value, _)) = constant(cx, cx.typeck_results(), expr);
 +        then {
 +            let needs_lint = match value {
 +                Constant::F32(num) => num.is_nan(),
 +                Constant::F64(num) => num.is_nan(),
 +                _ => false,
 +            };
 +
 +            if needs_lint {
 +                span_lint(
 +                    cx,
 +                    CMP_NAN,
 +                    cmp_expr.span,
 +                    "doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +fn is_named_constant<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
 +    if let Some((_, res)) = constant(cx, cx.typeck_results(), expr) {
 +        res
 +    } else {
 +        false
 +    }
 +}
 +
 +fn is_allowed<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
 +    match constant(cx, cx.typeck_results(), expr) {
 +        Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(),
 +        Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(),
 +        Some((Constant::Vec(vec), _)) => vec.iter().all(|f| match f {
 +            Constant::F32(f) => *f == 0.0 || (*f).is_infinite(),
 +            Constant::F64(f) => *f == 0.0 || (*f).is_infinite(),
 +            _ => false,
 +        }),
 +        _ => false,
 +    }
 +}
 +
 +// Return true if `expr` is the result of `signum()` invoked on a float value.
 +fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    // The negation of a signum is still a signum
 +    if let ExprKind::Unary(UnOp::UnNeg, ref child_expr) = expr.kind {
 +        return is_signum(cx, &child_expr);
 +    }
 +
 +    if_chain! {
 +        if let ExprKind::MethodCall(ref method_name, _, ref expressions, _) = expr.kind;
 +        if sym!(signum) == method_name.ident.name;
 +        // Check that the receiver of the signum() is a float (expressions[0] is the receiver of
 +        // the method call)
 +        then {
 +            return is_float(cx, &expressions[0]);
 +        }
 +    }
 +    false
 +}
 +
 +fn is_float(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    let value = &walk_ptrs_ty(cx.typeck_results().expr_ty(expr)).kind;
 +
 +    if let ty::Array(arr_ty, _) = value {
 +        return matches!(arr_ty.kind, ty::Float(_));
 +    };
 +
 +    matches!(value, ty::Float(_))
 +}
 +
 +fn is_array(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    matches!(&walk_ptrs_ty(cx.typeck_results().expr_ty(expr)).kind, ty::Array(_, _))
 +}
 +
 +fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {
 +    #[derive(Default)]
 +    struct EqImpl {
 +        ty_eq_other: bool,
 +        other_eq_ty: bool,
 +    }
 +
 +    impl EqImpl {
 +        fn is_implemented(&self) -> bool {
 +            self.ty_eq_other || self.other_eq_ty
 +        }
 +    }
 +
 +    fn symmetric_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> Option<EqImpl> {
 +        cx.tcx.lang_items().eq_trait().map(|def_id| EqImpl {
 +            ty_eq_other: implements_trait(cx, ty, def_id, &[other.into()]),
 +            other_eq_ty: implements_trait(cx, other, def_id, &[ty.into()]),
 +        })
 +    }
 +
 +    let (arg_ty, snip) = match expr.kind {
 +        ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => {
 +            if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) {
 +                (cx.typeck_results().expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
 +            } else {
 +                return;
 +            }
 +        },
 +        ExprKind::Call(ref path, ref v) if v.len() == 1 => {
 +            if let ExprKind::Path(ref path) = path.kind {
 +                if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) {
 +                    (cx.typeck_results().expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
 +                } else {
 +                    return;
 +                }
 +            } else {
 +                return;
 +            }
 +        },
 +        _ => return,
 +    };
 +
 +    let other_ty = cx.typeck_results().expr_ty(other);
 +
 +    let without_deref = symmetric_partial_eq(cx, arg_ty, other_ty).unwrap_or_default();
 +    let with_deref = arg_ty
 +        .builtin_deref(true)
 +        .and_then(|tam| symmetric_partial_eq(cx, tam.ty, other_ty))
 +        .unwrap_or_default();
 +
 +    if !with_deref.is_implemented() && !without_deref.is_implemented() {
 +        return;
 +    }
 +
 +    let other_gets_derefed = matches!(other.kind, ExprKind::Unary(UnOp::UnDeref, _));
 +
 +    let lint_span = if other_gets_derefed {
 +        expr.span.to(other.span)
 +    } else {
 +        expr.span
 +    };
 +
 +    span_lint_and_then(
 +        cx,
 +        CMP_OWNED,
 +        lint_span,
 +        "this creates an owned instance just for comparison",
 +        |diag| {
 +            // This also catches `PartialEq` implementations that call `to_owned`.
 +            if other_gets_derefed {
 +                diag.span_label(lint_span, "try implementing the comparison without allocating");
 +                return;
 +            }
 +
 +            let expr_snip;
 +            let eq_impl;
 +            if with_deref.is_implemented() {
 +                expr_snip = format!("*{}", snip);
 +                eq_impl = with_deref;
 +            } else {
 +                expr_snip = snip.to_string();
 +                eq_impl = without_deref;
 +            };
 +
 +            let span;
 +            let hint;
 +            if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) {
 +                span = expr.span;
 +                hint = expr_snip;
 +            } else {
 +                span = expr.span.to(other.span);
 +                if eq_impl.ty_eq_other {
 +                    hint = format!("{} == {}", expr_snip, snippet(cx, other.span, ".."));
 +                } else {
 +                    hint = format!("{} == {}", snippet(cx, other.span, ".."), expr_snip);
 +                }
 +            }
 +
 +            diag.span_suggestion(
 +                span,
 +                "try",
 +                hint,
 +                Applicability::MachineApplicable, // snippet
 +            );
 +        },
 +    );
 +}
 +
 +/// 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).map_or(true, |parent| match parent.kind {
 +        ExprKind::Assign(_, ref rhs, _) | ExprKind::AssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr),
 +        _ => is_used(cx, parent),
 +    })
 +}
 +
 +/// Tests whether an expression is in a macro expansion (e.g., something
 +/// generated by `#[derive(...)]` or the like).
 +fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
 +    use rustc_span::hygiene::MacroKind;
 +    if expr.span.from_expansion() {
 +        let data = expr.span.ctxt().outer_expn_data();
 +        matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _))
 +    } else {
 +        false
 +    }
 +}
 +
 +/// Tests whether `res` is a variable defined outside a macro.
 +fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
 +    if let def::Res::Local(id) = res {
 +        !cx.tcx.hir().span(id).from_expansion()
 +    } else {
 +        false
 +    }
 +}
 +
 +fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
 +    if_chain! {
 +        if let TyKind::Ptr(ref mut_ty) = ty.kind;
 +        if let ExprKind::Lit(ref lit) = e.kind;
 +        if let LitKind::Int(0, _) = lit.node;
 +        if !in_constant(cx, e.hir_id);
 +        then {
 +            let (msg, sugg_fn) = match mut_ty.mutbl {
 +                Mutability::Mut => ("`0 as *mut _` detected", "std::ptr::null_mut"),
 +                Mutability::Not => ("`0 as *const _` detected", "std::ptr::null"),
 +            };
 +
 +            let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
 +                (format!("{}()", sugg_fn), Applicability::MachineApplicable)
 +            } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
 +                (format!("{}::<{}>()", sugg_fn, mut_ty_snip), Applicability::MachineApplicable)
 +            } else {
 +                // `MaybeIncorrect` as type inference may not work with the suggested code
 +                (format!("{}()", sugg_fn), Applicability::MaybeIncorrect)
 +            };
 +            span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
 +        }
 +    }
 +}
index b84a1a3fe249449a81a574ea2be25118976bbd7e,0000000000000000000000000000000000000000..29aba7c121873bbd6c57aa3d24d2758942040ba3
mode 100644,000000..100644
--- /dev/null
@@@ -1,669 -1,0 +1,569 @@@
- use crate::utils::{
-     constants, snippet_opt, snippet_with_applicability, span_lint, span_lint_and_help, span_lint_and_sugg,
-     span_lint_and_then,
- };
- use if_chain::if_chain;
++use crate::utils::{constants, snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
 +use rustc_ast::ast::{
-     BindingMode, Block, Expr, ExprKind, GenericParamKind, Generics, Lit, LitFloatType, LitIntType, LitKind, Mutability,
-     NodeId, Pat, PatKind, StmtKind, UnOp,
++    BindingMode, Expr, ExprKind, GenericParamKind, Generics, Lit, LitFloatType, LitIntType, LitKind, Mutability,
++    NodeId, Pat, PatKind, UnOp,
 +};
- use rustc_ast::visit::{walk_expr, FnKind, Visitor};
++use rustc_ast::visit::FnKind;
 +use rustc_data_structures::fx::FxHashMap;
 +use rustc_errors::Applicability;
 +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 +use rustc_middle::lint::in_external_macro;
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for structure field patterns bound to wildcards.
 +    ///
 +    /// **Why is this bad?** Using `..` instead is shorter and leaves the focus on
 +    /// the fields that are actually bound.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct Foo {
 +    /// #     a: i32,
 +    /// #     b: i32,
 +    /// #     c: i32,
 +    /// # }
 +    /// let f = Foo { a: 0, b: 0, c: 0 };
 +    ///
 +    /// // Bad
 +    /// match f {
 +    ///     Foo { a: _, b: 0, .. } => {},
 +    ///     Foo { a: _, b: _, c: _ } => {},
 +    /// }
 +    ///
 +    /// // Good
 +    /// match f {
 +    ///     Foo { b: 0, .. } => {},
 +    ///     Foo { .. } => {},
 +    /// }
 +    /// ```
 +    pub UNNEEDED_FIELD_PATTERN,
 +    restriction,
 +    "struct fields bound to a wildcard instead of using `..`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for function arguments having the similar names
 +    /// differing by an underscore.
 +    ///
 +    /// **Why is this bad?** It affects code readability.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Bad
 +    /// fn foo(a: i32, _a: i32) {}
 +    ///
 +    /// // Good
 +    /// fn bar(a: i32, _b: i32) {}
 +    /// ```
 +    pub DUPLICATE_UNDERSCORE_ARGUMENT,
 +    style,
 +    "function arguments having names which only differ by an underscore"
 +}
 +
- declare_clippy_lint! {
-     /// **What it does:** Detects closures called in the same expression where they
-     /// are defined.
-     ///
-     /// **Why is this bad?** It is unnecessarily adding to the expression's
-     /// complexity.
-     ///
-     /// **Known problems:** None.
-     ///
-     /// **Example:**
-     /// ```rust,ignore
-     /// // Bad
-     /// let a = (|| 42)()
-     ///
-     /// // Good
-     /// let a = 42
-     /// ```
-     pub REDUNDANT_CLOSURE_CALL,
-     complexity,
-     "throwaway closures called in the expression they are defined"
- }
 +declare_clippy_lint! {
 +    /// **What it does:** Detects expressions of the form `--x`.
 +    ///
 +    /// **Why is this bad?** It can mislead C/C++ programmers to think `x` was
 +    /// decremented.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let mut x = 3;
 +    /// --x;
 +    /// ```
 +    pub DOUBLE_NEG,
 +    style,
 +    "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Warns on hexadecimal literals with mixed-case letter
 +    /// digits.
 +    ///
 +    /// **Why is this bad?** It looks confusing.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Bad
 +    /// let y = 0x1a9BAcD;
 +    ///
 +    /// // Good
 +    /// let y = 0x1A9BACD;
 +    /// ```
 +    pub MIXED_CASE_HEX_LITERALS,
 +    style,
 +    "hex literals whose letter digits are not consistently upper- or lowercased"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Warns if literal suffixes are not separated by an
 +    /// underscore.
 +    ///
 +    /// **Why is this bad?** It is much less readable.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Bad
 +    /// let y = 123832i32;
 +    ///
 +    /// // Good
 +    /// let y = 123832_i32;
 +    /// ```
 +    pub UNSEPARATED_LITERAL_SUFFIX,
 +    pedantic,
 +    "literals whose suffix is not separated by an underscore"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Warns if an integral constant literal starts with `0`.
 +    ///
 +    /// **Why is this bad?** In some languages (including the infamous C language
 +    /// and most of its
 +    /// family), this marks an octal constant. In Rust however, this is a decimal
 +    /// constant. This could
 +    /// be confusing for both the writer and a reader of the constant.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// In Rust:
 +    /// ```rust
 +    /// fn main() {
 +    ///     let a = 0123;
 +    ///     println!("{}", a);
 +    /// }
 +    /// ```
 +    ///
 +    /// prints `123`, while in C:
 +    ///
 +    /// ```c
 +    /// #include <stdio.h>
 +    ///
 +    /// int main() {
 +    ///     int a = 0123;
 +    ///     printf("%d\n", a);
 +    /// }
 +    /// ```
 +    ///
 +    /// prints `83` (as `83 == 0o123` while `123 == 0o173`).
 +    pub ZERO_PREFIXED_LITERAL,
 +    complexity,
 +    "integer literals starting with `0`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Warns if a generic shadows a built-in type.
 +    ///
 +    /// **Why is this bad?** This gives surprising type errors.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```ignore
 +    /// impl<u32> Foo<u32> {
 +    ///     fn impl_func(&self) -> u32 {
 +    ///         42
 +    ///     }
 +    /// }
 +    /// ```
 +    pub BUILTIN_TYPE_SHADOW,
 +    style,
 +    "shadowing a builtin type"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for patterns in the form `name @ _`.
 +    ///
 +    /// **Why is this bad?** It's almost always more readable to just use direct
 +    /// bindings.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let v = Some("abc");
 +    ///
 +    /// // Bad
 +    /// match v {
 +    ///     Some(x) => (),
 +    ///     y @ _ => (),
 +    /// }
 +    ///
 +    /// // Good
 +    /// match v {
 +    ///     Some(x) => (),
 +    ///     y => (),
 +    /// }
 +    /// ```
 +    pub REDUNDANT_PATTERN,
 +    style,
 +    "using `name @ _` in a pattern"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for tuple patterns with a wildcard
 +    /// pattern (`_`) is next to a rest pattern (`..`).
 +    ///
 +    /// _NOTE_: While `_, ..` means there is at least one element left, `..`
 +    /// means there are 0 or more elements left. This can make a difference
 +    /// when refactoring, but shouldn't result in errors in the refactored code,
 +    /// since the wildcard pattern isn't used anyway.
 +    /// **Why is this bad?** The wildcard pattern is unneeded as the rest pattern
 +    /// can match that element as well.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # struct TupleStruct(u32, u32, u32);
 +    /// # let t = TupleStruct(1, 2, 3);
 +    ///
 +    /// // Bad
 +    /// match t {
 +    ///     TupleStruct(0, .., _) => (),
 +    ///     _ => (),
 +    /// }
 +    ///
 +    /// // Good
 +    /// match t {
 +    ///     TupleStruct(0, ..) => (),
 +    ///     _ => (),
 +    /// }
 +    /// ```
 +    pub UNNEEDED_WILDCARD_PATTERN,
 +    complexity,
 +    "tuple patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)"
 +}
 +
 +declare_lint_pass!(MiscEarlyLints => [
 +    UNNEEDED_FIELD_PATTERN,
 +    DUPLICATE_UNDERSCORE_ARGUMENT,
-     REDUNDANT_CLOSURE_CALL,
 +    DOUBLE_NEG,
 +    MIXED_CASE_HEX_LITERALS,
 +    UNSEPARATED_LITERAL_SUFFIX,
 +    ZERO_PREFIXED_LITERAL,
 +    BUILTIN_TYPE_SHADOW,
 +    REDUNDANT_PATTERN,
 +    UNNEEDED_WILDCARD_PATTERN,
 +]);
 +
- // Used to find `return` statements or equivalents e.g., `?`
- struct ReturnVisitor {
-     found_return: bool,
- }
- impl ReturnVisitor {
-     #[must_use]
-     fn new() -> Self {
-         Self { found_return: false }
-     }
- }
- impl<'ast> Visitor<'ast> for ReturnVisitor {
-     fn visit_expr(&mut self, ex: &'ast Expr) {
-         if let ExprKind::Ret(_) = ex.kind {
-             self.found_return = true;
-         } else if let ExprKind::Try(_) = ex.kind {
-             self.found_return = true;
-         }
-         walk_expr(self, ex)
-     }
- }
 +impl EarlyLintPass for MiscEarlyLints {
 +    fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
 +        for param in &gen.params {
 +            if let GenericParamKind::Type { .. } = param.kind {
 +                let name = param.ident.as_str();
 +                if constants::BUILTIN_TYPES.contains(&&*name) {
 +                    span_lint(
 +                        cx,
 +                        BUILTIN_TYPE_SHADOW,
 +                        param.ident.span,
 +                        &format!("This generic shadows the built-in type `{}`", name),
 +                    );
 +                }
 +            }
 +        }
 +    }
 +
 +    fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {
 +        if let PatKind::Struct(ref npat, ref pfields, _) = pat.kind {
 +            let mut wilds = 0;
 +            let type_name = npat
 +                .segments
 +                .last()
 +                .expect("A path must have at least one segment")
 +                .ident
 +                .name;
 +
 +            for field in pfields {
 +                if let PatKind::Wild = field.pat.kind {
 +                    wilds += 1;
 +                }
 +            }
 +            if !pfields.is_empty() && wilds == pfields.len() {
 +                span_lint_and_help(
 +                    cx,
 +                    UNNEEDED_FIELD_PATTERN,
 +                    pat.span,
 +                    "All the struct fields are matched to a wildcard pattern, consider using `..`.",
 +                    None,
 +                    &format!("Try with `{} {{ .. }}` instead", type_name),
 +                );
 +                return;
 +            }
 +            if wilds > 0 {
 +                for field in pfields {
 +                    if let PatKind::Wild = field.pat.kind {
 +                        wilds -= 1;
 +                        if wilds > 0 {
 +                            span_lint(
 +                                cx,
 +                                UNNEEDED_FIELD_PATTERN,
 +                                field.span,
 +                                "You matched a field with a wildcard pattern. Consider using `..` instead",
 +                            );
 +                        } else {
 +                            let mut normal = vec![];
 +
 +                            for field in pfields {
 +                                match field.pat.kind {
 +                                    PatKind::Wild => {},
 +                                    _ => {
 +                                        if let Ok(n) = cx.sess().source_map().span_to_snippet(field.span) {
 +                                            normal.push(n);
 +                                        }
 +                                    },
 +                                }
 +                            }
 +
 +                            span_lint_and_help(
 +                                cx,
 +                                UNNEEDED_FIELD_PATTERN,
 +                                field.span,
 +                                "You matched a field with a wildcard pattern. Consider using `..` \
 +                                 instead",
 +                                None,
 +                                &format!("Try with `{} {{ {}, .. }}`", type_name, normal[..].join(", ")),
 +                            );
 +                        }
 +                    }
 +                }
 +            }
 +        }
 +
 +        if let PatKind::Ident(left, ident, Some(ref right)) = pat.kind {
 +            let left_binding = match left {
 +                BindingMode::ByRef(Mutability::Mut) => "ref mut ",
 +                BindingMode::ByRef(Mutability::Not) => "ref ",
 +                BindingMode::ByValue(..) => "",
 +            };
 +
 +            if let PatKind::Wild = right.kind {
 +                span_lint_and_sugg(
 +                    cx,
 +                    REDUNDANT_PATTERN,
 +                    pat.span,
 +                    &format!(
 +                        "the `{} @ _` pattern can be written as just `{}`",
 +                        ident.name, ident.name,
 +                    ),
 +                    "try",
 +                    format!("{}{}", left_binding, ident.name),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +        }
 +
 +        check_unneeded_wildcard_pattern(cx, pat);
 +    }
 +
 +    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, _: Span, _: NodeId) {
 +        let mut registered_names: FxHashMap<String, Span> = FxHashMap::default();
 +
 +        for arg in &fn_kind.decl().inputs {
 +            if let PatKind::Ident(_, ident, None) = arg.pat.kind {
 +                let arg_name = ident.to_string();
 +
 +                if arg_name.starts_with('_') {
 +                    if let Some(correspondence) = registered_names.get(&arg_name[1..]) {
 +                        span_lint(
 +                            cx,
 +                            DUPLICATE_UNDERSCORE_ARGUMENT,
 +                            *correspondence,
 +                            &format!(
 +                                "`{}` already exists, having another argument having almost the same \
 +                                 name makes code comprehension and documentation more difficult",
 +                                arg_name[1..].to_owned()
 +                            ),
 +                        );
 +                    }
 +                } else {
 +                    registered_names.insert(arg_name, arg.pat.span);
 +                }
 +            }
 +        }
 +    }
 +
 +    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
 +        if in_external_macro(cx.sess(), expr.span) {
 +            return;
 +        }
 +        match expr.kind {
-             ExprKind::Call(ref paren, _) => {
-                 if let ExprKind::Paren(ref closure) = paren.kind {
-                     if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.kind {
-                         let mut visitor = ReturnVisitor::new();
-                         visitor.visit_expr(block);
-                         if !visitor.found_return {
-                             span_lint_and_then(
-                                 cx,
-                                 REDUNDANT_CLOSURE_CALL,
-                                 expr.span,
-                                 "Try not to call a closure in the expression where it is declared.",
-                                 |diag| {
-                                     if decl.inputs.is_empty() {
-                                         let mut app = Applicability::MachineApplicable;
-                                         let hint =
-                                             snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
-                                         diag.span_suggestion(expr.span, "Try doing something like: ", hint, app);
-                                     }
-                                 },
-                             );
-                         }
-                     }
-                 }
-             },
 +            ExprKind::Unary(UnOp::Neg, ref inner) => {
 +                if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
 +                    span_lint(
 +                        cx,
 +                        DOUBLE_NEG,
 +                        expr.span,
 +                        "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
 +                    );
 +                }
 +            },
 +            ExprKind::Lit(ref lit) => Self::check_lit(cx, lit),
 +            _ => (),
 +        }
 +    }
-     fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {
-         for w in block.stmts.windows(2) {
-             if_chain! {
-                 if let StmtKind::Local(ref local) = w[0].kind;
-                 if let Option::Some(ref t) = local.init;
-                 if let ExprKind::Closure(..) = t.kind;
-                 if let PatKind::Ident(_, ident, _) = local.pat.kind;
-                 if let StmtKind::Semi(ref second) = w[1].kind;
-                 if let ExprKind::Assign(_, ref call, _) = second.kind;
-                 if let ExprKind::Call(ref closure, _) = call.kind;
-                 if let ExprKind::Path(_, ref path) = closure.kind;
-                 then {
-                     if ident == path.segments[0].ident {
-                         span_lint(
-                             cx,
-                             REDUNDANT_CLOSURE_CALL,
-                             second.span,
-                             "Closure called just once immediately after it was declared",
-                         );
-                     }
-                 }
-             }
-         }
-     }
 +}
 +
 +impl MiscEarlyLints {
 +    fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
 +        // We test if first character in snippet is a number, because the snippet could be an expansion
 +        // from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`.
 +        // Note that this check also covers special case that `line!()` is eagerly expanded by compiler.
 +        // See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.
 +        // FIXME: Find a better way to detect those cases.
 +        let lit_snip = match snippet_opt(cx, lit.span) {
 +            Some(snip) if snip.chars().next().map_or(false, |c| c.is_digit(10)) => snip,
 +            _ => return,
 +        };
 +
 +        if let LitKind::Int(value, lit_int_type) = lit.kind {
 +            let suffix = match lit_int_type {
 +                LitIntType::Signed(ty) => ty.name_str(),
 +                LitIntType::Unsigned(ty) => ty.name_str(),
 +                LitIntType::Unsuffixed => "",
 +            };
 +
 +            let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
 +                val
 +            } else {
 +                return; // It's useless so shouldn't lint.
 +            };
 +            // Do not lint when literal is unsuffixed.
 +            if !suffix.is_empty() && lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
 +                span_lint_and_sugg(
 +                    cx,
 +                    UNSEPARATED_LITERAL_SUFFIX,
 +                    lit.span,
 +                    "integer type suffix should be separated by an underscore",
 +                    "add an underscore",
 +                    format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +
 +            if lit_snip.starts_with("0x") {
 +                if maybe_last_sep_idx <= 2 {
 +                    // It's meaningless or causes range error.
 +                    return;
 +                }
 +                let mut seen = (false, false);
 +                for ch in lit_snip.as_bytes()[2..=maybe_last_sep_idx].iter() {
 +                    match ch {
 +                        b'a'..=b'f' => seen.0 = true,
 +                        b'A'..=b'F' => seen.1 = true,
 +                        _ => {},
 +                    }
 +                    if seen.0 && seen.1 {
 +                        span_lint(
 +                            cx,
 +                            MIXED_CASE_HEX_LITERALS,
 +                            lit.span,
 +                            "inconsistent casing in hexadecimal literal",
 +                        );
 +                        break;
 +                    }
 +                }
 +            } else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
 +                /* nothing to do */
 +            } else if value != 0 && lit_snip.starts_with('0') {
 +                span_lint_and_then(
 +                    cx,
 +                    ZERO_PREFIXED_LITERAL,
 +                    lit.span,
 +                    "this is a decimal constant",
 +                    |diag| {
 +                        diag.span_suggestion(
 +                            lit.span,
 +                            "if you mean to use a decimal constant, remove the `0` to avoid confusion",
 +                            lit_snip.trim_start_matches(|c| c == '_' || c == '0').to_string(),
 +                            Applicability::MaybeIncorrect,
 +                        );
 +                        diag.span_suggestion(
 +                            lit.span,
 +                            "if you mean to use an octal constant, use `0o`",
 +                            format!("0o{}", lit_snip.trim_start_matches(|c| c == '_' || c == '0')),
 +                            Applicability::MaybeIncorrect,
 +                        );
 +                    },
 +                );
 +            }
 +        } else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
 +            let suffix = float_ty.name_str();
 +            let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
 +                val
 +            } else {
 +                return; // It's useless so shouldn't lint.
 +            };
 +            if lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
 +                span_lint_and_sugg(
 +                    cx,
 +                    UNSEPARATED_LITERAL_SUFFIX,
 +                    lit.span,
 +                    "float type suffix should be separated by an underscore",
 +                    "add an underscore",
 +                    format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +fn check_unneeded_wildcard_pattern(cx: &EarlyContext<'_>, pat: &Pat) {
 +    if let PatKind::TupleStruct(_, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
 +        fn span_lint(cx: &EarlyContext<'_>, span: Span, only_one: bool) {
 +            span_lint_and_sugg(
 +                cx,
 +                UNNEEDED_WILDCARD_PATTERN,
 +                span,
 +                if only_one {
 +                    "this pattern is unneeded as the `..` pattern can match that element"
 +                } else {
 +                    "these patterns are unneeded as the `..` pattern can match those elements"
 +                },
 +                if only_one { "remove it" } else { "remove them" },
 +                "".to_string(),
 +                Applicability::MachineApplicable,
 +            );
 +        }
 +
 +        if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) {
 +            if let Some((left_index, left_pat)) = patterns[..rest_index]
 +                .iter()
 +                .rev()
 +                .take_while(|pat| matches!(pat.kind, PatKind::Wild))
 +                .enumerate()
 +                .last()
 +            {
 +                span_lint(cx, left_pat.span.until(patterns[rest_index].span), left_index == 0);
 +            }
 +
 +            if let Some((right_index, right_pat)) = patterns[rest_index + 1..]
 +                .iter()
 +                .take_while(|pat| matches!(pat.kind, PatKind::Wild))
 +                .enumerate()
 +                .last()
 +            {
 +                span_lint(
 +                    cx,
 +                    patterns[rest_index].span.shrink_to_hi().to(right_pat.span),
 +                    right_index == 0,
 +                );
 +            }
 +        }
 +    }
 +}
index bdce1bf15218041506f7f1b2a5301c012109e994,0000000000000000000000000000000000000000..1ad184dfc460b8358069739807854485096311b1
mode 100644,000000..100644
--- /dev/null
@@@ -1,145 -1,0 +1,145 @@@
-     // If any of the params are dropable, return true
 +use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
 +use rustc_hir as hir;
 +use rustc_hir::intravisit::FnKind;
 +use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::lint::in_external_macro;
 +use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::Span;
 +use rustc_typeck::hir_ty_to_ty;
 +
 +declare_clippy_lint! {
 +    /// **What it does:**
 +    ///
 +    /// Suggests the use of `const` in functions and methods where possible.
 +    ///
 +    /// **Why is this bad?**
 +    ///
 +    /// Not having the function const prevents callers of the function from being const as well.
 +    ///
 +    /// **Known problems:**
 +    ///
 +    /// Const functions are currently still being worked on, with some features only being available
 +    /// on nightly. This lint does not consider all edge cases currently and the suggestions may be
 +    /// incorrect if you are using this lint on stable.
 +    ///
 +    /// Also, the lint only runs one pass over the code. Consider these two non-const functions:
 +    ///
 +    /// ```rust
 +    /// fn a() -> i32 {
 +    ///     0
 +    /// }
 +    /// fn b() -> i32 {
 +    ///     a()
 +    /// }
 +    /// ```
 +    ///
 +    /// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time
 +    /// can't be const as it calls a non-const function. Making `a` const and running Clippy again,
 +    /// will suggest to make `b` const, too.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # struct Foo {
 +    /// #     random_number: usize,
 +    /// # }
 +    /// # impl Foo {
 +    /// fn new() -> Self {
 +    ///     Self { random_number: 42 }
 +    /// }
 +    /// # }
 +    /// ```
 +    ///
 +    /// Could be a const fn:
 +    ///
 +    /// ```rust
 +    /// # struct Foo {
 +    /// #     random_number: usize,
 +    /// # }
 +    /// # impl Foo {
 +    /// const fn new() -> Self {
 +    ///     Self { random_number: 42 }
 +    /// }
 +    /// # }
 +    /// ```
 +    pub MISSING_CONST_FOR_FN,
 +    nursery,
 +    "Lint functions definitions that could be made `const fn`"
 +}
 +
 +declare_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
 +
 +impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
 +    fn check_fn(
 +        &mut self,
 +        cx: &LateContext<'_>,
 +        kind: FnKind<'_>,
 +        _: &FnDecl<'_>,
 +        _: &Body<'_>,
 +        span: Span,
 +        hir_id: HirId,
 +    ) {
 +        let def_id = cx.tcx.hir().local_def_id(hir_id);
 +
 +        if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
 +            return;
 +        }
 +
 +        // Building MIR for `fn`s with unsatisfiable preds results in ICE.
 +        if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {
 +            return;
 +        }
 +
 +        // Perform some preliminary checks that rule out constness on the Clippy side. This way we
 +        // can skip the actual const check and return early.
 +        match kind {
 +            FnKind::ItemFn(_, generics, header, ..) => {
 +                let has_const_generic_params = generics
 +                    .params
 +                    .iter()
 +                    .any(|param| matches!(param.kind, GenericParamKind::Const{ .. }));
 +
 +                if already_const(header) || has_const_generic_params {
 +                    return;
 +                }
 +            },
 +            FnKind::Method(_, sig, ..) => {
 +                if trait_ref_of_method(cx, hir_id).is_some()
 +                    || already_const(sig.header)
 +                    || method_accepts_dropable(cx, sig.decl.inputs)
 +                {
 +                    return;
 +                }
 +            },
 +            FnKind::Closure(..) => return,
 +        }
 +
 +        let mir = cx.tcx.optimized_mir(def_id);
 +
 +        if let Err((span, err)) = is_min_const_fn(cx.tcx, def_id.to_def_id(), &mir) {
 +            if rustc_mir::const_eval::is_min_const_fn(cx.tcx, def_id.to_def_id()) {
 +                cx.tcx.sess.span_err(span, &err);
 +            }
 +        } else {
 +            span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`");
 +        }
 +    }
 +}
 +
 +/// Returns true if any of the method parameters is a type that implements `Drop`. The method
 +/// can't be made const then, because `drop` can't be const-evaluated.
 +fn method_accepts_dropable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
++    // If any of the params are droppable, return true
 +    param_tys.iter().any(|hir_ty| {
 +        let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
 +        has_drop(cx, ty_ty)
 +    })
 +}
 +
 +// We don't have to lint on something that's already `const`
 +#[must_use]
 +fn already_const(header: hir::FnHeader) -> bool {
 +    header.constness == Constness::Const
 +}
index 5d4436bd206d2b48d61edcbbee93b20cd02b26bf,0000000000000000000000000000000000000000..b1d788b5c683f4587cebc071623e2326e001160a
mode 100644,000000..100644
--- /dev/null
@@@ -1,148 -1,0 +1,148 @@@
-     /// **What it does:** Checks for modulo arithemtic.
 +use crate::consts::{constant, Constant};
 +use crate::utils::{sext, span_lint_and_then};
 +use if_chain::if_chain;
 +use rustc_hir::{BinOpKind, Expr, ExprKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::ty::{self};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use std::fmt::Display;
 +
 +declare_clippy_lint! {
++    /// **What it does:** Checks for modulo arithmetic.
 +    ///
 +    /// **Why is this bad?** The results of modulo (%) operation might differ
 +    /// depending on the language, when negative numbers are involved.
 +    /// If you interop with different languages it might be beneficial
 +    /// to double check all places that use modulo arithmetic.
 +    ///
 +    /// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x = -17 % 3;
 +    /// ```
 +    pub MODULO_ARITHMETIC,
 +    restriction,
 +    "any modulo arithmetic statement"
 +}
 +
 +declare_lint_pass!(ModuloArithmetic => [MODULO_ARITHMETIC]);
 +
 +struct OperandInfo {
 +    string_representation: Option<String>,
 +    is_negative: bool,
 +    is_integral: bool,
 +}
 +
 +fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<OperandInfo> {
 +    match constant(cx, cx.typeck_results(), operand) {
 +        Some((Constant::Int(v), _)) => match cx.typeck_results().expr_ty(expr).kind {
 +            ty::Int(ity) => {
 +                let value = sext(cx.tcx, v, ity);
 +                return Some(OperandInfo {
 +                    string_representation: Some(value.to_string()),
 +                    is_negative: value < 0,
 +                    is_integral: true,
 +                });
 +            },
 +            ty::Uint(_) => {
 +                return Some(OperandInfo {
 +                    string_representation: None,
 +                    is_negative: false,
 +                    is_integral: true,
 +                });
 +            },
 +            _ => {},
 +        },
 +        Some((Constant::F32(f), _)) => {
 +            return Some(floating_point_operand_info(&f));
 +        },
 +        Some((Constant::F64(f), _)) => {
 +            return Some(floating_point_operand_info(&f));
 +        },
 +        _ => {},
 +    }
 +    None
 +}
 +
 +fn floating_point_operand_info<T: Display + PartialOrd + From<f32>>(f: &T) -> OperandInfo {
 +    OperandInfo {
 +        string_representation: Some(format!("{:.3}", *f)),
 +        is_negative: *f < 0.0.into(),
 +        is_integral: false,
 +    }
 +}
 +
 +fn might_have_negative_value(t: &ty::TyS<'_>) -> bool {
 +    t.is_signed() || t.is_floating_point()
 +}
 +
 +fn check_const_operands<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx Expr<'_>,
 +    lhs_operand: &OperandInfo,
 +    rhs_operand: &OperandInfo,
 +) {
 +    if lhs_operand.is_negative ^ rhs_operand.is_negative {
 +        span_lint_and_then(
 +            cx,
 +            MODULO_ARITHMETIC,
 +            expr.span,
 +            &format!(
 +                "you are using modulo operator on constants with different signs: `{} % {}`",
 +                lhs_operand.string_representation.as_ref().unwrap(),
 +                rhs_operand.string_representation.as_ref().unwrap()
 +            ),
 +            |diag| {
 +                diag.note("double check for expected result especially when interoperating with different languages");
 +                if lhs_operand.is_integral {
 +                    diag.note("or consider using `rem_euclid` or similar function");
 +                }
 +            },
 +        );
 +    }
 +}
 +
 +fn check_non_const_operands<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) {
 +    let operand_type = cx.typeck_results().expr_ty(operand);
 +    if might_have_negative_value(operand_type) {
 +        span_lint_and_then(
 +            cx,
 +            MODULO_ARITHMETIC,
 +            expr.span,
 +            "you are using modulo operator on types that might have different signs",
 +            |diag| {
 +                diag.note("double check for expected result especially when interoperating with different languages");
 +                if operand_type.is_integral() {
 +                    diag.note("or consider using `rem_euclid` or similar function");
 +                }
 +            },
 +        );
 +    }
 +}
 +
 +impl<'tcx> LateLintPass<'tcx> for ModuloArithmetic {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        match &expr.kind {
 +            ExprKind::Binary(op, lhs, rhs) | ExprKind::AssignOp(op, lhs, rhs) => {
 +                if let BinOpKind::Rem = op.node {
 +                    let lhs_operand = analyze_operand(lhs, cx, expr);
 +                    let rhs_operand = analyze_operand(rhs, cx, expr);
 +                    if_chain! {
 +                        if let Some(lhs_operand) = lhs_operand;
 +                        if let Some(rhs_operand) = rhs_operand;
 +                        then {
 +                            check_const_operands(cx, expr, &lhs_operand, &rhs_operand);
 +                        }
 +                        else {
 +                            check_non_const_operands(cx, expr, lhs);
 +                        }
 +                    }
 +                };
 +            },
 +            _ => {},
 +        }
 +    }
 +}
index 1d4772bb3d606a41a5dd4af3d1b9d9d8dd332ee1,0000000000000000000000000000000000000000..48ab98418e4fafe62381a541d80296af1fb9b8bc
mode 100644,000000..100644
--- /dev/null
@@@ -1,424 -1,0 +1,428 @@@
-                     if existing_name.len - count != 1 || levenstein_not_1(&interned_name, &existing_name.interned.as_str()) {
 +use crate::utils::{span_lint, span_lint_and_then};
 +use rustc_ast::ast::{
 +    Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, MacCall, Pat, PatKind,
 +};
 +use rustc_ast::attr;
 +use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
 +use rustc_lint::{EarlyContext, EarlyLintPass};
 +use rustc_middle::lint::in_external_macro;
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_span::source_map::Span;
 +use rustc_span::symbol::{Ident, Symbol};
 +use std::cmp::Ordering;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for names that are very similar and thus confusing.
 +    ///
 +    /// **Why is this bad?** It's hard to distinguish between names that differ only
 +    /// by a single character.
 +    ///
 +    /// **Known problems:** None?
 +    ///
 +    /// **Example:**
 +    /// ```ignore
 +    /// let checked_exp = something;
 +    /// let checked_expr = something_else;
 +    /// ```
 +    pub SIMILAR_NAMES,
 +    pedantic,
 +    "similarly named items and bindings"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for too many variables whose name consists of a
 +    /// single character.
 +    ///
 +    /// **Why is this bad?** It's hard to memorize what a variable means without a
 +    /// descriptive name.
 +    ///
 +    /// **Known problems:** None?
 +    ///
 +    /// **Example:**
 +    /// ```ignore
 +    /// let (a, b, c, d, e, f, g) = (...);
 +    /// ```
 +    pub MANY_SINGLE_CHAR_NAMES,
 +    style,
 +    "too many single character bindings"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks if you have variables whose name consists of just
 +    /// underscores and digits.
 +    ///
 +    /// **Why is this bad?** It's hard to memorize what a variable means without a
 +    /// descriptive name.
 +    ///
 +    /// **Known problems:** None?
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let _1 = 1;
 +    /// let ___1 = 1;
 +    /// let __1___2 = 11;
 +    /// ```
 +    pub JUST_UNDERSCORES_AND_DIGITS,
 +    style,
 +    "unclear name"
 +}
 +
 +#[derive(Copy, Clone)]
 +pub struct NonExpressiveNames {
 +    pub single_char_binding_names_threshold: u64,
 +}
 +
 +impl_lint_pass!(NonExpressiveNames => [SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES, JUST_UNDERSCORES_AND_DIGITS]);
 +
 +struct ExistingName {
 +    interned: Symbol,
 +    span: Span,
 +    len: usize,
 +    exemptions: &'static [&'static str],
 +}
 +
 +struct SimilarNamesLocalVisitor<'a, 'tcx> {
 +    names: Vec<ExistingName>,
 +    cx: &'a EarlyContext<'tcx>,
 +    lint: &'a NonExpressiveNames,
 +
 +    /// A stack of scopes containing the single-character bindings in each scope.
 +    single_char_names: Vec<Vec<Ident>>,
 +}
 +
 +impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> {
 +    fn check_single_char_names(&self) {
 +        let num_single_char_names = self.single_char_names.iter().flatten().count();
 +        let threshold = self.lint.single_char_binding_names_threshold;
 +        if num_single_char_names as u64 > threshold {
 +            let span = self
 +                .single_char_names
 +                .iter()
 +                .flatten()
 +                .map(|ident| ident.span)
 +                .collect::<Vec<_>>();
 +            span_lint(
 +                self.cx,
 +                MANY_SINGLE_CHAR_NAMES,
 +                span,
 +                &format!(
 +                    "{} bindings with single-character names in scope",
 +                    num_single_char_names
 +                ),
 +            );
 +        }
 +    }
 +}
 +
 +// this list contains lists of names that are allowed to be similar
 +// the assumption is that no name is ever contained in multiple lists.
 +#[rustfmt::skip]
 +const ALLOWED_TO_BE_SIMILAR: &[&[&str]] = &[
 +    &["parsed", "parser"],
 +    &["lhs", "rhs"],
 +    &["tx", "rx"],
 +    &["set", "get"],
 +    &["args", "arms"],
 +    &["qpath", "path"],
 +    &["lit", "lint"],
 +];
 +
 +struct SimilarNamesNameVisitor<'a, 'tcx, 'b>(&'b mut SimilarNamesLocalVisitor<'a, 'tcx>);
 +
 +impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
 +    fn visit_pat(&mut self, pat: &'tcx Pat) {
 +        match pat.kind {
 +            PatKind::Ident(_, ident, _) => {
 +                if !pat.span.from_expansion() {
 +                    self.check_ident(ident);
 +                }
 +            },
 +            PatKind::Struct(_, ref fields, _) => {
 +                for field in fields {
 +                    if !field.is_shorthand {
 +                        self.visit_pat(&field.pat);
 +                    }
 +                }
 +            },
 +            // just go through the first pattern, as either all patterns
 +            // bind the same bindings or rustc would have errored much earlier
 +            PatKind::Or(ref pats) => self.visit_pat(&pats[0]),
 +            _ => walk_pat(self, pat),
 +        }
 +    }
 +    fn visit_mac(&mut self, _mac: &MacCall) {
 +        // do not check macs
 +    }
 +}
 +
 +#[must_use]
 +fn get_exemptions(interned_name: &str) -> Option<&'static [&'static str]> {
 +    for &list in ALLOWED_TO_BE_SIMILAR {
 +        if allowed_to_be_similar(interned_name, list) {
 +            return Some(list);
 +        }
 +    }
 +    None
 +}
 +
 +#[must_use]
 +fn allowed_to_be_similar(interned_name: &str, list: &[&str]) -> bool {
 +    list.iter()
 +        .any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name))
 +}
 +
 +impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
 +    fn check_short_ident(&mut self, ident: Ident) {
 +        // Ignore shadowing
 +        if self
 +            .0
 +            .single_char_names
 +            .iter()
 +            .flatten()
 +            .any(|id| id.name == ident.name)
 +        {
 +            return;
 +        }
 +
 +        if let Some(scope) = &mut self.0.single_char_names.last_mut() {
 +            scope.push(ident);
 +        }
 +    }
 +
 +    #[allow(clippy::too_many_lines)]
 +    fn check_ident(&mut self, ident: Ident) {
 +        let interned_name = ident.name.as_str();
 +        if interned_name.chars().any(char::is_uppercase) {
 +            return;
 +        }
 +        if interned_name.chars().all(|c| c.is_digit(10) || c == '_') {
 +            span_lint(
 +                self.0.cx,
 +                JUST_UNDERSCORES_AND_DIGITS,
 +                ident.span,
 +                "consider choosing a more descriptive name",
 +            );
 +            return;
 +        }
 +        let count = interned_name.chars().count();
 +        if count < 3 {
 +            if count == 1 {
 +                self.check_short_ident(ident);
 +            }
 +            return;
 +        }
 +        for existing_name in &self.0.names {
 +            if allowed_to_be_similar(&interned_name, existing_name.exemptions) {
 +                continue;
 +            }
 +            let mut split_at = None;
 +            match existing_name.len.cmp(&count) {
 +                Ordering::Greater => {
-                     if count - existing_name.len != 1 || levenstein_not_1(&existing_name.interned.as_str(), &interned_name) {
++                    if existing_name.len - count != 1
++                        || levenstein_not_1(&interned_name, &existing_name.interned.as_str())
++                    {
 +                        continue;
 +                    }
 +                },
 +                Ordering::Less => {
++                    if count - existing_name.len != 1
++                        || levenstein_not_1(&existing_name.interned.as_str(), &interned_name)
++                    {
 +                        continue;
 +                    }
 +                },
 +                Ordering::Equal => {
 +                    let mut interned_chars = interned_name.chars();
 +                    let interned_str = existing_name.interned.as_str();
 +                    let mut existing_chars = interned_str.chars();
 +                    let first_i = interned_chars.next().expect("we know we have at least one char");
 +                    let first_e = existing_chars.next().expect("we know we have at least one char");
 +                    let eq_or_numeric = |(a, b): (char, char)| a == b || a.is_numeric() && b.is_numeric();
 +
 +                    if eq_or_numeric((first_i, first_e)) {
 +                        let last_i = interned_chars.next_back().expect("we know we have at least two chars");
 +                        let last_e = existing_chars.next_back().expect("we know we have at least two chars");
 +                        if eq_or_numeric((last_i, last_e)) {
 +                            if interned_chars
 +                                .zip(existing_chars)
 +                                .filter(|&ie| !eq_or_numeric(ie))
 +                                .count()
 +                                != 1
 +                            {
 +                                continue;
 +                            }
 +                        } else {
 +                            let second_last_i = interned_chars
 +                                .next_back()
 +                                .expect("we know we have at least three chars");
 +                            let second_last_e = existing_chars
 +                                .next_back()
 +                                .expect("we know we have at least three chars");
 +                            if !eq_or_numeric((second_last_i, second_last_e))
 +                                || second_last_i == '_'
 +                                || !interned_chars.zip(existing_chars).all(eq_or_numeric)
 +                            {
 +                                // allowed similarity foo_x, foo_y
 +                                // or too many chars differ (foo_x, boo_y) or (foox, booy)
 +                                continue;
 +                            }
 +                            split_at = interned_name.char_indices().rev().next().map(|(i, _)| i);
 +                        }
 +                    } else {
 +                        let second_i = interned_chars.next().expect("we know we have at least two chars");
 +                        let second_e = existing_chars.next().expect("we know we have at least two chars");
 +                        if !eq_or_numeric((second_i, second_e))
 +                            || second_i == '_'
 +                            || !interned_chars.zip(existing_chars).all(eq_or_numeric)
 +                        {
 +                            // allowed similarity x_foo, y_foo
 +                            // or too many chars differ (x_foo, y_boo) or (xfoo, yboo)
 +                            continue;
 +                        }
 +                        split_at = interned_name.chars().next().map(char::len_utf8);
 +                    }
 +                },
 +            }
 +            span_lint_and_then(
 +                self.0.cx,
 +                SIMILAR_NAMES,
 +                ident.span,
 +                "binding's name is too similar to existing binding",
 +                |diag| {
 +                    diag.span_note(existing_name.span, "existing binding defined here");
 +                    if let Some(split) = split_at {
 +                        diag.span_help(
 +                            ident.span,
 +                            &format!(
 +                                "separate the discriminating character by an \
 +                                 underscore like: `{}_{}`",
 +                                &interned_name[..split],
 +                                &interned_name[split..]
 +                            ),
 +                        );
 +                    }
 +                },
 +            );
 +            return;
 +        }
 +        self.0.names.push(ExistingName {
 +            exemptions: get_exemptions(&interned_name).unwrap_or(&[]),
 +            interned: ident.name,
 +            span: ident.span,
 +            len: count,
 +        });
 +    }
 +}
 +
 +impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
 +    /// ensure scoping rules work
 +    fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
 +        let n = self.names.len();
 +        let single_char_count = self.single_char_names.len();
 +        f(self);
 +        self.names.truncate(n);
 +        self.single_char_names.truncate(single_char_count);
 +    }
 +}
 +
 +impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
 +    fn visit_local(&mut self, local: &'tcx Local) {
 +        if let Some(ref init) = local.init {
 +            self.apply(|this| walk_expr(this, &**init));
 +        }
 +        // add the pattern after the expression because the bindings aren't available
 +        // yet in the init
 +        // expression
 +        SimilarNamesNameVisitor(self).visit_pat(&*local.pat);
 +    }
 +    fn visit_block(&mut self, blk: &'tcx Block) {
 +        self.single_char_names.push(vec![]);
 +
 +        self.apply(|this| walk_block(this, blk));
 +
 +        self.check_single_char_names();
 +        self.single_char_names.pop();
 +    }
 +    fn visit_arm(&mut self, arm: &'tcx Arm) {
 +        self.single_char_names.push(vec![]);
 +
 +        self.apply(|this| {
 +            SimilarNamesNameVisitor(this).visit_pat(&arm.pat);
 +            this.apply(|this| walk_expr(this, &arm.body));
 +        });
 +
 +        self.check_single_char_names();
 +        self.single_char_names.pop();
 +    }
 +    fn visit_item(&mut self, _: &Item) {
 +        // do not recurse into inner items
 +    }
 +    fn visit_mac(&mut self, _mac: &MacCall) {
 +        // do not check macs
 +    }
 +}
 +
 +impl EarlyLintPass for NonExpressiveNames {
 +    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
 +        if in_external_macro(cx.sess, item.span) {
 +            return;
 +        }
 +
 +        if let ItemKind::Fn(_, ref sig, _, Some(ref blk)) = item.kind {
 +            do_check(self, cx, &item.attrs, &sig.decl, blk);
 +        }
 +    }
 +
 +    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
 +        if in_external_macro(cx.sess, item.span) {
 +            return;
 +        }
 +
 +        if let AssocItemKind::Fn(_, ref sig, _, Some(ref blk)) = item.kind {
 +            do_check(self, cx, &item.attrs, &sig.decl, blk);
 +        }
 +    }
 +}
 +
 +fn do_check(lint: &mut NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) {
 +    if !attr::contains_name(attrs, sym!(test)) {
 +        let mut visitor = SimilarNamesLocalVisitor {
 +            names: Vec::new(),
 +            cx,
 +            lint,
 +            single_char_names: vec![vec![]],
 +        };
 +
 +        // initialize with function arguments
 +        for arg in &decl.inputs {
 +            SimilarNamesNameVisitor(&mut visitor).visit_pat(&arg.pat);
 +        }
 +        // walk all other bindings
 +        walk_block(&mut visitor, blk);
 +
 +        visitor.check_single_char_names();
 +    }
 +}
 +
 +/// Precondition: `a_name.chars().count() < b_name.chars().count()`.
 +#[must_use]
 +fn levenstein_not_1(a_name: &str, b_name: &str) -> bool {
 +    debug_assert!(a_name.chars().count() < b_name.chars().count());
 +    let mut a_chars = a_name.chars();
 +    let mut b_chars = b_name.chars();
 +    while let (Some(a), Some(b)) = (a_chars.next(), b_chars.next()) {
 +        if a == b {
 +            continue;
 +        }
 +        if let Some(b2) = b_chars.next() {
 +            // check if there's just one character inserted
 +            return a != b2 || a_chars.ne(b_chars);
 +        } else {
 +            // tuple
 +            // ntuple
 +            return true;
 +        }
 +    }
 +    // for item in items
 +    true
 +}
index 065f863b8654e0dddac2cf299614c803b59f411a,0000000000000000000000000000000000000000..9494efe736cce2a37f7efafdf211b62a6e075214
mode 100644,000000..100644
--- /dev/null
@@@ -1,268 -1,0 +1,268 @@@
- /// A struct containing information about occurences of the
 +use crate::utils;
 +use crate::utils::sugg::Sugg;
 +use crate::utils::{match_type, paths, span_lint_and_sugg};
 +use if_chain::if_chain;
 +
 +use rustc_errors::Applicability;
 +use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
 +use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, MatchSource, Mutability, PatKind, UnOp};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::hir::map::Map;
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +
 +declare_clippy_lint! {
 +    /// **What it does:**
 +    /// Lints usage of  `if let Some(v) = ... { y } else { x }` which is more
 +    /// idiomatically done with `Option::map_or` (if the else bit is a simple
 +    /// expression) or `Option::map_or_else` (if the else bit is a longer
 +    /// block).
 +    ///
 +    /// **Why is this bad?**
 +    /// Using the dedicated functions of the Option type is clearer and
 +    /// more concise than an if let expression.
 +    ///
 +    /// **Known problems:**
 +    /// This lint uses whether the block is just an expression or if it has
 +    /// more statements to decide whether to use `Option::map_or` or
 +    /// `Option::map_or_else`. If you have a single expression which calls
 +    /// an expensive function, then it would be more efficient to use
 +    /// `Option::map_or_else`, but this lint would suggest `Option::map_or`.
 +    ///
 +    /// Also, this lint uses a deliberately conservative metric for checking
 +    /// if the inside of either body contains breaks or continues which will
 +    /// cause it to not suggest a fix if either block contains a loop with
 +    /// continues or breaks contained within the loop.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// # let optional: Option<u32> = Some(0);
 +    /// # fn do_complicated_function() -> u32 { 5 };
 +    /// let _ = if let Some(foo) = optional {
 +    ///     foo
 +    /// } else {
 +    ///     5
 +    /// };
 +    /// let _ = if let Some(foo) = optional {
 +    ///     foo
 +    /// } else {
 +    ///     let y = do_complicated_function();
 +    ///     y*y
 +    /// };
 +    /// ```
 +    ///
 +    /// should be
 +    ///
 +    /// ```rust
 +    /// # let optional: Option<u32> = Some(0);
 +    /// # fn do_complicated_function() -> u32 { 5 };
 +    /// let _ = optional.map_or(5, |foo| foo);
 +    /// let _ = optional.map_or_else(||{
 +    ///     let y = do_complicated_function();
 +    ///     y*y
 +    /// }, |foo| foo);
 +    /// ```
 +    pub OPTION_IF_LET_ELSE,
 +    pedantic,
 +    "reimplementation of Option::map_or"
 +}
 +
 +declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]);
 +
 +/// Returns true iff the given expression is the result of calling `Result::ok`
 +fn is_result_ok(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
 +    if let ExprKind::MethodCall(ref path, _, &[ref receiver], _) = &expr.kind {
 +        path.ident.name.to_ident_string() == "ok"
 +            && match_type(cx, &cx.typeck_results().expr_ty(&receiver), &paths::RESULT)
 +    } else {
 +        false
 +    }
 +}
 +
++/// A struct containing information about occurrences of the
 +/// `if let Some(..) = .. else` construct that this lint detects.
 +struct OptionIfLetElseOccurence {
 +    option: String,
 +    method_sugg: String,
 +    some_expr: String,
 +    none_expr: String,
 +    wrap_braces: bool,
 +}
 +
 +struct ReturnBreakContinueMacroVisitor {
 +    seen_return_break_continue: bool,
 +}
 +impl ReturnBreakContinueMacroVisitor {
 +    fn new() -> ReturnBreakContinueMacroVisitor {
 +        ReturnBreakContinueMacroVisitor {
 +            seen_return_break_continue: false,
 +        }
 +    }
 +}
 +impl<'tcx> Visitor<'tcx> for ReturnBreakContinueMacroVisitor {
 +    type Map = Map<'tcx>;
 +    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
 +        NestedVisitorMap::None
 +    }
 +
 +    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
 +        if self.seen_return_break_continue {
 +            // No need to look farther if we've already seen one of them
 +            return;
 +        }
 +        match &ex.kind {
 +            ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => {
 +                self.seen_return_break_continue = true;
 +            },
 +            // Something special could be done here to handle while or for loop
 +            // desugaring, as this will detect a break if there's a while loop
 +            // or a for loop inside the expression.
 +            _ => {
 +                if utils::in_macro(ex.span) {
 +                    self.seen_return_break_continue = true;
 +                } else {
 +                    rustc_hir::intravisit::walk_expr(self, ex);
 +                }
 +            },
 +        }
 +    }
 +}
 +
 +fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
 +    let mut recursive_visitor = ReturnBreakContinueMacroVisitor::new();
 +    recursive_visitor.visit_expr(expression);
 +    recursive_visitor.seen_return_break_continue
 +}
 +
 +/// Extracts the body of a given arm. If the arm contains only an expression,
 +/// then it returns the expression. Otherwise, it returns the entire block
 +fn extract_body_from_arm<'a>(arm: &'a Arm<'a>) -> Option<&'a Expr<'a>> {
 +    if let ExprKind::Block(
 +        Block {
 +            stmts: statements,
 +            expr: Some(expr),
 +            ..
 +        },
 +        _,
 +    ) = &arm.body.kind
 +    {
 +        if let [] = statements {
 +            Some(&expr)
 +        } else {
 +            Some(&arm.body)
 +        }
 +    } else {
 +        None
 +    }
 +}
 +
 +/// If this is the else body of an if/else expression, then we need to wrap
 +/// it in curcly braces. Otherwise, we don't.
 +fn should_wrap_in_braces(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| {
 +        if let Some(Expr {
 +            kind:
 +                ExprKind::Match(
 +                    _,
 +                    arms,
 +                    MatchSource::IfDesugar {
 +                        contains_else_clause: true,
 +                    }
 +                    | MatchSource::IfLetDesugar {
 +                        contains_else_clause: true,
 +                    },
 +                ),
 +            ..
 +        }) = parent.expr
 +        {
 +            expr.hir_id == arms[1].body.hir_id
 +        } else {
 +            false
 +        }
 +    })
 +}
 +
 +fn format_option_in_sugg(cx: &LateContext<'_>, cond_expr: &Expr<'_>, as_ref: bool, as_mut: bool) -> String {
 +    format!(
 +        "{}{}",
 +        Sugg::hir(cx, cond_expr, "..").maybe_par(),
 +        if as_mut {
 +            ".as_mut()"
 +        } else if as_ref {
 +            ".as_ref()"
 +        } else {
 +            ""
 +        }
 +    )
 +}
 +
 +/// If this expression is the option if let/else construct we're detecting, then
 +/// this function returns an `OptionIfLetElseOccurence` struct with details if
 +/// this construct is found, or None if this construct is not found.
 +fn detect_option_if_let_else(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<OptionIfLetElseOccurence> {
 +    if_chain! {
 +        if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly
 +        if let ExprKind::Match(cond_expr, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind;
 +        if arms.len() == 2;
 +        if !is_result_ok(cx, cond_expr); // Don't lint on Result::ok because a different lint does it already
 +        if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind;
 +        if utils::match_qpath(struct_qpath, &paths::OPTION_SOME);
 +        if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind;
 +        if !contains_return_break_continue_macro(arms[0].body);
 +        if !contains_return_break_continue_macro(arms[1].body);
 +        then {
 +            let capture_mut = if bind_annotation == &BindingAnnotation::Mutable { "mut " } else { "" };
 +            let some_body = extract_body_from_arm(&arms[0])?;
 +            let none_body = extract_body_from_arm(&arms[1])?;
 +            let method_sugg = match &none_body.kind {
 +                ExprKind::Block(..) => "map_or_else",
 +                _ => "map_or",
 +            };
 +            let capture_name = id.name.to_ident_string();
 +            let wrap_braces = should_wrap_in_braces(cx, expr);
 +            let (as_ref, as_mut) = match &cond_expr.kind {
 +                ExprKind::AddrOf(_, Mutability::Not, _) => (true, false),
 +                ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true),
 +                _ => (bind_annotation == &BindingAnnotation::Ref, bind_annotation == &BindingAnnotation::RefMut),
 +            };
 +            let cond_expr = match &cond_expr.kind {
 +                // Pointer dereferencing happens automatically, so we can omit it in the suggestion
 +                ExprKind::Unary(UnOp::UnDeref, expr) | ExprKind::AddrOf(_, _, expr) => expr,
 +                _ => cond_expr,
 +            };
 +            Some(OptionIfLetElseOccurence {
 +                option: format_option_in_sugg(cx, cond_expr, as_ref, as_mut),
 +                method_sugg: method_sugg.to_string(),
 +                some_expr: format!("|{}{}| {}", capture_mut, capture_name, Sugg::hir(cx, some_body, "..")),
 +                none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")),
 +                wrap_braces,
 +            })
 +        } else {
 +            None
 +        }
 +    }
 +}
 +
 +impl<'a> LateLintPass<'a> for OptionIfLetElse {
 +    fn check_expr(&mut self, cx: &LateContext<'a>, expr: &Expr<'_>) {
 +        if let Some(detection) = detect_option_if_let_else(cx, expr) {
 +            span_lint_and_sugg(
 +                cx,
 +                OPTION_IF_LET_ELSE,
 +                expr.span,
 +                format!("use Option::{} instead of an if let/else", detection.method_sugg).as_str(),
 +                "try",
 +                format!(
 +                    "{}{}.{}({}, {}){}",
 +                    if detection.wrap_braces { "{ " } else { "" },
 +                    detection.option,
 +                    detection.method_sugg,
 +                    detection.none_expr,
 +                    detection.some_expr,
 +                    if detection.wrap_braces { " }" } else { "" },
 +                ),
 +                Applicability::MaybeIncorrect,
 +            );
 +        }
 +    }
 +}
index 10f4694640eed99907d31aedd6ee0beaed624aa7,0000000000000000000000000000000000000000..6379dffd22e372ac8305f8fce41fe8a50ad2e555
mode 100644,000000..100644
--- /dev/null
@@@ -1,154 -1,0 +1,151 @@@
-             if let Some(params) = match_function_call(cx, ex, &paths::BEGIN_PANIC);
-             if params.len() == 1;
 +use crate::utils::{is_direct_expn_of, is_expn_of, match_function_call, paths, span_lint};
 +use if_chain::if_chain;
 +use rustc_ast::ast::LitKind;
 +use rustc_hir::{Expr, ExprKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for missing parameters in `panic!`.
 +    ///
 +    /// **Why is this bad?** Contrary to the `format!` family of macros, there are
 +    /// two forms of `panic!`: if there are no parameters given, the first argument
 +    /// is not a format string and used literally. So while `format!("{}")` will
 +    /// fail to compile, `panic!("{}")` will not.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```no_run
 +    /// panic!("This `panic!` is probably missing a parameter there: {}");
 +    /// ```
 +    pub PANIC_PARAMS,
 +    style,
 +    "missing parameters in `panic!` calls"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `panic!`.
 +    ///
 +    /// **Why is this bad?** `panic!` will stop the execution of the executable
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```no_run
 +    /// panic!("even with a good reason");
 +    /// ```
 +    pub PANIC,
 +    restriction,
 +    "usage of the `panic!` macro"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `unimplemented!`.
 +    ///
 +    /// **Why is this bad?** This macro should not be present in production code
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```no_run
 +    /// unimplemented!();
 +    /// ```
 +    pub UNIMPLEMENTED,
 +    restriction,
 +    "`unimplemented!` should not be present in production code"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `todo!`.
 +    ///
 +    /// **Why is this bad?** This macro should not be present in production code
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```no_run
 +    /// todo!();
 +    /// ```
 +    pub TODO,
 +    restriction,
 +    "`todo!` should not be present in production code"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for usage of `unreachable!`.
 +    ///
 +    /// **Why is this bad?** This macro can cause code to panic
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```no_run
 +    /// unreachable!();
 +    /// ```
 +    pub UNREACHABLE,
 +    restriction,
 +    "`unreachable!` should not be present in production code"
 +}
 +
 +declare_lint_pass!(PanicUnimplemented => [PANIC_PARAMS, UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]);
 +
 +impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if_chain! {
 +            if let ExprKind::Block(ref block, _) = expr.kind;
 +            if let Some(ref ex) = block.expr;
-                     let span = get_outer_span(expr);
++            if let Some(params) = match_function_call(cx, ex, &paths::BEGIN_PANIC)
++                .or_else(|| match_function_call(cx, ex, &paths::BEGIN_PANIC_FMT));
 +            then {
++                let span = get_outer_span(expr);
 +                if is_expn_of(expr.span, "unimplemented").is_some() {
-                     let span = get_outer_span(expr);
 +                    span_lint(cx, UNIMPLEMENTED, span,
 +                              "`unimplemented` should not be present in production code");
 +                } else if is_expn_of(expr.span, "todo").is_some() {
-                     let span = get_outer_span(expr);
 +                    span_lint(cx, TODO, span,
 +                              "`todo` should not be present in production code");
 +                } else if is_expn_of(expr.span, "unreachable").is_some() {
-                     let span = get_outer_span(expr);
 +                    span_lint(cx, UNREACHABLE, span,
 +                              "`unreachable` should not be present in production code");
 +                } else if is_expn_of(expr.span, "panic").is_some() {
 +                    span_lint(cx, PANIC, span,
 +                              "`panic` should not be present in production code");
 +                    match_panic(params, expr, cx);
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +fn get_outer_span(expr: &Expr<'_>) -> Span {
 +    if_chain! {
 +        if expr.span.from_expansion();
 +        let first = expr.span.ctxt().outer_expn_data();
 +        if first.call_site.from_expansion();
 +        let second = first.call_site.ctxt().outer_expn_data();
 +        then {
 +            second.call_site
 +        } else {
 +            expr.span
 +        }
 +    }
 +}
 +
 +fn match_panic(params: &[Expr<'_>], expr: &Expr<'_>, cx: &LateContext<'_>) {
 +    if_chain! {
 +        if let ExprKind::Lit(ref lit) = params[0].kind;
 +        if is_direct_expn_of(expr.span, "panic").is_some();
 +        if let LitKind::Str(ref string, _) = lit.node;
 +        let string = string.as_str().replace("{{", "").replace("}}", "");
 +        if let Some(par) = string.find('{');
 +        if string[par..].contains('}');
 +        if params[0].span.source_callee().is_none();
 +        if params[0].span.lo() != params[0].span.hi();
 +        then {
 +            span_lint(cx, PANIC_PARAMS, params[0].span,
 +                      "you probably are missing some parameter in your format string");
 +        }
 +    }
 +}
index fda7480194dce274089f7c765b78eb2e88e0ecac,0000000000000000000000000000000000000000..7932be0d4b1f260a59b3d839002d3747bb1a9ad1
mode 100644,000000..100644
--- /dev/null
@@@ -1,613 -1,0 +1,619 @@@
 +use crate::utils::{
 +    fn_has_unsatisfiable_preds, has_drop, is_copy, is_type_diagnostic_item, match_def_path, match_type, paths,
 +    snippet_opt, span_lint_hir, span_lint_hir_and_then, walk_ptrs_ty_depth,
 +};
 +use if_chain::if_chain;
 +use rustc_data_structures::{fx::FxHashMap, transitive_relation::TransitiveRelation};
 +use rustc_errors::Applicability;
 +use rustc_hir::intravisit::FnKind;
 +use rustc_hir::{def_id, Body, FnDecl, HirId};
 +use rustc_index::bit_set::{BitSet, HybridBitSet};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::mir::{
 +    self, traversal,
 +    visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor as _},
 +};
 +use rustc_middle::ty::{self, fold::TypeVisitor, Ty};
 +use rustc_mir::dataflow::BottomValue;
 +use rustc_mir::dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::{BytePos, Span};
 +use std::convert::TryFrom;
 +
 +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
 +    /// value that is going to be dropped without further use.
 +    ///
 +    /// **Why is this bad?** It is not always possible for the compiler to eliminate useless
 +    /// allocations and deallocations generated by redundant `clone()`s.
 +    ///
 +    /// **Known problems:**
 +    ///
 +    /// False-negatives: analysis performed by this lint is conservative and limited.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # use std::path::Path;
 +    /// # #[derive(Clone)]
 +    /// # struct Foo;
 +    /// # impl Foo {
 +    /// #     fn new() -> Self { Foo {} }
 +    /// # }
 +    /// # fn call(x: Foo) {}
 +    /// {
 +    ///     let x = Foo::new();
 +    ///     call(x.clone());
 +    ///     call(x.clone()); // this can just pass `x`
 +    /// }
 +    ///
 +    /// ["lorem", "ipsum"].join(" ").to_string();
 +    ///
 +    /// Path::new("/a/b").join("c").to_path_buf();
 +    /// ```
 +    pub REDUNDANT_CLONE,
 +    perf,
 +    "`clone()` of an owned value that is going to be dropped immediately"
 +}
 +
 +declare_lint_pass!(RedundantClone => [REDUNDANT_CLONE]);
 +
 +impl<'tcx> LateLintPass<'tcx> for RedundantClone {
 +    #[allow(clippy::too_many_lines)]
 +    fn check_fn(
 +        &mut self,
 +        cx: &LateContext<'tcx>,
 +        _: FnKind<'tcx>,
 +        _: &'tcx FnDecl<'_>,
 +        body: &'tcx Body<'_>,
 +        _: Span,
 +        _: HirId,
 +    ) {
 +        let def_id = cx.tcx.hir().body_owner_def_id(body.id());
 +
 +        // Building MIR for `fn`s with unsatisfiable preds results in ICE.
 +        if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {
 +            return;
 +        }
 +
 +        let mir = cx.tcx.optimized_mir(def_id.to_def_id());
 +
 +        let maybe_storage_live_result = MaybeStorageLive
 +            .into_engine(cx.tcx, mir, def_id.to_def_id())
 +            .iterate_to_fixpoint()
 +            .into_results_cursor(mir);
 +        let mut possible_borrower = {
 +            let mut vis = PossibleBorrowerVisitor::new(cx, mir);
 +            vis.visit_body(&mir);
 +            vis.into_map(cx, maybe_storage_live_result)
 +        };
 +
 +        for (bb, bbdata) in mir.basic_blocks().iter_enumerated() {
 +            let terminator = bbdata.terminator();
 +
 +            if terminator.source_info.span.from_expansion() {
 +                continue;
 +            }
 +
 +            // Give up on loops
 +            if terminator.successors().any(|s| *s == bb) {
 +                continue;
 +            }
 +
 +            let (fn_def_id, arg, arg_ty, clone_ret) =
 +                unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));
 +
 +            let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
 +                || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
 +                || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
 +                    && is_type_diagnostic_item(cx, arg_ty, sym!(string_type)));
 +
 +            let from_deref = !from_borrow
 +                && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
 +                    || match_def_path(cx, fn_def_id, &paths::OS_STR_TO_OS_STRING));
 +
 +            if !from_borrow && !from_deref {
 +                continue;
 +            }
 +
++            if let ty::Adt(ref def, _) = arg_ty.kind {
++                if match_def_path(cx, def.did, &paths::MEM_MANUALLY_DROP) {
++                    continue;
++                }
++            }
++
 +            // `{ cloned = &arg; clone(move cloned); }` or `{ cloned = &arg; to_path_buf(cloned); }`
 +            let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));
 +
 +            let loc = mir::Location {
 +                block: bb,
 +                statement_index: bbdata.statements.len(),
 +            };
 +
 +            // `Local` to be cloned, and a local of `clone` call's destination
 +            let (local, ret_local) = if from_borrow {
 +                // `res = clone(arg)` can be turned into `res = move arg;`
 +                // if `arg` is the only borrow of `cloned` at this point.
 +
 +                if cannot_move_out || !possible_borrower.only_borrowers(&[arg], cloned, loc) {
 +                    continue;
 +                }
 +
 +                (cloned, clone_ret)
 +            } else {
 +                // `arg` is a reference as it is `.deref()`ed in the previous block.
 +                // Look into the predecessor block and find out the source of deref.
 +
 +                let ps = &mir.predecessors()[bb];
 +                if ps.len() != 1 {
 +                    continue;
 +                }
 +                let pred_terminator = mir[ps[0]].terminator();
 +
 +                // receiver of the `deref()` call
 +                let (pred_arg, deref_clone_ret) = if_chain! {
 +                    if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, res)) =
 +                        is_call_with_ref_arg(cx, mir, &pred_terminator.kind);
 +                    if res == cloned;
 +                    if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD);
 +                    if match_type(cx, pred_arg_ty, &paths::PATH_BUF)
 +                        || match_type(cx, pred_arg_ty, &paths::OS_STRING);
 +                    then {
 +                        (pred_arg, res)
 +                    } else {
 +                        continue;
 +                    }
 +                };
 +
 +                let (local, cannot_move_out) =
 +                    unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0]));
 +                let loc = mir::Location {
 +                    block: bb,
 +                    statement_index: mir.basic_blocks()[bb].statements.len(),
 +                };
 +
 +                // This can be turned into `res = move local` if `arg` and `cloned` are not borrowed
 +                // at the last statement:
 +                //
 +                // ```
 +                // pred_arg = &local;
 +                // cloned = deref(pred_arg);
 +                // arg = &cloned;
 +                // StorageDead(pred_arg);
 +                // res = to_path_buf(cloned);
 +                // ```
 +                if cannot_move_out || !possible_borrower.only_borrowers(&[arg, cloned], local, loc) {
 +                    continue;
 +                }
 +
 +                (local, deref_clone_ret)
 +            };
 +
 +            let is_temp = mir.local_kind(ret_local) == mir::LocalKind::Temp;
 +
 +            // 1. `local` can be moved out if it is not used later.
 +            // 2. If `ret_local` is a temporary and is neither consumed nor mutated, we can remove this `clone`
 +            // call anyway.
 +            let (used, consumed_or_mutated) = traversal::ReversePostorder::new(&mir, bb).skip(1).fold(
 +                (false, !is_temp),
 +                |(used, consumed), (tbb, tdata)| {
 +                    // Short-circuit
 +                    if (used && consumed) ||
 +                        // Give up on loops
 +                        tdata.terminator().successors().any(|s| *s == bb)
 +                    {
 +                        return (true, true);
 +                    }
 +
 +                    let mut vis = LocalUseVisitor {
 +                        used: (local, false),
 +                        consumed_or_mutated: (ret_local, false),
 +                    };
 +                    vis.visit_basic_block_data(tbb, tdata);
 +                    (used || vis.used.1, consumed || vis.consumed_or_mutated.1)
 +                },
 +            );
 +
 +            if !used || !consumed_or_mutated {
 +                let span = terminator.source_info.span;
 +                let scope = terminator.source_info.scope;
 +                let node = mir.source_scopes[scope]
 +                    .local_data
 +                    .as_ref()
 +                    .assert_crate_local()
 +                    .lint_root;
 +
 +                if_chain! {
 +                    if let Some(snip) = snippet_opt(cx, span);
 +                    if let Some(dot) = snip.rfind('.');
 +                    then {
 +                        let sugg_span = span.with_lo(
 +                            span.lo() + BytePos(u32::try_from(dot).unwrap())
 +                        );
 +                        let mut app = Applicability::MaybeIncorrect;
 +
 +                        let mut call_snip = &snip[dot + 1..];
 +                        // Machine applicable when `call_snip` looks like `foobar()`
 +                        if call_snip.ends_with("()") {
 +                            call_snip = call_snip[..call_snip.len()-2].trim();
 +                            if call_snip.as_bytes().iter().all(|b| b.is_ascii_alphabetic() || *b == b'_') {
 +                                app = Applicability::MachineApplicable;
 +                            }
 +                        }
 +
 +                        span_lint_hir_and_then(cx, REDUNDANT_CLONE, node, sugg_span, "redundant clone", |diag| {
 +                            diag.span_suggestion(
 +                                sugg_span,
 +                                "remove this",
 +                                String::new(),
 +                                app,
 +                            );
 +                            if used {
 +                                diag.span_note(
 +                                    span,
 +                                    "cloned value is neither consumed nor mutated",
 +                                );
 +                            } else {
 +                                diag.span_note(
 +                                    span.with_hi(span.lo() + BytePos(u32::try_from(dot).unwrap())),
 +                                    "this value is dropped without further use",
 +                                );
 +                            }
 +                        });
 +                    } else {
 +                        span_lint_hir(cx, REDUNDANT_CLONE, node, span, "redundant clone");
 +                    }
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +/// If `kind` is `y = func(x: &T)` where `T: !Copy`, returns `(DefId of func, x, T, y)`.
 +fn is_call_with_ref_arg<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    mir: &'tcx mir::Body<'tcx>,
 +    kind: &'tcx mir::TerminatorKind<'tcx>,
 +) -> Option<(def_id::DefId, mir::Local, Ty<'tcx>, mir::Local)> {
 +    if_chain! {
 +        if let mir::TerminatorKind::Call { func, args, destination, .. } = kind;
 +        if args.len() == 1;
 +        if let mir::Operand::Move(mir::Place { local, .. }) = &args[0];
 +        if let ty::FnDef(def_id, _) = func.ty(&*mir, cx.tcx).kind;
 +        if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(&*mir, cx.tcx));
 +        if !is_copy(cx, inner_ty);
 +        then {
 +            Some((def_id, *local, inner_ty, destination.as_ref().map(|(dest, _)| dest)?.as_local()?))
 +        } else {
 +            None
 +        }
 +    }
 +}
 +
 +type CannotMoveOut = bool;
 +
 +/// Finds the first `to = (&)from`, and returns
 +/// ``Some((from, whether `from` cannot be moved out))``.
 +fn find_stmt_assigns_to<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    mir: &mir::Body<'tcx>,
 +    to_local: mir::Local,
 +    by_ref: bool,
 +    bb: mir::BasicBlock,
 +) -> Option<(mir::Local, CannotMoveOut)> {
 +    let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| {
 +        if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind {
 +            return if *local == to_local { Some(v) } else { None };
 +        }
 +
 +        None
 +    })?;
 +
 +    match (by_ref, &*rvalue) {
 +        (true, mir::Rvalue::Ref(_, _, place)) | (false, mir::Rvalue::Use(mir::Operand::Copy(place))) => {
 +            base_local_and_movability(cx, mir, *place)
 +        },
 +        (false, mir::Rvalue::Ref(_, _, place)) => {
 +            if let [mir::ProjectionElem::Deref] = place.as_ref().projection {
 +                base_local_and_movability(cx, mir, *place)
 +            } else {
 +                None
 +            }
 +        },
 +        _ => None,
 +    }
 +}
 +
 +/// Extracts and returns the undermost base `Local` of given `place`. Returns `place` itself
 +/// if it is already a `Local`.
 +///
 +/// Also reports whether given `place` cannot be moved out.
 +fn base_local_and_movability<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    mir: &mir::Body<'tcx>,
 +    place: mir::Place<'tcx>,
 +) -> Option<(mir::Local, CannotMoveOut)> {
 +    use rustc_middle::mir::PlaceRef;
 +
 +    // Dereference. You cannot move things out from a borrowed value.
 +    let mut deref = false;
 +    // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
 +    let mut field = false;
 +    // If projection is a slice index then clone can be removed only if the
 +    // underlying type implements Copy
 +    let mut slice = false;
 +
 +    let PlaceRef { local, mut projection } = place.as_ref();
 +    while let [base @ .., elem] = projection {
 +        projection = base;
 +        deref |= matches!(elem, mir::ProjectionElem::Deref);
 +        field |= matches!(elem, mir::ProjectionElem::Field(..))
 +            && has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
 +        slice |= matches!(elem, mir::ProjectionElem::Index(..))
 +            && !is_copy(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
 +    }
 +
 +    Some((local, deref || field || slice))
 +}
 +
 +struct LocalUseVisitor {
 +    used: (mir::Local, bool),
 +    consumed_or_mutated: (mir::Local, bool),
 +}
 +
 +impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
 +    fn visit_basic_block_data(&mut self, block: mir::BasicBlock, data: &mir::BasicBlockData<'tcx>) {
 +        let statements = &data.statements;
 +        for (statement_index, statement) in statements.iter().enumerate() {
 +            self.visit_statement(statement, mir::Location { block, statement_index });
 +        }
 +
 +        self.visit_terminator(
 +            data.terminator(),
 +            mir::Location {
 +                block,
 +                statement_index: statements.len(),
 +            },
 +        );
 +    }
 +
 +    fn visit_place(&mut self, place: &mir::Place<'tcx>, ctx: PlaceContext, _: mir::Location) {
 +        let local = place.local;
 +
 +        if local == self.used.0
 +            && !matches!(ctx, PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(_))
 +        {
 +            self.used.1 = true;
 +        }
 +
 +        if local == self.consumed_or_mutated.0 {
 +            match ctx {
 +                PlaceContext::NonMutatingUse(NonMutatingUseContext::Move)
 +                | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
 +                    self.consumed_or_mutated.1 = true;
 +                },
 +                _ => {},
 +            }
 +        }
 +    }
 +}
 +
 +/// Determines liveness of each local purely based on `StorageLive`/`Dead`.
 +#[derive(Copy, Clone)]
 +struct MaybeStorageLive;
 +
 +impl<'tcx> AnalysisDomain<'tcx> for MaybeStorageLive {
 +    type Idx = mir::Local;
 +    const NAME: &'static str = "maybe_storage_live";
 +
 +    fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize {
 +        body.local_decls.len()
 +    }
 +
 +    fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
 +        for arg in body.args_iter() {
 +            state.insert(arg);
 +        }
 +    }
 +}
 +
 +impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
 +    fn statement_effect(&self, trans: &mut impl GenKill<Self::Idx>, stmt: &mir::Statement<'tcx>, _: mir::Location) {
 +        match stmt.kind {
 +            mir::StatementKind::StorageLive(l) => trans.gen(l),
 +            mir::StatementKind::StorageDead(l) => trans.kill(l),
 +            _ => (),
 +        }
 +    }
 +
 +    fn terminator_effect(
 +        &self,
 +        _trans: &mut impl GenKill<Self::Idx>,
 +        _terminator: &mir::Terminator<'tcx>,
 +        _loc: mir::Location,
 +    ) {
 +    }
 +
 +    fn call_return_effect(
 +        &self,
 +        _in_out: &mut impl GenKill<Self::Idx>,
 +        _block: mir::BasicBlock,
 +        _func: &mir::Operand<'tcx>,
 +        _args: &[mir::Operand<'tcx>],
 +        _return_place: mir::Place<'tcx>,
 +    ) {
 +        // Nothing to do when a call returns successfully
 +    }
 +}
 +
 +impl BottomValue for MaybeStorageLive {
 +    /// bottom = dead
 +    const BOTTOM_VALUE: bool = false;
 +}
 +
 +/// Collects the possible borrowers of each local.
 +/// For example, `b = &a; c = &a;` will make `b` and (transitively) `c`
 +/// possible borrowers of `a`.
 +struct PossibleBorrowerVisitor<'a, 'tcx> {
 +    possible_borrower: TransitiveRelation<mir::Local>,
 +    body: &'a mir::Body<'tcx>,
 +    cx: &'a LateContext<'tcx>,
 +}
 +
 +impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
 +    fn new(cx: &'a LateContext<'tcx>, body: &'a mir::Body<'tcx>) -> Self {
 +        Self {
 +            possible_borrower: TransitiveRelation::default(),
 +            cx,
 +            body,
 +        }
 +    }
 +
 +    fn into_map(
 +        self,
 +        cx: &LateContext<'tcx>,
 +        maybe_live: ResultsCursor<'tcx, 'tcx, MaybeStorageLive>,
 +    ) -> PossibleBorrowerMap<'a, 'tcx> {
 +        let mut map = FxHashMap::default();
 +        for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {
 +            if is_copy(cx, self.body.local_decls[row].ty) {
 +                continue;
 +            }
 +
 +            let borrowers = self.possible_borrower.reachable_from(&row);
 +            if !borrowers.is_empty() {
 +                let mut bs = HybridBitSet::new_empty(self.body.local_decls.len());
 +                for &c in borrowers {
 +                    if c != mir::Local::from_usize(0) {
 +                        bs.insert(c);
 +                    }
 +                }
 +
 +                if !bs.is_empty() {
 +                    map.insert(row, bs);
 +                }
 +            }
 +        }
 +
 +        let bs = BitSet::new_empty(self.body.local_decls.len());
 +        PossibleBorrowerMap {
 +            map,
 +            maybe_live,
 +            bitset: (bs.clone(), bs),
 +        }
 +    }
 +}
 +
 +impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
 +    fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
 +        let lhs = place.local;
 +        match rvalue {
 +            mir::Rvalue::Ref(_, _, borrowed) => {
 +                self.possible_borrower.add(borrowed.local, lhs);
 +            },
 +            other => {
 +                if !ContainsRegion.visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) {
 +                    return;
 +                }
 +                rvalue_locals(other, |rhs| {
 +                    if lhs != rhs {
 +                        self.possible_borrower.add(rhs, lhs);
 +                    }
 +                });
 +            },
 +        }
 +    }
 +
 +    fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) {
 +        if let mir::TerminatorKind::Call {
 +            args,
 +            destination: Some((mir::Place { local: dest, .. }, _)),
 +            ..
 +        } = &terminator.kind
 +        {
 +            // If the call returns something with lifetimes,
 +            // let's conservatively assume the returned value contains lifetime of all the arguments.
 +            // For example, given `let y: Foo<'a> = foo(x)`, `y` is considered to be a possible borrower of `x`.
 +            if !ContainsRegion.visit_ty(&self.body.local_decls[*dest].ty) {
 +                return;
 +            }
 +
 +            for op in args {
 +                match op {
 +                    mir::Operand::Copy(p) | mir::Operand::Move(p) => {
 +                        self.possible_borrower.add(p.local, *dest);
 +                    },
 +                    _ => (),
 +                }
 +            }
 +        }
 +    }
 +}
 +
 +struct ContainsRegion;
 +
 +impl TypeVisitor<'_> for ContainsRegion {
 +    fn visit_region(&mut self, _: ty::Region<'_>) -> bool {
 +        true
 +    }
 +}
 +
 +fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
 +    use rustc_middle::mir::Rvalue::{Aggregate, BinaryOp, Cast, CheckedBinaryOp, Repeat, UnaryOp, Use};
 +
 +    let mut visit_op = |op: &mir::Operand<'_>| match op {
 +        mir::Operand::Copy(p) | mir::Operand::Move(p) => visit(p.local),
 +        _ => (),
 +    };
 +
 +    match rvalue {
 +        Use(op) | Repeat(op, _) | Cast(_, op, _) | UnaryOp(_, op) => visit_op(op),
 +        Aggregate(_, ops) => ops.iter().for_each(visit_op),
 +        BinaryOp(_, lhs, rhs) | CheckedBinaryOp(_, lhs, rhs) => {
 +            visit_op(lhs);
 +            visit_op(rhs);
 +        },
 +        _ => (),
 +    }
 +}
 +
 +/// Result of `PossibleBorrowerVisitor`.
 +struct PossibleBorrowerMap<'a, 'tcx> {
 +    /// Mapping `Local -> its possible borrowers`
 +    map: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
 +    maybe_live: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
 +    // Caches to avoid allocation of `BitSet` on every query
 +    bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
 +}
 +
 +impl PossibleBorrowerMap<'_, '_> {
 +    /// Returns true if the set of borrowers of `borrowed` living at `at` matches with `borrowers`.
 +    fn only_borrowers(&mut self, borrowers: &[mir::Local], borrowed: mir::Local, at: mir::Location) -> bool {
 +        self.maybe_live.seek_after_primary_effect(at);
 +
 +        self.bitset.0.clear();
 +        let maybe_live = &mut self.maybe_live;
 +        if let Some(bitset) = self.map.get(&borrowed) {
 +            for b in bitset.iter().filter(move |b| maybe_live.contains(*b)) {
 +                self.bitset.0.insert(b);
 +            }
 +        } else {
 +            return false;
 +        }
 +
 +        self.bitset.1.clear();
 +        for b in borrowers {
 +            self.bitset.1.insert(*b);
 +        }
 +
 +        self.bitset.0 == self.bitset.1
 +    }
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8aa478ea2d69f41aa77253cc4696827820fa2a7e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,151 @@@
++use crate::utils::{snippet_with_applicability, span_lint, span_lint_and_then};
++use if_chain::if_chain;
++use rustc_ast::ast;
++use rustc_ast::visit as ast_visit;
++use rustc_ast::visit::Visitor as AstVisitor;
++use rustc_errors::Applicability;
++use rustc_hir as hir;
++use rustc_hir::intravisit as hir_visit;
++use rustc_hir::intravisit::Visitor as HirVisitor;
++use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
++use rustc_middle::hir::map::Map;
++use rustc_middle::lint::in_external_macro;
++use rustc_session::{declare_lint_pass, declare_tool_lint};
++
++declare_clippy_lint! {
++    /// **What it does:** Detects closures called in the same expression where they
++    /// are defined.
++    ///
++    /// **Why is this bad?** It is unnecessarily adding to the expression's
++    /// complexity.
++    ///
++    /// **Known problems:** None.
++    ///
++    /// **Example:**
++    /// ```rust,ignore
++    /// // Bad
++    /// let a = (|| 42)()
++    ///
++    /// // Good
++    /// let a = 42
++    /// ```
++    pub REDUNDANT_CLOSURE_CALL,
++    complexity,
++    "throwaway closures called in the expression they are defined"
++}
++
++declare_lint_pass!(RedundantClosureCall => [REDUNDANT_CLOSURE_CALL]);
++
++// Used to find `return` statements or equivalents e.g., `?`
++struct ReturnVisitor {
++    found_return: bool,
++}
++
++impl ReturnVisitor {
++    #[must_use]
++    fn new() -> Self {
++        Self { found_return: false }
++    }
++}
++
++impl<'ast> ast_visit::Visitor<'ast> for ReturnVisitor {
++    fn visit_expr(&mut self, ex: &'ast ast::Expr) {
++        if let ast::ExprKind::Ret(_) = ex.kind {
++            self.found_return = true;
++        } else if let ast::ExprKind::Try(_) = ex.kind {
++            self.found_return = true;
++        }
++
++        ast_visit::walk_expr(self, ex)
++    }
++}
++
++impl EarlyLintPass for RedundantClosureCall {
++    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
++        if in_external_macro(cx.sess(), expr.span) {
++            return;
++        }
++        if_chain! {
++            if let ast::ExprKind::Call(ref paren, _) = expr.kind;
++            if let ast::ExprKind::Paren(ref closure) = paren.kind;
++            if let ast::ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.kind;
++            then {
++                let mut visitor = ReturnVisitor::new();
++                visitor.visit_expr(block);
++                if !visitor.found_return {
++                    span_lint_and_then(
++                        cx,
++                        REDUNDANT_CLOSURE_CALL,
++                        expr.span,
++                        "try not to call a closure in the expression where it is declared.",
++                        |diag| {
++                            if decl.inputs.is_empty() {
++                                let mut app = Applicability::MachineApplicable;
++                                let hint =
++                                    snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
++                                diag.span_suggestion(expr.span, "try doing something like", hint, app);
++                            }
++                        },
++                    );
++                }
++            }
++        }
++    }
++}
++
++impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
++    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
++        fn count_closure_usage<'tcx>(block: &'tcx hir::Block<'_>, path: &'tcx hir::Path<'tcx>) -> usize {
++            struct ClosureUsageCount<'tcx> {
++                path: &'tcx hir::Path<'tcx>,
++                count: usize,
++            };
++            impl<'tcx> hir_visit::Visitor<'tcx> for ClosureUsageCount<'tcx> {
++                type Map = Map<'tcx>;
++
++                fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
++                    if_chain! {
++                        if let hir::ExprKind::Call(ref closure, _) = expr.kind;
++                        if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = closure.kind;
++                        if self.path.segments[0].ident == path.segments[0].ident
++                            && self.path.res == path.res;
++                        then {
++                            self.count += 1;
++                        }
++                    }
++                    hir_visit::walk_expr(self, expr);
++                }
++
++                fn nested_visit_map(&mut self) -> hir_visit::NestedVisitorMap<Self::Map> {
++                    hir_visit::NestedVisitorMap::None
++                }
++            };
++            let mut closure_usage_count = ClosureUsageCount { path, count: 0 };
++            closure_usage_count.visit_block(block);
++            closure_usage_count.count
++        }
++
++        for w in block.stmts.windows(2) {
++            if_chain! {
++                if let hir::StmtKind::Local(ref local) = w[0].kind;
++                if let Option::Some(ref t) = local.init;
++                if let hir::ExprKind::Closure(..) = t.kind;
++                if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind;
++                if let hir::StmtKind::Semi(ref second) = w[1].kind;
++                if let hir::ExprKind::Assign(_, ref call, _) = second.kind;
++                if let hir::ExprKind::Call(ref closure, _) = call.kind;
++                if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = closure.kind;
++                if ident == path.segments[0].ident;
++                if count_closure_usage(block, path) == 1;
++                then {
++                    span_lint(
++                        cx,
++                        REDUNDANT_CLOSURE_CALL,
++                        second.span,
++                        "closure called just once immediately after it was declared",
++                    );
++                }
++            }
++        }
++    }
++}
index 901c0a65d7fef93b06cd208427787235ee4bc76c,0000000000000000000000000000000000000000..6f03e92bde36fcb64a353e23ab731379f14c2ca7
mode 100644,000000..100644
--- /dev/null
@@@ -1,392 -1,0 +1,388 @@@
-                 &format!(
-                     "`{}` is shadowed by `{}`",
-                     snippet(cx, pattern_span, "_"),
-                     snippet(cx, expr.span, "..")
-                 ),
 +use crate::reexport::Name;
 +use crate::utils::{contains_name, higher, iter_input_pats, snippet, span_lint_and_then};
 +use rustc_hir::intravisit::FnKind;
 +use rustc_hir::{
 +    Block, Body, Expr, ExprKind, FnDecl, Guard, HirId, Local, MutTy, Pat, PatKind, Path, QPath, StmtKind, Ty, TyKind,
 +    UnOp,
 +};
 +use rustc_lint::{LateContext, LateLintPass, LintContext};
 +use rustc_middle::lint::in_external_macro;
 +use rustc_middle::ty;
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for bindings that shadow other bindings already in
 +    /// scope, while just changing reference level or mutability.
 +    ///
 +    /// **Why is this bad?** Not much, in fact it's a very common pattern in Rust
 +    /// code. Still, some may opt to avoid it in their code base, they can set this
 +    /// lint to `Warn`.
 +    ///
 +    /// **Known problems:** This lint, as the other shadowing related lints,
 +    /// currently only catches very simple patterns.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let x = 1;
 +    ///
 +    /// // Bad
 +    /// let x = &x;
 +    ///
 +    /// // Good
 +    /// let y = &x; // use different variable name
 +    /// ```
 +    pub SHADOW_SAME,
 +    restriction,
 +    "rebinding a name to itself, e.g., `let mut x = &mut x`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for bindings that shadow other bindings already in
 +    /// scope, while reusing the original value.
 +    ///
 +    /// **Why is this bad?** Not too much, in fact it's a common pattern in Rust
 +    /// code. Still, some argue that name shadowing like this hurts readability,
 +    /// because a value may be bound to different things depending on position in
 +    /// the code.
 +    ///
 +    /// **Known problems:** This lint, as the other shadowing related lints,
 +    /// currently only catches very simple patterns.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// let x = 2;
 +    /// let x = x + 1;
 +    /// ```
 +    /// use different variable name:
 +    /// ```rust
 +    /// let x = 2;
 +    /// let y = x + 1;
 +    /// ```
 +    pub SHADOW_REUSE,
 +    restriction,
 +    "rebinding a name to an expression that re-uses the original value, e.g., `let x = x + 1`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for bindings that shadow other bindings already in
 +    /// scope, either without a initialization or with one that does not even use
 +    /// the original value.
 +    ///
 +    /// **Why is this bad?** Name shadowing can hurt readability, especially in
 +    /// large code bases, because it is easy to lose track of the active binding at
 +    /// any place in the code. This can be alleviated by either giving more specific
 +    /// names to bindings or introducing more scopes to contain the bindings.
 +    ///
 +    /// **Known problems:** This lint, as the other shadowing related lints,
 +    /// currently only catches very simple patterns.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// # let y = 1;
 +    /// # let z = 2;
 +    /// let x = y;
 +    ///
 +    /// // Bad
 +    /// let x = z; // shadows the earlier binding
 +    ///
 +    /// // Good
 +    /// let w = z; // use different variable name
 +    /// ```
 +    pub SHADOW_UNRELATED,
 +    pedantic,
 +    "rebinding a name without even using the original value"
 +}
 +
 +declare_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
 +
 +impl<'tcx> LateLintPass<'tcx> for Shadow {
 +    fn check_fn(
 +        &mut self,
 +        cx: &LateContext<'tcx>,
 +        _: FnKind<'tcx>,
 +        decl: &'tcx FnDecl<'_>,
 +        body: &'tcx Body<'_>,
 +        _: Span,
 +        _: HirId,
 +    ) {
 +        if in_external_macro(cx.sess(), body.value.span) {
 +            return;
 +        }
 +        check_fn(cx, decl, body);
 +    }
 +}
 +
 +fn check_fn<'tcx>(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>) {
 +    let mut bindings = Vec::with_capacity(decl.inputs.len());
 +    for arg in iter_input_pats(decl, body) {
 +        if let PatKind::Binding(.., ident, _) = arg.pat.kind {
 +            bindings.push((ident.name, ident.span))
 +        }
 +    }
 +    check_expr(cx, &body.value, &mut bindings);
 +}
 +
 +fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>, bindings: &mut Vec<(Name, Span)>) {
 +    let len = bindings.len();
 +    for stmt in block.stmts {
 +        match stmt.kind {
 +            StmtKind::Local(ref local) => check_local(cx, local, bindings),
 +            StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => check_expr(cx, e, bindings),
 +            StmtKind::Item(..) => {},
 +        }
 +    }
 +    if let Some(ref o) = block.expr {
 +        check_expr(cx, o, bindings);
 +    }
 +    bindings.truncate(len);
 +}
 +
 +fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: &mut Vec<(Name, Span)>) {
 +    if in_external_macro(cx.sess(), local.span) {
 +        return;
 +    }
 +    if higher::is_from_for_desugar(local) {
 +        return;
 +    }
 +    let Local {
 +        ref pat,
 +        ref ty,
 +        ref init,
 +        span,
 +        ..
 +    } = *local;
 +    if let Some(ref t) = *ty {
 +        check_ty(cx, t, bindings)
 +    }
 +    if let Some(ref o) = *init {
 +        check_expr(cx, o, bindings);
 +        check_pat(cx, pat, Some(o), span, bindings);
 +    } else {
 +        check_pat(cx, pat, None, span, bindings);
 +    }
 +}
 +
 +fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool {
 +    let var_ty = cx.typeck_results().node_type_opt(pat_id);
 +    var_ty.map_or(false, |var_ty| !matches!(var_ty.kind, ty::Adt(..)))
 +}
 +
 +fn check_pat<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    pat: &'tcx Pat<'_>,
 +    init: Option<&'tcx Expr<'_>>,
 +    span: Span,
 +    bindings: &mut Vec<(Name, Span)>,
 +) {
 +    // TODO: match more stuff / destructuring
 +    match pat.kind {
 +        PatKind::Binding(.., ident, ref inner) => {
 +            let name = ident.name;
 +            if is_binding(cx, pat.hir_id) {
 +                let mut new_binding = true;
 +                for tup in bindings.iter_mut() {
 +                    if tup.0 == name {
 +                        lint_shadow(cx, name, span, pat.span, init, tup.1);
 +                        tup.1 = ident.span;
 +                        new_binding = false;
 +                        break;
 +                    }
 +                }
 +                if new_binding {
 +                    bindings.push((name, ident.span));
 +                }
 +            }
 +            if let Some(ref p) = *inner {
 +                check_pat(cx, p, init, span, bindings);
 +            }
 +        },
 +        PatKind::Struct(_, pfields, _) => {
 +            if let Some(init_struct) = init {
 +                if let ExprKind::Struct(_, ref efields, _) = init_struct.kind {
 +                    for field in pfields {
 +                        let name = field.ident.name;
 +                        let efield = efields
 +                            .iter()
 +                            .find_map(|f| if f.ident.name == name { Some(&*f.expr) } else { None });
 +                        check_pat(cx, &field.pat, efield, span, bindings);
 +                    }
 +                } else {
 +                    for field in pfields {
 +                        check_pat(cx, &field.pat, init, span, bindings);
 +                    }
 +                }
 +            } else {
 +                for field in pfields {
 +                    check_pat(cx, &field.pat, None, span, bindings);
 +                }
 +            }
 +        },
 +        PatKind::Tuple(inner, _) => {
 +            if let Some(init_tup) = init {
 +                if let ExprKind::Tup(ref tup) = init_tup.kind {
 +                    for (i, p) in inner.iter().enumerate() {
 +                        check_pat(cx, p, Some(&tup[i]), p.span, bindings);
 +                    }
 +                } else {
 +                    for p in inner {
 +                        check_pat(cx, p, init, span, bindings);
 +                    }
 +                }
 +            } else {
 +                for p in inner {
 +                    check_pat(cx, p, None, span, bindings);
 +                }
 +            }
 +        },
 +        PatKind::Box(ref inner) => {
 +            if let Some(initp) = init {
 +                if let ExprKind::Box(ref inner_init) = initp.kind {
 +                    check_pat(cx, inner, Some(&**inner_init), span, bindings);
 +                } else {
 +                    check_pat(cx, inner, init, span, bindings);
 +                }
 +            } else {
 +                check_pat(cx, inner, init, span, bindings);
 +            }
 +        },
 +        PatKind::Ref(ref inner, _) => check_pat(cx, inner, init, span, bindings),
 +        // PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
 +        _ => (),
 +    }
 +}
 +
 +fn lint_shadow<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    name: Name,
 +    span: Span,
 +    pattern_span: Span,
 +    init: Option<&'tcx Expr<'_>>,
 +    prev_span: Span,
 +) {
 +    if let Some(expr) = init {
 +        if is_self_shadow(name, expr) {
 +            span_lint_and_then(
 +                cx,
 +                SHADOW_SAME,
 +                span,
 +                &format!(
 +                    "`{}` is shadowed by itself in `{}`",
 +                    snippet(cx, pattern_span, "_"),
 +                    snippet(cx, expr.span, "..")
 +                ),
 +                |diag| {
 +                    diag.span_note(prev_span, "previous binding is here");
 +                },
 +            );
 +        } else if contains_name(name, expr) {
 +            span_lint_and_then(
 +                cx,
 +                SHADOW_REUSE,
 +                pattern_span,
 +                &format!(
 +                    "`{}` is shadowed by `{}` which reuses the original value",
 +                    snippet(cx, pattern_span, "_"),
 +                    snippet(cx, expr.span, "..")
 +                ),
 +                |diag| {
 +                    diag.span_note(expr.span, "initialization happens here");
 +                    diag.span_note(prev_span, "previous binding is here");
 +                },
 +            );
 +        } else {
 +            span_lint_and_then(
 +                cx,
 +                SHADOW_UNRELATED,
 +                pattern_span,
++                &format!("`{}` is being shadowed", snippet(cx, pattern_span, "_")),
 +                |diag| {
 +                    diag.span_note(expr.span, "initialization happens here");
 +                    diag.span_note(prev_span, "previous binding is here");
 +                },
 +            );
 +        }
 +    } else {
 +        span_lint_and_then(
 +            cx,
 +            SHADOW_UNRELATED,
 +            span,
 +            &format!("`{}` shadows a previous declaration", snippet(cx, pattern_span, "_")),
 +            |diag| {
 +                diag.span_note(prev_span, "previous binding is here");
 +            },
 +        );
 +    }
 +}
 +
 +fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut Vec<(Name, Span)>) {
 +    if in_external_macro(cx.sess(), expr.span) {
 +        return;
 +    }
 +    match expr.kind {
 +        ExprKind::Unary(_, ref e)
 +        | ExprKind::Field(ref e, _)
 +        | ExprKind::AddrOf(_, _, ref e)
 +        | ExprKind::Box(ref e) => check_expr(cx, e, bindings),
 +        ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, _, _) => check_block(cx, block, bindings),
 +        // ExprKind::Call
 +        // ExprKind::MethodCall
 +        ExprKind::Array(v) | ExprKind::Tup(v) => {
 +            for e in v {
 +                check_expr(cx, e, bindings)
 +            }
 +        },
 +        ExprKind::Match(ref init, arms, _) => {
 +            check_expr(cx, init, bindings);
 +            let len = bindings.len();
 +            for arm in arms {
 +                check_pat(cx, &arm.pat, Some(&**init), arm.pat.span, bindings);
 +                // This is ugly, but needed to get the right type
 +                if let Some(ref guard) = arm.guard {
 +                    match guard {
 +                        Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
 +                    }
 +                }
 +                check_expr(cx, &arm.body, bindings);
 +                bindings.truncate(len);
 +            }
 +        },
 +        _ => (),
 +    }
 +}
 +
 +fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: &'tcx Ty<'_>, bindings: &mut Vec<(Name, Span)>) {
 +    match ty.kind {
 +        TyKind::Slice(ref sty) => check_ty(cx, sty, bindings),
 +        TyKind::Array(ref fty, ref anon_const) => {
 +            check_ty(cx, fty, bindings);
 +            check_expr(cx, &cx.tcx.hir().body(anon_const.body).value, bindings);
 +        },
 +        TyKind::Ptr(MutTy { ty: ref mty, .. }) | TyKind::Rptr(_, MutTy { ty: ref mty, .. }) => {
 +            check_ty(cx, mty, bindings)
 +        },
 +        TyKind::Tup(tup) => {
 +            for t in tup {
 +                check_ty(cx, t, bindings)
 +            }
 +        },
 +        TyKind::Typeof(ref anon_const) => check_expr(cx, &cx.tcx.hir().body(anon_const.body).value, bindings),
 +        _ => (),
 +    }
 +}
 +
 +fn is_self_shadow(name: Name, expr: &Expr<'_>) -> bool {
 +    match expr.kind {
 +        ExprKind::Box(ref inner) | ExprKind::AddrOf(_, _, ref inner) => is_self_shadow(name, inner),
 +        ExprKind::Block(ref block, _) => {
 +            block.stmts.is_empty() && block.expr.as_ref().map_or(false, |e| is_self_shadow(name, e))
 +        },
 +        ExprKind::Unary(op, ref inner) => (UnOp::UnDeref == op) && is_self_shadow(name, inner),
 +        ExprKind::Path(QPath::Resolved(_, ref path)) => path_eq_name(name, path),
 +        _ => false,
 +    }
 +}
 +
 +fn path_eq_name(name: Name, path: &Path<'_>) -> bool {
 +    !path.is_global() && path.segments.len() == 1 && path.segments[0].ident.as_str() == name.as_str()
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ac6f3d125bb422a2734be9b31d21e39d4c04fed9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,177 @@@
++use crate::utils::{get_trait_def_id, paths, span_lint, span_lint_and_help};
++use if_chain::if_chain;
++use rustc_hir::def_id::DefId;
++use rustc_hir::{Expr, ExprKind, StmtKind};
++use rustc_lint::{LateContext, LateLintPass};
++use rustc_middle::ty;
++use rustc_middle::ty::{GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
++use rustc_session::{declare_lint_pass, declare_tool_lint};
++use rustc_span::{BytePos, Span};
++
++declare_clippy_lint! {
++    /// **What it does:** Checks for functions that expect closures of type
++    /// Fn(...) -> Ord where the implemented closure returns the unit type.
++    /// The lint also suggests to remove the semi-colon at the end of the statement if present.
++    ///
++    /// **Why is this bad?** Likely, returning the unit type is unintentional, and
++    /// could simply be caused by an extra semi-colon. Since () implements Ord
++    /// it doesn't cause a compilation error.
++    /// This is the same reasoning behind the unit_cmp lint.
++    ///
++    /// **Known problems:** If returning unit is intentional, then there is no
++    /// way of specifying this without triggering needless_return lint
++    ///
++    /// **Example:**
++    ///
++    /// ```rust
++    /// let mut twins = vec!((1,1), (2,2));
++    /// twins.sort_by_key(|x| { x.1; });
++    /// ```
++    pub UNIT_RETURN_EXPECTING_ORD,
++    correctness,
++    "fn arguments of type Fn(...) -> Ord returning the unit type ()."
++}
++
++declare_lint_pass!(UnitReturnExpectingOrd => [UNIT_RETURN_EXPECTING_ORD]);
++
++fn get_trait_predicates_for_trait_id<'tcx>(
++    cx: &LateContext<'tcx>,
++    generics: GenericPredicates<'tcx>,
++    trait_id: Option<DefId>,
++) -> Vec<TraitPredicate<'tcx>> {
++    let mut preds = Vec::new();
++    for (pred, _) in generics.predicates {
++        if_chain! {
++            if let PredicateKind::Trait(poly_trait_pred, _) = pred.kind();
++            let trait_pred = cx.tcx.erase_late_bound_regions(&poly_trait_pred);
++            if let Some(trait_def_id) = trait_id;
++            if trait_def_id == trait_pred.trait_ref.def_id;
++            then {
++                preds.push(trait_pred);
++            }
++        }
++    }
++    preds
++}
++
++fn get_projection_pred<'tcx>(
++    cx: &LateContext<'tcx>,
++    generics: GenericPredicates<'tcx>,
++    pred: TraitPredicate<'tcx>,
++) -> Option<ProjectionPredicate<'tcx>> {
++    generics.predicates.iter().find_map(|(proj_pred, _)| {
++        if let PredicateKind::Projection(proj_pred) = proj_pred.kind() {
++            let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred);
++            if projection_pred.projection_ty.substs == pred.trait_ref.substs {
++                return Some(projection_pred);
++            }
++        }
++        None
++    })
++}
++
++fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Vec<(usize, String)> {
++    let mut args_to_check = Vec::new();
++    if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
++        let fn_sig = cx.tcx.fn_sig(def_id);
++        let generics = cx.tcx.predicates_of(def_id);
++        let fn_mut_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().fn_mut_trait());
++        let ord_preds = get_trait_predicates_for_trait_id(cx, generics, get_trait_def_id(cx, &paths::ORD));
++        let partial_ord_preds =
++            get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().partial_ord_trait());
++        // Trying to call erase_late_bound_regions on fn_sig.inputs() gives the following error
++        // The trait `rustc::ty::TypeFoldable<'_>` is not implemented for `&[&rustc::ty::TyS<'_>]`
++        let inputs_output = cx.tcx.erase_late_bound_regions(&fn_sig.inputs_and_output());
++        inputs_output
++            .iter()
++            .rev()
++            .skip(1)
++            .rev()
++            .enumerate()
++            .for_each(|(i, inp)| {
++                for trait_pred in &fn_mut_preds {
++                    if_chain! {
++                        if trait_pred.self_ty() == inp;
++                        if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred);
++                        then {
++                            if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.ty) {
++                                args_to_check.push((i, "Ord".to_string()));
++                            } else if partial_ord_preds.iter().any(|pord| pord.self_ty() == return_ty_pred.ty) {
++                                args_to_check.push((i, "PartialOrd".to_string()));
++                            }
++                        }
++                    }
++                }
++            });
++    }
++    args_to_check
++}
++
++fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {
++    if_chain! {
++        if let ExprKind::Closure(_, _fn_decl, body_id, span, _) = arg.kind;
++        if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind;
++        let ret_ty = substs.as_closure().sig().output();
++        let ty = cx.tcx.erase_late_bound_regions(&ret_ty);
++        if ty.is_unit();
++        then {
++            if_chain! {
++                let body = cx.tcx.hir().body(body_id);
++                if let ExprKind::Block(block, _) = body.value.kind;
++                if block.expr.is_none();
++                if let Some(stmt) = block.stmts.last();
++                if let StmtKind::Semi(_) = stmt.kind;
++                then {
++                    let data = stmt.span.data();
++                    // Make a span out of the semicolon for the help message
++                    Some((span, Some(Span::new(data.hi-BytePos(1), data.hi, data.ctxt))))
++                } else {
++                    Some((span, None))
++                }
++            }
++        } else {
++            None
++        }
++    }
++}
++
++impl<'tcx> LateLintPass<'tcx> for UnitReturnExpectingOrd {
++    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
++        if let ExprKind::MethodCall(_, _, ref args, _) = expr.kind {
++            let arg_indices = get_args_to_check(cx, expr);
++            for (i, trait_name) in arg_indices {
++                if i < args.len() {
++                    match check_arg(cx, &args[i]) {
++                        Some((span, None)) => {
++                            span_lint(
++                                cx,
++                                UNIT_RETURN_EXPECTING_ORD,
++                                span,
++                                &format!(
++                                    "this closure returns \
++                                   the unit type which also implements {}",
++                                    trait_name
++                                ),
++                            );
++                        },
++                        Some((span, Some(last_semi))) => {
++                            span_lint_and_help(
++                                cx,
++                                UNIT_RETURN_EXPECTING_ORD,
++                                span,
++                                &format!(
++                                    "this closure returns \
++                                   the unit type which also implements {}",
++                                    trait_name
++                                ),
++                                Some(last_semi),
++                                &"probably caused by this trailing semicolon".to_string(),
++                            );
++                        },
++                        None => {},
++                    }
++                }
++            }
++        }
++    }
++}
index a48ad3185e9c2f440de3f95fd5bb0b9eb40e6ae8,0000000000000000000000000000000000000000..1bf37632e326cfa2d7a76be9361983a49fecd731
mode 100644,000000..100644
--- /dev/null
@@@ -1,181 -1,0 +1,188 @@@
-     is_type_diagnostic_item, match_def_path, match_trait_method, paths, snippet, snippet_with_macro_callsite,
-     span_lint_and_help, span_lint_and_sugg,
 +use crate::utils::{
++    get_parent_expr, is_type_diagnostic_item, match_def_path, match_trait_method, paths, snippet,
++    snippet_with_macro_callsite, span_lint_and_help, span_lint_and_sugg,
 +};
 +use if_chain::if_chain;
 +use rustc_errors::Applicability;
 +use rustc_hir::{Expr, ExprKind, HirId, MatchSource};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::ty::{self, TyS};
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `Into`, `TryInto`, `From`, `TryFrom`,`IntoIter` calls
 +    /// that useless converts to the same type as caller.
 +    ///
 +    /// **Why is this bad?** Redundant code.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// // Bad
 +    /// // format!() returns a `String`
 +    /// let s: String = format!("hello").into();
 +    ///
 +    /// // Good
 +    /// let s: String = format!("hello");
 +    /// ```
 +    pub USELESS_CONVERSION,
 +    complexity,
 +    "calls to `Into`, `TryInto`, `From`, `TryFrom`, `IntoIter` that performs useless conversions to the same type"
 +}
 +
 +#[derive(Default)]
 +pub struct UselessConversion {
 +    try_desugar_arm: Vec<HirId>,
 +}
 +
 +impl_lint_pass!(UselessConversion => [USELESS_CONVERSION]);
 +
 +#[allow(clippy::too_many_lines)]
 +impl<'tcx> LateLintPass<'tcx> for UselessConversion {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
 +        if e.span.from_expansion() {
 +            return;
 +        }
 +
 +        if Some(&e.hir_id) == self.try_desugar_arm.last() {
 +            return;
 +        }
 +
 +        match e.kind {
 +            ExprKind::Match(_, ref arms, MatchSource::TryDesugar) => {
 +                let e = match arms[0].body.kind {
 +                    ExprKind::Ret(Some(ref e)) | ExprKind::Break(_, Some(ref e)) => e,
 +                    _ => return,
 +                };
 +                if let ExprKind::Call(_, ref args) = e.kind {
 +                    self.try_desugar_arm.push(args[0].hir_id);
 +                }
 +            },
 +
 +            ExprKind::MethodCall(ref name, .., ref args, _) => {
 +                if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" {
 +                    let a = cx.typeck_results().expr_ty(e);
 +                    let b = cx.typeck_results().expr_ty(&args[0]);
 +                    if TyS::same_type(a, b) {
 +                        let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
 +                        span_lint_and_sugg(
 +                            cx,
 +                            USELESS_CONVERSION,
 +                            e.span,
 +                            "useless conversion to the same type",
 +                            "consider removing `.into()`",
 +                            sugg,
 +                            Applicability::MachineApplicable, // snippet
 +                        );
 +                    }
 +                }
 +                if match_trait_method(cx, e, &paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" {
++                    if let Some(parent_expr) = get_parent_expr(cx, e) {
++                        if let ExprKind::MethodCall(ref parent_name, ..) = parent_expr.kind {
++                            if &*parent_name.ident.as_str() != "into_iter" {
++                                return;
++                            }
++                        }
++                    }
 +                    let a = cx.typeck_results().expr_ty(e);
 +                    let b = cx.typeck_results().expr_ty(&args[0]);
 +                    if TyS::same_type(a, b) {
 +                        let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
 +                        span_lint_and_sugg(
 +                            cx,
 +                            USELESS_CONVERSION,
 +                            e.span,
 +                            "useless conversion to the same type",
 +                            "consider removing `.into_iter()`",
 +                            sugg,
 +                            Applicability::MachineApplicable, // snippet
 +                        );
 +                    }
 +                }
 +                if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && &*name.ident.as_str() == "try_into" {
 +                    if_chain! {
 +                        let a = cx.typeck_results().expr_ty(e);
 +                        let b = cx.typeck_results().expr_ty(&args[0]);
 +                        if is_type_diagnostic_item(cx, a, sym!(result_type));
 +                        if let ty::Adt(_, substs) = a.kind;
 +                        if let Some(a_type) = substs.types().next();
 +                        if TyS::same_type(a_type, b);
 +
 +                        then {
 +                            span_lint_and_help(
 +                                cx,
 +                                USELESS_CONVERSION,
 +                                e.span,
 +                                "useless conversion to the same type",
 +                                None,
 +                                "consider removing `.try_into()`",
 +                            );
 +                        }
 +                    }
 +                }
 +            },
 +
 +            ExprKind::Call(ref path, ref args) => {
 +                if_chain! {
 +                    if args.len() == 1;
 +                    if let ExprKind::Path(ref qpath) = path.kind;
 +                    if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
 +                    let a = cx.typeck_results().expr_ty(e);
 +                    let b = cx.typeck_results().expr_ty(&args[0]);
 +
 +                    then {
 +                        if_chain! {
 +                            if match_def_path(cx, def_id, &paths::TRY_FROM);
 +                            if is_type_diagnostic_item(cx, a, sym!(result_type));
 +                            if let ty::Adt(_, substs) = a.kind;
 +                            if let Some(a_type) = substs.types().next();
 +                            if TyS::same_type(a_type, b);
 +
 +                            then {
 +                                let hint = format!("consider removing `{}()`", snippet(cx, path.span, "TryFrom::try_from"));
 +                                span_lint_and_help(
 +                                    cx,
 +                                    USELESS_CONVERSION,
 +                                    e.span,
 +                                    "useless conversion to the same type",
 +                                    None,
 +                                    &hint,
 +                                );
 +                            }
 +                        }
 +
 +                        if_chain! {
 +                            if match_def_path(cx, def_id, &paths::FROM_FROM);
 +                            if TyS::same_type(a, b);
 +
 +                            then {
 +                                let sugg = snippet(cx, args[0].span.source_callsite(), "<expr>").into_owned();
 +                                let sugg_msg =
 +                                    format!("consider removing `{}()`", snippet(cx, path.span, "From::from"));
 +                                span_lint_and_sugg(
 +                                    cx,
 +                                    USELESS_CONVERSION,
 +                                    e.span,
 +                                    "useless conversion to the same type",
 +                                    &sugg_msg,
 +                                    sugg,
 +                                    Applicability::MachineApplicable, // snippet
 +                                );
 +                            }
 +                        }
 +                    }
 +                }
 +            },
 +
 +            _ => {},
 +        }
 +    }
 +
 +    fn check_expr_post(&mut self, _: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
 +        if Some(&e.hir_id) == self.try_desugar_arm.last() {
 +            self.try_desugar_arm.pop();
 +        }
 +    }
 +}
index 87cb454f654bcfb9a2a8ad70c4cceac6ccbd3253,0000000000000000000000000000000000000000..5e8800d38eb52e9ee82387d5a7071755800bea4e
mode 100644,000000..100644
--- /dev/null
@@@ -1,225 -1,0 +1,225 @@@
-     /// The character used as exponent seperator (b'e' or b'E') and the exponent part.
 +use rustc_ast::ast::{Lit, LitFloatType, LitIntType, LitKind};
 +
 +#[derive(Debug, PartialEq)]
 +pub enum Radix {
 +    Binary,
 +    Octal,
 +    Decimal,
 +    Hexadecimal,
 +}
 +
 +impl Radix {
 +    /// Returns a reasonable digit group size for this radix.
 +    #[must_use]
 +    fn suggest_grouping(&self) -> usize {
 +        match *self {
 +            Self::Binary | Self::Hexadecimal => 4,
 +            Self::Octal | Self::Decimal => 3,
 +        }
 +    }
 +}
 +
 +/// A helper method to format numeric literals with digit grouping.
 +/// `lit` must be a valid numeric literal without suffix.
 +pub fn format(lit: &str, type_suffix: Option<&str>, float: bool) -> String {
 +    NumericLiteral::new(lit, type_suffix, float).format()
 +}
 +
 +#[derive(Debug)]
 +pub struct NumericLiteral<'a> {
 +    /// Which radix the literal was represented in.
 +    pub radix: Radix,
 +    /// The radix prefix, if present.
 +    pub prefix: Option<&'a str>,
 +
 +    /// The integer part of the number.
 +    pub integer: &'a str,
 +    /// The fraction part of the number.
 +    pub fraction: Option<&'a str>,
++    /// The character used as exponent separator (b'e' or b'E') and the exponent part.
 +    pub exponent: Option<(char, &'a str)>,
 +
 +    /// The type suffix, including preceding underscore if present.
 +    pub suffix: Option<&'a str>,
 +}
 +
 +impl<'a> NumericLiteral<'a> {
 +    pub fn from_lit(src: &'a str, lit: &Lit) -> Option<NumericLiteral<'a>> {
 +        NumericLiteral::from_lit_kind(src, &lit.kind)
 +    }
 +
 +    pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option<NumericLiteral<'a>> {
 +        if lit_kind.is_numeric() && src.chars().next().map_or(false, |c| c.is_digit(10)) {
 +            let (unsuffixed, suffix) = split_suffix(&src, lit_kind);
 +            let float = matches!(lit_kind, LitKind::Float(..));
 +            Some(NumericLiteral::new(unsuffixed, suffix, float))
 +        } else {
 +            None
 +        }
 +    }
 +
 +    #[must_use]
 +    pub fn new(lit: &'a str, suffix: Option<&'a str>, float: bool) -> Self {
 +        // Determine delimiter for radix prefix, if present, and radix.
 +        let radix = if lit.starts_with("0x") {
 +            Radix::Hexadecimal
 +        } else if lit.starts_with("0b") {
 +            Radix::Binary
 +        } else if lit.starts_with("0o") {
 +            Radix::Octal
 +        } else {
 +            Radix::Decimal
 +        };
 +
 +        // Grab part of the literal after prefix, if present.
 +        let (prefix, mut sans_prefix) = if let Radix::Decimal = radix {
 +            (None, lit)
 +        } else {
 +            let (p, s) = lit.split_at(2);
 +            (Some(p), s)
 +        };
 +
 +        if suffix.is_some() && sans_prefix.ends_with('_') {
 +            // The '_' before the suffix isn't part of the digits
 +            sans_prefix = &sans_prefix[..sans_prefix.len() - 1];
 +        }
 +
 +        let (integer, fraction, exponent) = Self::split_digit_parts(sans_prefix, float);
 +
 +        Self {
 +            radix,
 +            prefix,
 +            integer,
 +            fraction,
 +            exponent,
 +            suffix,
 +        }
 +    }
 +
 +    pub fn is_decimal(&self) -> bool {
 +        self.radix == Radix::Decimal
 +    }
 +
 +    pub fn split_digit_parts(digits: &str, float: bool) -> (&str, Option<&str>, Option<(char, &str)>) {
 +        let mut integer = digits;
 +        let mut fraction = None;
 +        let mut exponent = None;
 +
 +        if float {
 +            for (i, c) in digits.char_indices() {
 +                match c {
 +                    '.' => {
 +                        integer = &digits[..i];
 +                        fraction = Some(&digits[i + 1..]);
 +                    },
 +                    'e' | 'E' => {
 +                        if integer.len() > i {
 +                            integer = &digits[..i];
 +                        } else {
 +                            fraction = Some(&digits[integer.len() + 1..i]);
 +                        };
 +                        exponent = Some((c, &digits[i + 1..]));
 +                        break;
 +                    },
 +                    _ => {},
 +                }
 +            }
 +        }
 +
 +        (integer, fraction, exponent)
 +    }
 +
 +    /// Returns literal formatted in a sensible way.
 +    pub fn format(&self) -> String {
 +        let mut output = String::new();
 +
 +        if let Some(prefix) = self.prefix {
 +            output.push_str(prefix);
 +        }
 +
 +        let group_size = self.radix.suggest_grouping();
 +
 +        Self::group_digits(
 +            &mut output,
 +            self.integer,
 +            group_size,
 +            true,
 +            self.radix == Radix::Hexadecimal,
 +        );
 +
 +        if let Some(fraction) = self.fraction {
 +            output.push('.');
 +            Self::group_digits(&mut output, fraction, group_size, false, false);
 +        }
 +
 +        if let Some((separator, exponent)) = self.exponent {
 +            output.push(separator);
 +            Self::group_digits(&mut output, exponent, group_size, true, false);
 +        }
 +
 +        if let Some(suffix) = self.suffix {
 +            output.push('_');
 +            output.push_str(suffix);
 +        }
 +
 +        output
 +    }
 +
 +    pub fn group_digits(output: &mut String, input: &str, group_size: usize, partial_group_first: bool, pad: bool) {
 +        debug_assert!(group_size > 0);
 +
 +        let mut digits = input.chars().filter(|&c| c != '_');
 +
 +        let first_group_size;
 +
 +        if partial_group_first {
 +            first_group_size = (digits.clone().count() - 1) % group_size + 1;
 +            if pad {
 +                for _ in 0..group_size - first_group_size {
 +                    output.push('0');
 +                }
 +            }
 +        } else {
 +            first_group_size = group_size;
 +        }
 +
 +        for _ in 0..first_group_size {
 +            if let Some(digit) = digits.next() {
 +                output.push(digit);
 +            }
 +        }
 +
 +        for (c, i) in digits.zip((0..group_size).cycle()) {
 +            if i == 0 {
 +                output.push('_');
 +            }
 +            output.push(c);
 +        }
 +    }
 +}
 +
 +fn split_suffix<'a>(src: &'a str, lit_kind: &LitKind) -> (&'a str, Option<&'a str>) {
 +    debug_assert!(lit_kind.is_numeric());
 +    lit_suffix_length(lit_kind).map_or((src, None), |suffix_length| {
 +        let (unsuffixed, suffix) = src.split_at(src.len() - suffix_length);
 +        (unsuffixed, Some(suffix))
 +    })
 +}
 +
 +fn lit_suffix_length(lit_kind: &LitKind) -> Option<usize> {
 +    debug_assert!(lit_kind.is_numeric());
 +    let suffix = match lit_kind {
 +        LitKind::Int(_, int_lit_kind) => match int_lit_kind {
 +            LitIntType::Signed(int_ty) => Some(int_ty.name_str()),
 +            LitIntType::Unsigned(uint_ty) => Some(uint_ty.name_str()),
 +            LitIntType::Unsuffixed => None,
 +        },
 +        LitKind::Float(_, float_lit_kind) => match float_lit_kind {
 +            LitFloatType::Suffixed(float_ty) => Some(float_ty.name_str()),
 +            LitFloatType::Unsuffixed => None,
 +        },
 +        _ => None,
 +    };
 +
 +    suffix.map(str::len)
 +}
index 4c3462802e9218535b8343bc10b1946a3c3adb87,0000000000000000000000000000000000000000..a515ee29c82adc64e2678302137a26ac40254157
mode 100644,000000..100644
--- /dev/null
@@@ -1,142 -1,0 +1,143 @@@
 +//! This module contains paths to types and functions Clippy needs to know
 +//! about.
 +//!
 +//! Whenever possible, please consider diagnostic items over hardcoded paths.
 +//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
 +
 +pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
 +pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
 +pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
 +pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
 +pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
 +pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
 +pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
 +pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
 +pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"];
 +pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
 +pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"];
 +pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
 +pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"];
 +pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
 +pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
 +pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
 +pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
 +pub const CSTRING: [&str; 4] = ["std", "ffi", "c_str", "CString"];
 +pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
 +pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
 +pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
 +pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
 +pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
 +pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"];
 +pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"];
 +pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"];
 +pub const DROP: [&str; 3] = ["core", "mem", "drop"];
 +pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"];
 +pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
 +pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
 +pub const EXIT: [&str; 3] = ["std", "process", "exit"];
 +pub const FILE: [&str; 3] = ["std", "fs", "File"];
 +pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"];
 +pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
 +pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
 +pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
 +pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
 +pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
 +pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
 +pub const HASH: [&str; 2] = ["hash", "Hash"];
 +pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
 +pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
 +pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
 +pub const INDEX: [&str; 3] = ["core", "ops", "Index"];
 +pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"];
 +pub const INTO: [&str; 3] = ["core", "convert", "Into"];
 +pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
 +pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
 +pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
 +pub const ITERATOR: [&str; 5] = ["core", "iter", "traits", "iterator", "Iterator"];
 +pub const LATE_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "LateContext"];
 +pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
 +pub const LINT: [&str; 3] = ["rustc_session", "lint", "Lint"];
 +pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
 +pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
++pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
 +pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
 +pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
 +pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
 +pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
 +pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
 +pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
 +pub const OPTION: [&str; 3] = ["core", "option", "Option"];
 +pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"];
 +pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
 +pub const ORD: [&str; 3] = ["core", "cmp", "Ord"];
 +pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"];
 +pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
 +pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
 +pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"];
 +pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"];
 +pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"];
 +pub const PATH: [&str; 3] = ["std", "path", "Path"];
 +pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"];
 +pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
 +pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
 +pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
 +pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
 +pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
 +pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
 +pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
 +pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
 +pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
 +pub const RANGE_FULL: [&str; 4] = ["core", "ops", "range", "RangeFull"];
 +pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"];
 +pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"];
 +pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"];
 +pub const RANGE_STD: [&str; 3] = ["std", "ops", "Range"];
 +pub const RANGE_TO: [&str; 3] = ["core", "ops", "RangeTo"];
 +pub const RANGE_TO_INCLUSIVE: [&str; 3] = ["core", "ops", "RangeToInclusive"];
 +pub const RANGE_TO_INCLUSIVE_STD: [&str; 3] = ["std", "ops", "RangeToInclusive"];
 +pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"];
 +pub const RC: [&str; 3] = ["alloc", "rc", "Rc"];
 +pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"];
 +pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"];
 +pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];
 +pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"];
 +pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
 +pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
 +pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
 +pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
 +pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
 +pub const RESULT: [&str; 3] = ["core", "result", "Result"];
 +pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
 +pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
 +pub const RWLOCK_READ_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockReadGuard"];
 +pub const RWLOCK_WRITE_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockWriteGuard"];
 +pub const SERDE_DESERIALIZE: [&str; 2] = ["_serde", "Deserialize"];
 +pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
 +pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
 +pub const SLICE_ITER: [&str; 3] = ["core", "slice", "Iter"];
 +pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
 +pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
 +pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
 +pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
 +pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
 +pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
 +pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
 +pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
 +pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"];
 +pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
 +pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"];
 +pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
 +pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
 +pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
 +pub const TRY_FROM_ERROR: [&str; 4] = ["std", "ops", "Try", "from_error"];
 +pub const TRY_INTO_RESULT: [&str; 4] = ["std", "ops", "Try", "into_result"];
 +pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"];
 +pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
 +pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
 +pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
 +pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
 +pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
 +pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
 +pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
 +pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
 +pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
index ad73a1ea1acdfeda18cc022307729c2fc16ad470,0000000000000000000000000000000000000000..58e7c354b27da1e2ab90ec3d74f3028fe891008c
mode 100644,000000..100644
--- /dev/null
@@@ -1,59 -1,0 +1,59 @@@
-     /// **What it does:** Finds occurences of `Vec::resize(0, an_int)`
 +use crate::utils::span_lint_and_then;
 +use if_chain::if_chain;
 +use rustc_errors::Applicability;
 +use rustc_hir::{Expr, ExprKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Spanned;
 +
 +use crate::utils::{match_def_path, paths};
 +use rustc_ast::ast::LitKind;
 +use rustc_hir as hir;
 +
 +declare_clippy_lint! {
++    /// **What it does:** Finds occurrences of `Vec::resize(0, an_int)`
 +    ///
 +    /// **Why is this bad?** This is probably an argument inversion mistake.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// vec!(1, 2, 3, 4, 5).resize(0, 5)
 +    /// ```
 +    pub VEC_RESIZE_TO_ZERO,
 +    correctness,
 +    "emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake"
 +}
 +
 +declare_lint_pass!(VecResizeToZero => [VEC_RESIZE_TO_ZERO]);
 +
 +impl<'tcx> LateLintPass<'tcx> for VecResizeToZero {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if_chain! {
 +            if let hir::ExprKind::MethodCall(path_segment, _, ref args, _) = expr.kind;
 +            if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
 +            if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3;
 +            if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind;
 +            if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind;
 +            then {
 +                let method_call_span = expr.span.with_lo(path_segment.ident.span.lo());
 +                span_lint_and_then(
 +                    cx,
 +                    VEC_RESIZE_TO_ZERO,
 +                    expr.span,
 +                    "emptying a vector with `resize`",
 +                    |db| {
 +                        db.help("the arguments may be inverted...");
 +                        db.span_suggestion(
 +                            method_call_span,
 +                            "...or you can empty the vector with",
 +                            "clear()".to_string(),
 +                            Applicability::MaybeIncorrect,
 +                        );
 +                    },
 +                );
 +            }
 +        }
 +    }
 +}
index b89a87128626bc927db31c27665d220c452c52fd,0000000000000000000000000000000000000000..1879aae77fb650783301cd1bc8500cca8551bdb7
mode 100644,000000..100644
--- /dev/null
@@@ -1,2675 -1,0 +1,2682 @@@
-         module: "misc_early",
 +//! This file is managed by `cargo dev update_lints`. Do not edit.
 +
 +use lazy_static::lazy_static;
 +
 +pub mod lint;
 +pub use lint::Level;
 +pub use lint::Lint;
 +pub use lint::LINT_LEVELS;
 +
 +lazy_static! {
 +// begin lint list, do not remove this comment, it’s used in `update_lints`
 +pub static ref ALL_LINTS: Vec<Lint> = vec![
 +    Lint {
 +        name: "absurd_extreme_comparisons",
 +        group: "correctness",
 +        desc: "a comparison with a maximum or minimum value that is always true or false",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "almost_swapped",
 +        group: "correctness",
 +        desc: "`foo = bar; bar = foo` sequence",
 +        deprecation: None,
 +        module: "swap",
 +    },
 +    Lint {
 +        name: "approx_constant",
 +        group: "correctness",
 +        desc: "the approximate of a known float constant (in `std::fXX::consts`)",
 +        deprecation: None,
 +        module: "approx_const",
 +    },
 +    Lint {
 +        name: "as_conversions",
 +        group: "restriction",
 +        desc: "using a potentially dangerous silent `as` conversion",
 +        deprecation: None,
 +        module: "as_conversions",
 +    },
 +    Lint {
 +        name: "assertions_on_constants",
 +        group: "style",
 +        desc: "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`",
 +        deprecation: None,
 +        module: "assertions_on_constants",
 +    },
 +    Lint {
 +        name: "assign_op_pattern",
 +        group: "style",
 +        desc: "assigning the result of an operation on a variable to that same variable",
 +        deprecation: None,
 +        module: "assign_ops",
 +    },
 +    Lint {
 +        name: "await_holding_lock",
 +        group: "pedantic",
 +        desc: "Inside an async function, holding a MutexGuard while calling await",
 +        deprecation: None,
 +        module: "await_holding_lock",
 +    },
 +    Lint {
 +        name: "bad_bit_mask",
 +        group: "correctness",
 +        desc: "expressions of the form `_ & mask == select` that will only ever return `true` or `false`",
 +        deprecation: None,
 +        module: "bit_mask",
 +    },
 +    Lint {
 +        name: "bind_instead_of_map",
 +        group: "complexity",
 +        desc: "using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "blacklisted_name",
 +        group: "style",
 +        desc: "usage of a blacklisted/placeholder name",
 +        deprecation: None,
 +        module: "blacklisted_name",
 +    },
 +    Lint {
 +        name: "blanket_clippy_restriction_lints",
 +        group: "style",
 +        desc: "enabling the complete restriction group",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "blocks_in_if_conditions",
 +        group: "style",
 +        desc: "useless or complex blocks that can be eliminated in conditions",
 +        deprecation: None,
 +        module: "blocks_in_if_conditions",
 +    },
 +    Lint {
 +        name: "bool_comparison",
 +        group: "complexity",
 +        desc: "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`",
 +        deprecation: None,
 +        module: "needless_bool",
 +    },
 +    Lint {
 +        name: "borrow_interior_mutable_const",
 +        group: "correctness",
 +        desc: "referencing `const` with interior mutability",
 +        deprecation: None,
 +        module: "non_copy_const",
 +    },
 +    Lint {
 +        name: "borrowed_box",
 +        group: "complexity",
 +        desc: "a borrow of a boxed type",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "box_vec",
 +        group: "perf",
 +        desc: "usage of `Box<Vec<T>>`, vector elements are already on the heap",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "boxed_local",
 +        group: "perf",
 +        desc: "using `Box<T>` where unnecessary",
 +        deprecation: None,
 +        module: "escape",
 +    },
 +    Lint {
 +        name: "builtin_type_shadow",
 +        group: "style",
 +        desc: "shadowing a builtin type",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "cargo_common_metadata",
 +        group: "cargo",
 +        desc: "common metadata is defined in `Cargo.toml`",
 +        deprecation: None,
 +        module: "cargo_common_metadata",
 +    },
 +    Lint {
 +        name: "cast_lossless",
 +        group: "pedantic",
 +        desc: "casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_possible_truncation",
 +        group: "pedantic",
 +        desc: "casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_possible_wrap",
 +        group: "pedantic",
 +        desc: "casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_precision_loss",
 +        group: "pedantic",
 +        desc: "casts that cause loss of precision, e.g., `x as f32` where `x: u64`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_ptr_alignment",
 +        group: "pedantic",
 +        desc: "cast from a pointer to a more-strictly-aligned pointer",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_ref_to_mut",
 +        group: "correctness",
 +        desc: "a cast of reference to a mutable pointer",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "cast_sign_loss",
 +        group: "pedantic",
 +        desc: "casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "char_lit_as_u8",
 +        group: "complexity",
 +        desc: "casting a character literal to `u8` truncates",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "chars_last_cmp",
 +        group: "style",
 +        desc: "using `.chars().last()` or `.chars().next_back()` to check if a string ends with a char",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "chars_next_cmp",
 +        group: "style",
 +        desc: "using `.chars().next()` to check if a string starts with a char",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "checked_conversions",
 +        group: "pedantic",
 +        desc: "`try_from` could replace manual bounds checking when casting",
 +        deprecation: None,
 +        module: "checked_conversions",
 +    },
 +    Lint {
 +        name: "clone_double_ref",
 +        group: "correctness",
 +        desc: "using `clone` on `&&T`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "clone_on_copy",
 +        group: "complexity",
 +        desc: "using `clone` on a `Copy` type",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "clone_on_ref_ptr",
 +        group: "restriction",
 +        desc: "using \'clone\' on a ref-counted pointer",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "cmp_nan",
 +        group: "correctness",
 +        desc: "comparisons to `NAN`, which will always return false, probably not intended",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "cmp_null",
 +        group: "style",
 +        desc: "comparing a pointer to a null pointer, suggesting to use `.is_null()` instead.",
 +        deprecation: None,
 +        module: "ptr",
 +    },
 +    Lint {
 +        name: "cmp_owned",
 +        group: "perf",
 +        desc: "creating owned instances for comparing with others, e.g., `x == \"foo\".to_string()`",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "cognitive_complexity",
 +        group: "nursery",
 +        desc: "functions that should be split up into multiple functions",
 +        deprecation: None,
 +        module: "cognitive_complexity",
 +    },
 +    Lint {
 +        name: "collapsible_if",
 +        group: "style",
 +        desc: "`if`s that can be collapsed (e.g., `if x { if y { ... } }` and `else { if x { ... } }`)",
 +        deprecation: None,
 +        module: "collapsible_if",
 +    },
 +    Lint {
 +        name: "comparison_chain",
 +        group: "style",
 +        desc: "`if`s that can be rewritten with `match` and `cmp`",
 +        deprecation: None,
 +        module: "comparison_chain",
 +    },
 +    Lint {
 +        name: "copy_iterator",
 +        group: "pedantic",
 +        desc: "implementing `Iterator` on a `Copy` type",
 +        deprecation: None,
 +        module: "copy_iterator",
 +    },
 +    Lint {
 +        name: "crosspointer_transmute",
 +        group: "complexity",
 +        desc: "transmutes that have to or from types that are a pointer to the other",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "dbg_macro",
 +        group: "restriction",
 +        desc: "`dbg!` macro is intended as a debugging tool",
 +        deprecation: None,
 +        module: "dbg_macro",
 +    },
 +    Lint {
 +        name: "debug_assert_with_mut_call",
 +        group: "nursery",
 +        desc: "mutable arguments in `debug_assert{,_ne,_eq}!`",
 +        deprecation: None,
 +        module: "mutable_debug_assertion",
 +    },
 +    Lint {
 +        name: "decimal_literal_representation",
 +        group: "restriction",
 +        desc: "using decimal representation when hexadecimal would be better",
 +        deprecation: None,
 +        module: "literal_representation",
 +    },
 +    Lint {
 +        name: "declare_interior_mutable_const",
 +        group: "correctness",
 +        desc: "declaring `const` with interior mutability",
 +        deprecation: None,
 +        module: "non_copy_const",
 +    },
 +    Lint {
 +        name: "default_trait_access",
 +        group: "pedantic",
 +        desc: "checks for literal calls to `Default::default()`",
 +        deprecation: None,
 +        module: "default_trait_access",
 +    },
 +    Lint {
 +        name: "deprecated_cfg_attr",
 +        group: "complexity",
 +        desc: "usage of `cfg_attr(rustfmt)` instead of tool attributes",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "deprecated_semver",
 +        group: "correctness",
 +        desc: "use of `#[deprecated(since = \"x\")]` where x is not semver",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "deref_addrof",
 +        group: "complexity",
 +        desc: "use of `*&` or `*&mut` in an expression",
 +        deprecation: None,
 +        module: "reference",
 +    },
 +    Lint {
 +        name: "derive_hash_xor_eq",
 +        group: "correctness",
 +        desc: "deriving `Hash` but implementing `PartialEq` explicitly",
 +        deprecation: None,
 +        module: "derive",
 +    },
 +    Lint {
 +        name: "diverging_sub_expression",
 +        group: "complexity",
 +        desc: "whether an expression contains a diverging sub expression",
 +        deprecation: None,
 +        module: "eval_order_dependence",
 +    },
 +    Lint {
 +        name: "doc_markdown",
 +        group: "pedantic",
 +        desc: "presence of `_`, `::` or camel-case outside backticks in documentation",
 +        deprecation: None,
 +        module: "doc",
 +    },
 +    Lint {
 +        name: "double_comparisons",
 +        group: "complexity",
 +        desc: "unnecessary double comparisons that can be simplified",
 +        deprecation: None,
 +        module: "double_comparison",
 +    },
 +    Lint {
 +        name: "double_must_use",
 +        group: "style",
 +        desc: "`#[must_use]` attribute on a `#[must_use]`-returning function / method",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "double_neg",
 +        group: "style",
 +        desc: "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "double_parens",
 +        group: "complexity",
 +        desc: "Warn on unnecessary double parentheses",
 +        deprecation: None,
 +        module: "double_parens",
 +    },
 +    Lint {
 +        name: "drop_bounds",
 +        group: "correctness",
 +        desc: "Bounds of the form `T: Drop` are useless",
 +        deprecation: None,
 +        module: "drop_bounds",
 +    },
 +    Lint {
 +        name: "drop_copy",
 +        group: "correctness",
 +        desc: "calls to `std::mem::drop` with a value that implements Copy",
 +        deprecation: None,
 +        module: "drop_forget_ref",
 +    },
 +    Lint {
 +        name: "drop_ref",
 +        group: "correctness",
 +        desc: "calls to `std::mem::drop` with a reference instead of an owned value",
 +        deprecation: None,
 +        module: "drop_forget_ref",
 +    },
 +    Lint {
 +        name: "duplicate_underscore_argument",
 +        group: "style",
 +        desc: "function arguments having names which only differ by an underscore",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "duration_subsec",
 +        group: "complexity",
 +        desc: "checks for calculation of subsecond microseconds or milliseconds",
 +        deprecation: None,
 +        module: "duration_subsec",
 +    },
 +    Lint {
 +        name: "else_if_without_else",
 +        group: "restriction",
 +        desc: "`if` expression with an `else if`, but without a final `else` branch",
 +        deprecation: None,
 +        module: "else_if_without_else",
 +    },
 +    Lint {
 +        name: "empty_enum",
 +        group: "pedantic",
 +        desc: "enum with no variants",
 +        deprecation: None,
 +        module: "empty_enum",
 +    },
 +    Lint {
 +        name: "empty_line_after_outer_attr",
 +        group: "nursery",
 +        desc: "empty line after outer attribute",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "empty_loop",
 +        group: "style",
 +        desc: "empty `loop {}`, which should block or sleep",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "enum_clike_unportable_variant",
 +        group: "correctness",
 +        desc: "C-like enums that are `repr(isize/usize)` and have values that don\'t fit into an `i32`",
 +        deprecation: None,
 +        module: "enum_clike",
 +    },
 +    Lint {
 +        name: "enum_glob_use",
 +        group: "pedantic",
 +        desc: "use items that import all variants of an enum",
 +        deprecation: None,
 +        module: "wildcard_imports",
 +    },
 +    Lint {
 +        name: "enum_variant_names",
 +        group: "style",
 +        desc: "enums where all variants share a prefix/postfix",
 +        deprecation: None,
 +        module: "enum_variants",
 +    },
 +    Lint {
 +        name: "eq_op",
 +        group: "correctness",
 +        desc: "equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)",
 +        deprecation: None,
 +        module: "eq_op",
 +    },
 +    Lint {
 +        name: "erasing_op",
 +        group: "correctness",
 +        desc: "using erasing operations, e.g., `x * 0` or `y & 0`",
 +        deprecation: None,
 +        module: "erasing_op",
 +    },
 +    Lint {
 +        name: "eval_order_dependence",
 +        group: "complexity",
 +        desc: "whether a variable read occurs before a write depends on sub-expression evaluation order",
 +        deprecation: None,
 +        module: "eval_order_dependence",
 +    },
 +    Lint {
 +        name: "excessive_precision",
 +        group: "style",
 +        desc: "excessive precision for float literal",
 +        deprecation: None,
 +        module: "float_literal",
 +    },
 +    Lint {
 +        name: "exit",
 +        group: "restriction",
 +        desc: "`std::process::exit` is called, terminating the program",
 +        deprecation: None,
 +        module: "exit",
 +    },
 +    Lint {
 +        name: "expect_fun_call",
 +        group: "perf",
 +        desc: "using any `expect` method with a function call",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "expect_used",
 +        group: "restriction",
 +        desc: "using `.expect()` on `Result` or `Option`, which might be better handled",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "expl_impl_clone_on_copy",
 +        group: "pedantic",
 +        desc: "implementing `Clone` explicitly on `Copy` types",
 +        deprecation: None,
 +        module: "derive",
 +    },
 +    Lint {
 +        name: "explicit_counter_loop",
 +        group: "complexity",
 +        desc: "for-looping with an explicit counter when `_.enumerate()` would do",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "explicit_deref_methods",
 +        group: "pedantic",
 +        desc: "Explicit use of deref or deref_mut method while not in a method chain.",
 +        deprecation: None,
 +        module: "dereference",
 +    },
 +    Lint {
 +        name: "explicit_into_iter_loop",
 +        group: "pedantic",
 +        desc: "for-looping over `_.into_iter()` when `_` would do",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "explicit_iter_loop",
 +        group: "pedantic",
 +        desc: "for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "explicit_write",
 +        group: "complexity",
 +        desc: "using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work",
 +        deprecation: None,
 +        module: "explicit_write",
 +    },
 +    Lint {
 +        name: "extra_unused_lifetimes",
 +        group: "complexity",
 +        desc: "unused lifetimes in function definitions",
 +        deprecation: None,
 +        module: "lifetimes",
 +    },
 +    Lint {
 +        name: "fallible_impl_from",
 +        group: "nursery",
 +        desc: "Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`",
 +        deprecation: None,
 +        module: "fallible_impl_from",
 +    },
 +    Lint {
 +        name: "filetype_is_file",
 +        group: "restriction",
 +        desc: "`FileType::is_file` is not recommended to test for readable file type",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "filter_map",
 +        group: "pedantic",
 +        desc: "using combinations of `filter`, `map`, `filter_map` and `flat_map` which can usually be written as a single method call",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "filter_map_next",
 +        group: "pedantic",
 +        desc: "using combination of `filter_map` and `next` which can usually be written as a single method call",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "filter_next",
 +        group: "complexity",
 +        desc: "using `filter(p).next()`, which is more succinctly expressed as `.find(p)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "find_map",
 +        group: "pedantic",
 +        desc: "using a combination of `find` and `map` can usually be written as a single method call",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "flat_map_identity",
 +        group: "complexity",
 +        desc: "call to `flat_map` where `flatten` is sufficient",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "float_arithmetic",
 +        group: "restriction",
 +        desc: "any floating-point arithmetic statement",
 +        deprecation: None,
 +        module: "arithmetic",
 +    },
 +    Lint {
 +        name: "float_cmp",
 +        group: "correctness",
 +        desc: "using `==` or `!=` on float values instead of comparing difference with an epsilon",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "float_cmp_const",
 +        group: "restriction",
 +        desc: "using `==` or `!=` on float constants instead of comparing difference with an epsilon",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "fn_address_comparisons",
 +        group: "correctness",
 +        desc: "comparison with an address of a function item",
 +        deprecation: None,
 +        module: "unnamed_address",
 +    },
 +    Lint {
 +        name: "fn_params_excessive_bools",
 +        group: "pedantic",
 +        desc: "using too many bools in function parameters",
 +        deprecation: None,
 +        module: "excessive_bools",
 +    },
 +    Lint {
 +        name: "fn_to_numeric_cast",
 +        group: "style",
 +        desc: "casting a function pointer to a numeric type other than usize",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "fn_to_numeric_cast_with_truncation",
 +        group: "style",
 +        desc: "casting a function pointer to a numeric type not wide enough to store the address",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "for_kv_map",
 +        group: "style",
 +        desc: "looping on a map using `iter` when `keys` or `values` would do",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "for_loops_over_fallibles",
 +        group: "correctness",
 +        desc: "for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "forget_copy",
 +        group: "correctness",
 +        desc: "calls to `std::mem::forget` with a value that implements Copy",
 +        deprecation: None,
 +        module: "drop_forget_ref",
 +    },
 +    Lint {
 +        name: "forget_ref",
 +        group: "correctness",
 +        desc: "calls to `std::mem::forget` with a reference instead of an owned value",
 +        deprecation: None,
 +        module: "drop_forget_ref",
 +    },
 +    Lint {
 +        name: "future_not_send",
 +        group: "nursery",
 +        desc: "public Futures must be Send",
 +        deprecation: None,
 +        module: "future_not_send",
 +    },
 +    Lint {
 +        name: "get_last_with_len",
 +        group: "complexity",
 +        desc: "Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler",
 +        deprecation: None,
 +        module: "get_last_with_len",
 +    },
 +    Lint {
 +        name: "get_unwrap",
 +        group: "restriction",
 +        desc: "using `.get().unwrap()` or `.get_mut().unwrap()` when using `[]` would work instead",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "identity_op",
 +        group: "complexity",
 +        desc: "using identity operations, e.g., `x + 0` or `y / 1`",
 +        deprecation: None,
 +        module: "identity_op",
 +    },
 +    Lint {
 +        name: "if_let_mutex",
 +        group: "correctness",
 +        desc: "locking a `Mutex` in an `if let` block can cause deadlocks",
 +        deprecation: None,
 +        module: "if_let_mutex",
 +    },
 +    Lint {
 +        name: "if_let_some_result",
 +        group: "style",
 +        desc: "usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead",
 +        deprecation: None,
 +        module: "if_let_some_result",
 +    },
 +    Lint {
 +        name: "if_not_else",
 +        group: "pedantic",
 +        desc: "`if` branches that could be swapped so no negation operation is necessary on the condition",
 +        deprecation: None,
 +        module: "if_not_else",
 +    },
 +    Lint {
 +        name: "if_same_then_else",
 +        group: "correctness",
 +        desc: "`if` with the same `then` and `else` blocks",
 +        deprecation: None,
 +        module: "copies",
 +    },
 +    Lint {
 +        name: "ifs_same_cond",
 +        group: "correctness",
 +        desc: "consecutive `if`s with the same condition",
 +        deprecation: None,
 +        module: "copies",
 +    },
 +    Lint {
 +        name: "implicit_hasher",
 +        group: "pedantic",
 +        desc: "missing generalization over different hashers",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "implicit_return",
 +        group: "restriction",
 +        desc: "use a return statement like `return expr` instead of an expression",
 +        deprecation: None,
 +        module: "implicit_return",
 +    },
 +    Lint {
 +        name: "implicit_saturating_sub",
 +        group: "pedantic",
 +        desc: "Perform saturating subtraction instead of implicitly checking lower bound of data type",
 +        deprecation: None,
 +        module: "implicit_saturating_sub",
 +    },
 +    Lint {
 +        name: "imprecise_flops",
 +        group: "nursery",
 +        desc: "usage of imprecise floating point operations",
 +        deprecation: None,
 +        module: "floating_point_arithmetic",
 +    },
 +    Lint {
 +        name: "inconsistent_digit_grouping",
 +        group: "style",
 +        desc: "integer literals with digits grouped inconsistently",
 +        deprecation: None,
 +        module: "literal_representation",
 +    },
 +    Lint {
 +        name: "indexing_slicing",
 +        group: "restriction",
 +        desc: "indexing/slicing usage",
 +        deprecation: None,
 +        module: "indexing_slicing",
 +    },
 +    Lint {
 +        name: "ineffective_bit_mask",
 +        group: "correctness",
 +        desc: "expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`",
 +        deprecation: None,
 +        module: "bit_mask",
 +    },
 +    Lint {
 +        name: "inefficient_to_string",
 +        group: "pedantic",
 +        desc: "using `to_string` on `&&T` where `T: ToString`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "infallible_destructuring_match",
 +        group: "style",
 +        desc: "a `match` statement with a single infallible arm instead of a `let`",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "infinite_iter",
 +        group: "correctness",
 +        desc: "infinite iteration",
 +        deprecation: None,
 +        module: "infinite_iter",
 +    },
 +    Lint {
 +        name: "inherent_to_string",
 +        group: "style",
 +        desc: "type implements inherent method `to_string()`, but should instead implement the `Display` trait",
 +        deprecation: None,
 +        module: "inherent_to_string",
 +    },
 +    Lint {
 +        name: "inherent_to_string_shadow_display",
 +        group: "correctness",
 +        desc: "type implements inherent method `to_string()`, which gets shadowed by the implementation of the `Display` trait",
 +        deprecation: None,
 +        module: "inherent_to_string",
 +    },
 +    Lint {
 +        name: "inline_always",
 +        group: "pedantic",
 +        desc: "use of `#[inline(always)]`",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "inline_fn_without_body",
 +        group: "correctness",
 +        desc: "use of `#[inline]` on trait methods without bodies",
 +        deprecation: None,
 +        module: "inline_fn_without_body",
 +    },
 +    Lint {
 +        name: "int_plus_one",
 +        group: "complexity",
 +        desc: "instead of using `x >= y + 1`, use `x > y`",
 +        deprecation: None,
 +        module: "int_plus_one",
 +    },
 +    Lint {
 +        name: "integer_arithmetic",
 +        group: "restriction",
 +        desc: "any integer arithmetic expression which could overflow or panic",
 +        deprecation: None,
 +        module: "arithmetic",
 +    },
 +    Lint {
 +        name: "integer_division",
 +        group: "restriction",
 +        desc: "integer division may cause loss of precision",
 +        deprecation: None,
 +        module: "integer_division",
 +    },
 +    Lint {
 +        name: "into_iter_on_ref",
 +        group: "style",
 +        desc: "using `.into_iter()` on a reference",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "invalid_atomic_ordering",
 +        group: "correctness",
 +        desc: "usage of invalid atomic ordering in atomic loads/stores and memory fences",
 +        deprecation: None,
 +        module: "atomic_ordering",
 +    },
 +    Lint {
 +        name: "invalid_regex",
 +        group: "correctness",
 +        desc: "invalid regular expressions",
 +        deprecation: None,
 +        module: "regex",
 +    },
 +    Lint {
 +        name: "invalid_upcast_comparisons",
 +        group: "pedantic",
 +        desc: "a comparison involving an upcast which is always true or false",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "items_after_statements",
 +        group: "pedantic",
 +        desc: "blocks where an item comes after a statement",
 +        deprecation: None,
 +        module: "items_after_statements",
 +    },
 +    Lint {
 +        name: "iter_cloned_collect",
 +        group: "style",
 +        desc: "using `.cloned().collect()` on slice to create a `Vec`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "iter_next_loop",
 +        group: "correctness",
 +        desc: "for-looping over `_.next()` which is probably not intended",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "iter_next_slice",
 +        group: "style",
 +        desc: "using `.iter().next()` on a sliced array, which can be shortened to just `.get()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "iter_nth",
 +        group: "perf",
 +        desc: "using `.iter().nth()` on a standard library type with O(1) element access",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "iter_nth_zero",
 +        group: "style",
 +        desc: "replace `iter.nth(0)` with `iter.next()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "iter_skip_next",
 +        group: "style",
 +        desc: "using `.skip(x).next()` on an iterator",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "iterator_step_by_zero",
 +        group: "correctness",
 +        desc: "using `Iterator::step_by(0)`, which will panic at runtime",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "just_underscores_and_digits",
 +        group: "style",
 +        desc: "unclear name",
 +        deprecation: None,
 +        module: "non_expressive_names",
 +    },
 +    Lint {
 +        name: "large_const_arrays",
 +        group: "perf",
 +        desc: "large non-scalar const array may cause performance overhead",
 +        deprecation: None,
 +        module: "large_const_arrays",
 +    },
 +    Lint {
 +        name: "large_digit_groups",
 +        group: "pedantic",
 +        desc: "grouping digits into groups that are too large",
 +        deprecation: None,
 +        module: "literal_representation",
 +    },
 +    Lint {
 +        name: "large_enum_variant",
 +        group: "perf",
 +        desc: "large size difference between variants on an enum",
 +        deprecation: None,
 +        module: "large_enum_variant",
 +    },
 +    Lint {
 +        name: "large_stack_arrays",
 +        group: "pedantic",
 +        desc: "allocating large arrays on stack may cause stack overflow",
 +        deprecation: None,
 +        module: "large_stack_arrays",
 +    },
 +    Lint {
 +        name: "len_without_is_empty",
 +        group: "style",
 +        desc: "traits or impls with a public `len` method but no corresponding `is_empty` method",
 +        deprecation: None,
 +        module: "len_zero",
 +    },
 +    Lint {
 +        name: "len_zero",
 +        group: "style",
 +        desc: "checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead",
 +        deprecation: None,
 +        module: "len_zero",
 +    },
 +    Lint {
 +        name: "let_and_return",
 +        group: "style",
 +        desc: "creating a let-binding and then immediately returning it like `let x = expr; x` at the end of a block",
 +        deprecation: None,
 +        module: "let_and_return",
 +    },
 +    Lint {
 +        name: "let_underscore_lock",
 +        group: "correctness",
 +        desc: "non-binding let on a synchronization lock",
 +        deprecation: None,
 +        module: "let_underscore",
 +    },
 +    Lint {
 +        name: "let_underscore_must_use",
 +        group: "restriction",
 +        desc: "non-binding let on a `#[must_use]` expression",
 +        deprecation: None,
 +        module: "let_underscore",
 +    },
 +    Lint {
 +        name: "let_unit_value",
 +        group: "pedantic",
 +        desc: "creating a `let` binding to a value of unit type, which usually can\'t be used afterwards",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "linkedlist",
 +        group: "pedantic",
 +        desc: "usage of LinkedList, usually a vector is faster, or a more specialized data structure like a `VecDeque`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "logic_bug",
 +        group: "correctness",
 +        desc: "boolean expressions that contain terminals which can be eliminated",
 +        deprecation: None,
 +        module: "booleans",
 +    },
 +    Lint {
 +        name: "lossy_float_literal",
 +        group: "restriction",
 +        desc: "lossy whole number float literals",
 +        deprecation: None,
 +        module: "float_literal",
 +    },
 +    Lint {
 +        name: "macro_use_imports",
 +        group: "pedantic",
 +        desc: "#[macro_use] is no longer needed",
 +        deprecation: None,
 +        module: "macro_use",
 +    },
 +    Lint {
 +        name: "main_recursion",
 +        group: "style",
 +        desc: "recursion using the entrypoint",
 +        deprecation: None,
 +        module: "main_recursion",
 +    },
 +    Lint {
 +        name: "manual_async_fn",
 +        group: "style",
 +        desc: "manual implementations of `async` functions can be simplified using the dedicated syntax",
 +        deprecation: None,
 +        module: "manual_async_fn",
 +    },
 +    Lint {
 +        name: "manual_memcpy",
 +        group: "perf",
 +        desc: "manually copying items between slices",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "manual_non_exhaustive",
 +        group: "style",
 +        desc: "manual implementations of the non-exhaustive pattern can be simplified using #[non_exhaustive]",
 +        deprecation: None,
 +        module: "manual_non_exhaustive",
 +    },
 +    Lint {
 +        name: "manual_saturating_arithmetic",
 +        group: "style",
 +        desc: "`.chcked_add/sub(x).unwrap_or(MAX/MIN)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "manual_swap",
 +        group: "complexity",
 +        desc: "manual swap of two variables",
 +        deprecation: None,
 +        module: "swap",
 +    },
 +    Lint {
 +        name: "many_single_char_names",
 +        group: "style",
 +        desc: "too many single character bindings",
 +        deprecation: None,
 +        module: "non_expressive_names",
 +    },
 +    Lint {
 +        name: "map_clone",
 +        group: "style",
 +        desc: "using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types",
 +        deprecation: None,
 +        module: "map_clone",
 +    },
 +    Lint {
 +        name: "map_entry",
 +        group: "perf",
 +        desc: "use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`",
 +        deprecation: None,
 +        module: "entry",
 +    },
 +    Lint {
 +        name: "map_flatten",
 +        group: "pedantic",
 +        desc: "using combinations of `flatten` and `map` which can usually be written as a single method call",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "map_identity",
 +        group: "complexity",
 +        desc: "using iterator.map(|x| x)",
 +        deprecation: None,
 +        module: "map_identity",
 +    },
 +    Lint {
 +        name: "map_unwrap_or",
 +        group: "pedantic",
 +        desc: "using `.map(f).unwrap_or(a)` or `.map(f).unwrap_or_else(func)`, which are more succinctly expressed as `map_or(a, f)` or `map_or_else(a, f)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "match_as_ref",
 +        group: "complexity",
 +        desc: "a `match` on an Option value instead of using `as_ref()` or `as_mut`",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_bool",
 +        group: "pedantic",
 +        desc: "a `match` on a boolean expression instead of an `if..else` block",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_like_matches_macro",
 +        group: "style",
 +        desc: "a match that could be written with the matches! macro",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_on_vec_items",
 +        group: "pedantic",
 +        desc: "matching on vector elements can panic",
 +        deprecation: None,
 +        module: "match_on_vec_items",
 +    },
 +    Lint {
 +        name: "match_overlapping_arm",
 +        group: "style",
 +        desc: "a `match` with overlapping arms",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_ref_pats",
 +        group: "style",
 +        desc: "a `match` or `if let` with all arms prefixed with `&` instead of deref-ing the match expression",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_same_arms",
 +        group: "pedantic",
 +        desc: "`match` with identical arm bodies",
 +        deprecation: None,
 +        module: "copies",
 +    },
 +    Lint {
 +        name: "match_single_binding",
 +        group: "complexity",
 +        desc: "a match with a single binding instead of using `let` statement",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_wild_err_arm",
 +        group: "pedantic",
 +        desc: "a `match` with `Err(_)` arm and take drastic actions",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "match_wildcard_for_single_variants",
 +        group: "pedantic",
 +        desc: "a wildcard enum match for a single variant",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "maybe_infinite_iter",
 +        group: "pedantic",
 +        desc: "possible infinite iteration",
 +        deprecation: None,
 +        module: "infinite_iter",
 +    },
 +    Lint {
 +        name: "mem_discriminant_non_enum",
 +        group: "correctness",
 +        desc: "calling `mem::descriminant` on non-enum type",
 +        deprecation: None,
 +        module: "mem_discriminant",
 +    },
 +    Lint {
 +        name: "mem_forget",
 +        group: "restriction",
 +        desc: "`mem::forget` usage on `Drop` types, likely to cause memory leaks",
 +        deprecation: None,
 +        module: "mem_forget",
 +    },
 +    Lint {
 +        name: "mem_replace_option_with_none",
 +        group: "style",
 +        desc: "replacing an `Option` with `None` instead of `take()`",
 +        deprecation: None,
 +        module: "mem_replace",
 +    },
 +    Lint {
 +        name: "mem_replace_with_default",
 +        group: "style",
 +        desc: "replacing a value of type `T` with `T::default()` instead of using `std::mem::take`",
 +        deprecation: None,
 +        module: "mem_replace",
 +    },
 +    Lint {
 +        name: "mem_replace_with_uninit",
 +        group: "correctness",
 +        desc: "`mem::replace(&mut _, mem::uninitialized())` or `mem::replace(&mut _, mem::zeroed())`",
 +        deprecation: None,
 +        module: "mem_replace",
 +    },
 +    Lint {
 +        name: "min_max",
 +        group: "correctness",
 +        desc: "`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant",
 +        deprecation: None,
 +        module: "minmax",
 +    },
 +    Lint {
 +        name: "mismatched_target_os",
 +        group: "correctness",
 +        desc: "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "misrefactored_assign_op",
 +        group: "complexity",
 +        desc: "having a variable on both sides of an assign op",
 +        deprecation: None,
 +        module: "assign_ops",
 +    },
 +    Lint {
 +        name: "missing_const_for_fn",
 +        group: "nursery",
 +        desc: "Lint functions definitions that could be made `const fn`",
 +        deprecation: None,
 +        module: "missing_const_for_fn",
 +    },
 +    Lint {
 +        name: "missing_docs_in_private_items",
 +        group: "restriction",
 +        desc: "detects missing documentation for public and private members",
 +        deprecation: None,
 +        module: "missing_doc",
 +    },
 +    Lint {
 +        name: "missing_errors_doc",
 +        group: "pedantic",
 +        desc: "`pub fn` returns `Result` without `# Errors` in doc comment",
 +        deprecation: None,
 +        module: "doc",
 +    },
 +    Lint {
 +        name: "missing_inline_in_public_items",
 +        group: "restriction",
 +        desc: "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)",
 +        deprecation: None,
 +        module: "missing_inline",
 +    },
 +    Lint {
 +        name: "missing_safety_doc",
 +        group: "style",
 +        desc: "`pub unsafe fn` without `# Safety` docs",
 +        deprecation: None,
 +        module: "doc",
 +    },
 +    Lint {
 +        name: "mistyped_literal_suffixes",
 +        group: "correctness",
 +        desc: "mistyped literal suffix",
 +        deprecation: None,
 +        module: "literal_representation",
 +    },
 +    Lint {
 +        name: "mixed_case_hex_literals",
 +        group: "style",
 +        desc: "hex literals whose letter digits are not consistently upper- or lowercased",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "module_inception",
 +        group: "style",
 +        desc: "modules that have the same name as their parent module",
 +        deprecation: None,
 +        module: "enum_variants",
 +    },
 +    Lint {
 +        name: "module_name_repetitions",
 +        group: "pedantic",
 +        desc: "type names prefixed/postfixed with their containing module\'s name",
 +        deprecation: None,
 +        module: "enum_variants",
 +    },
 +    Lint {
 +        name: "modulo_arithmetic",
 +        group: "restriction",
 +        desc: "any modulo arithmetic statement",
 +        deprecation: None,
 +        module: "modulo_arithmetic",
 +    },
 +    Lint {
 +        name: "modulo_one",
 +        group: "correctness",
 +        desc: "taking a number modulo 1, which always returns 0",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "multiple_crate_versions",
 +        group: "cargo",
 +        desc: "multiple versions of the same crate being used",
 +        deprecation: None,
 +        module: "multiple_crate_versions",
 +    },
 +    Lint {
 +        name: "multiple_inherent_impl",
 +        group: "restriction",
 +        desc: "Multiple inherent impl that could be grouped",
 +        deprecation: None,
 +        module: "inherent_impl",
 +    },
 +    Lint {
 +        name: "must_use_candidate",
 +        group: "pedantic",
 +        desc: "function or method that could take a `#[must_use]` attribute",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "must_use_unit",
 +        group: "style",
 +        desc: "`#[must_use]` attribute on a unit-returning function / method",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "mut_from_ref",
 +        group: "correctness",
 +        desc: "fns that create mutable refs from immutable ref args",
 +        deprecation: None,
 +        module: "ptr",
 +    },
 +    Lint {
 +        name: "mut_mut",
 +        group: "pedantic",
 +        desc: "usage of double-mut refs, e.g., `&mut &mut ...`",
 +        deprecation: None,
 +        module: "mut_mut",
 +    },
 +    Lint {
 +        name: "mut_range_bound",
 +        group: "complexity",
 +        desc: "for loop over a range where one of the bounds is a mutable variable",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "mutable_key_type",
 +        group: "correctness",
 +        desc: "Check for mutable `Map`/`Set` key type",
 +        deprecation: None,
 +        module: "mut_key",
 +    },
 +    Lint {
 +        name: "mutex_atomic",
 +        group: "perf",
 +        desc: "using a mutex where an atomic value could be used instead",
 +        deprecation: None,
 +        module: "mutex_atomic",
 +    },
 +    Lint {
 +        name: "mutex_integer",
 +        group: "nursery",
 +        desc: "using a mutex for an integer type",
 +        deprecation: None,
 +        module: "mutex_atomic",
 +    },
 +    Lint {
 +        name: "naive_bytecount",
 +        group: "perf",
 +        desc: "use of naive `<slice>.filter(|&x| x == y).count()` to count byte values",
 +        deprecation: None,
 +        module: "bytecount",
 +    },
 +    Lint {
 +        name: "needless_bool",
 +        group: "complexity",
 +        desc: "if-statements with plain booleans in the then- and else-clause, e.g., `if p { true } else { false }`",
 +        deprecation: None,
 +        module: "needless_bool",
 +    },
 +    Lint {
 +        name: "needless_borrow",
 +        group: "nursery",
 +        desc: "taking a reference that is going to be automatically dereferenced",
 +        deprecation: None,
 +        module: "needless_borrow",
 +    },
 +    Lint {
 +        name: "needless_borrowed_reference",
 +        group: "complexity",
 +        desc: "taking a needless borrowed reference",
 +        deprecation: None,
 +        module: "needless_borrowed_ref",
 +    },
 +    Lint {
 +        name: "needless_collect",
 +        group: "perf",
 +        desc: "collecting an iterator when collect is not needed",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "needless_continue",
 +        group: "pedantic",
 +        desc: "`continue` statements that can be replaced by a rearrangement of code",
 +        deprecation: None,
 +        module: "needless_continue",
 +    },
 +    Lint {
 +        name: "needless_doctest_main",
 +        group: "style",
 +        desc: "presence of `fn main() {` in code examples",
 +        deprecation: None,
 +        module: "doc",
 +    },
 +    Lint {
 +        name: "needless_lifetimes",
 +        group: "complexity",
 +        desc: "using explicit lifetimes for references in function arguments when elision rules would allow omitting them",
 +        deprecation: None,
 +        module: "lifetimes",
 +    },
 +    Lint {
 +        name: "needless_pass_by_value",
 +        group: "pedantic",
 +        desc: "functions taking arguments by value, but not consuming them in its body",
 +        deprecation: None,
 +        module: "needless_pass_by_value",
 +    },
 +    Lint {
 +        name: "needless_range_loop",
 +        group: "style",
 +        desc: "for-looping over a range of indices where an iterator over items would do",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "needless_return",
 +        group: "style",
 +        desc: "using a return statement like `return expr;` where an expression would suffice",
 +        deprecation: None,
 +        module: "returns",
 +    },
 +    Lint {
 +        name: "needless_update",
 +        group: "complexity",
 +        desc: "using `Foo { ..base }` when there are no missing fields",
 +        deprecation: None,
 +        module: "needless_update",
 +    },
 +    Lint {
 +        name: "neg_cmp_op_on_partial_ord",
 +        group: "complexity",
 +        desc: "The use of negated comparison operators on partially ordered types may produce confusing code.",
 +        deprecation: None,
 +        module: "neg_cmp_op_on_partial_ord",
 +    },
 +    Lint {
 +        name: "neg_multiply",
 +        group: "style",
 +        desc: "multiplying integers with `-1`",
 +        deprecation: None,
 +        module: "neg_multiply",
 +    },
 +    Lint {
 +        name: "never_loop",
 +        group: "correctness",
 +        desc: "any loop that will always `break` or `return`",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "new_ret_no_self",
 +        group: "style",
 +        desc: "not returning type containing `Self` in a `new` method",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "new_without_default",
 +        group: "style",
 +        desc: "`fn new() -> Self` method without `Default` implementation",
 +        deprecation: None,
 +        module: "new_without_default",
 +    },
 +    Lint {
 +        name: "no_effect",
 +        group: "complexity",
 +        desc: "statements with no effect",
 +        deprecation: None,
 +        module: "no_effect",
 +    },
 +    Lint {
 +        name: "non_ascii_literal",
 +        group: "pedantic",
 +        desc: "using any literal non-ASCII chars in a string literal instead of using the `\\\\u` escape",
 +        deprecation: None,
 +        module: "unicode",
 +    },
 +    Lint {
 +        name: "nonminimal_bool",
 +        group: "complexity",
 +        desc: "boolean expressions that can be written more concisely",
 +        deprecation: None,
 +        module: "booleans",
 +    },
 +    Lint {
 +        name: "nonsensical_open_options",
 +        group: "correctness",
 +        desc: "nonsensical combination of options for opening a file",
 +        deprecation: None,
 +        module: "open_options",
 +    },
 +    Lint {
 +        name: "not_unsafe_ptr_arg_deref",
 +        group: "correctness",
 +        desc: "public functions dereferencing raw pointer arguments but not marked `unsafe`",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "ok_expect",
 +        group: "style",
 +        desc: "using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "op_ref",
 +        group: "style",
 +        desc: "taking a reference to satisfy the type constraints on `==`",
 +        deprecation: None,
 +        module: "eq_op",
 +    },
 +    Lint {
 +        name: "option_as_ref_deref",
 +        group: "complexity",
 +        desc: "using `as_ref().map(Deref::deref)`, which is more succinctly expressed as `as_deref()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "option_env_unwrap",
 +        group: "correctness",
 +        desc: "using `option_env!(...).unwrap()` to get environment variable",
 +        deprecation: None,
 +        module: "option_env_unwrap",
 +    },
 +    Lint {
 +        name: "option_if_let_else",
 +        group: "pedantic",
 +        desc: "reimplementation of Option::map_or",
 +        deprecation: None,
 +        module: "option_if_let_else",
 +    },
 +    Lint {
 +        name: "option_map_or_none",
 +        group: "style",
 +        desc: "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "option_map_unit_fn",
 +        group: "complexity",
 +        desc: "using `option.map(f)`, where `f` is a function or closure that returns `()`",
 +        deprecation: None,
 +        module: "map_unit_fn",
 +    },
 +    Lint {
 +        name: "option_option",
 +        group: "pedantic",
 +        desc: "usage of `Option<Option<T>>`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "or_fun_call",
 +        group: "perf",
 +        desc: "using any `*or` method with a function call, which suggests `*or_else`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "out_of_bounds_indexing",
 +        group: "correctness",
 +        desc: "out of bounds constant indexing",
 +        deprecation: None,
 +        module: "indexing_slicing",
 +    },
 +    Lint {
 +        name: "overflow_check_conditional",
 +        group: "complexity",
 +        desc: "overflow checks inspired by C which are likely to panic",
 +        deprecation: None,
 +        module: "overflow_check_conditional",
 +    },
 +    Lint {
 +        name: "panic",
 +        group: "restriction",
 +        desc: "usage of the `panic!` macro",
 +        deprecation: None,
 +        module: "panic_unimplemented",
 +    },
 +    Lint {
 +        name: "panic_params",
 +        group: "style",
 +        desc: "missing parameters in `panic!` calls",
 +        deprecation: None,
 +        module: "panic_unimplemented",
 +    },
 +    Lint {
 +        name: "panicking_unwrap",
 +        group: "correctness",
 +        desc: "checks for calls of `unwrap[_err]()` that will always fail",
 +        deprecation: None,
 +        module: "unwrap",
 +    },
 +    Lint {
 +        name: "partialeq_ne_impl",
 +        group: "complexity",
 +        desc: "re-implementing `PartialEq::ne`",
 +        deprecation: None,
 +        module: "partialeq_ne_impl",
 +    },
 +    Lint {
 +        name: "path_buf_push_overwrite",
 +        group: "nursery",
 +        desc: "calling `push` with file system root on `PathBuf` can overwrite it",
 +        deprecation: None,
 +        module: "path_buf_push_overwrite",
 +    },
 +    Lint {
 +        name: "pattern_type_mismatch",
 +        group: "restriction",
 +        desc: "type of pattern does not match the expression type",
 +        deprecation: None,
 +        module: "pattern_type_mismatch",
 +    },
 +    Lint {
 +        name: "possible_missing_comma",
 +        group: "correctness",
 +        desc: "possible missing comma in array",
 +        deprecation: None,
 +        module: "formatting",
 +    },
 +    Lint {
 +        name: "precedence",
 +        group: "complexity",
 +        desc: "operations where precedence may be unclear",
 +        deprecation: None,
 +        module: "precedence",
 +    },
 +    Lint {
 +        name: "print_literal",
 +        group: "style",
 +        desc: "printing a literal with a format string",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "print_stdout",
 +        group: "restriction",
 +        desc: "printing on stdout",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "print_with_newline",
 +        group: "style",
 +        desc: "using `print!()` with a format string that ends in a single newline",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "println_empty_string",
 +        group: "style",
 +        desc: "using `println!(\"\")` with an empty string",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "ptr_arg",
 +        group: "style",
 +        desc: "fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively",
 +        deprecation: None,
 +        module: "ptr",
 +    },
 +    Lint {
 +        name: "ptr_offset_with_cast",
 +        group: "complexity",
 +        desc: "unneeded pointer offset cast",
 +        deprecation: None,
 +        module: "ptr_offset_with_cast",
 +    },
 +    Lint {
 +        name: "pub_enum_variant_names",
 +        group: "pedantic",
 +        desc: "public enums where all variants share a prefix/postfix",
 +        deprecation: None,
 +        module: "enum_variants",
 +    },
 +    Lint {
 +        name: "question_mark",
 +        group: "style",
 +        desc: "checks for expressions that could be replaced by the question mark operator",
 +        deprecation: None,
 +        module: "question_mark",
 +    },
 +    Lint {
 +        name: "range_minus_one",
 +        group: "pedantic",
 +        desc: "`x..=(y-1)` reads better as `x..y`",
 +        deprecation: None,
 +        module: "ranges",
 +    },
 +    Lint {
 +        name: "range_plus_one",
 +        group: "pedantic",
 +        desc: "`x..(y+1)` reads better as `x..=y`",
 +        deprecation: None,
 +        module: "ranges",
 +    },
 +    Lint {
 +        name: "range_zip_with_len",
 +        group: "complexity",
 +        desc: "zipping iterator with a range when `enumerate()` would do",
 +        deprecation: None,
 +        module: "ranges",
 +    },
 +    Lint {
 +        name: "redundant_allocation",
 +        group: "perf",
 +        desc: "redundant allocation",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "redundant_clone",
 +        group: "perf",
 +        desc: "`clone()` of an owned value that is going to be dropped immediately",
 +        deprecation: None,
 +        module: "redundant_clone",
 +    },
 +    Lint {
 +        name: "redundant_closure",
 +        group: "style",
 +        desc: "redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)",
 +        deprecation: None,
 +        module: "eta_reduction",
 +    },
 +    Lint {
 +        name: "redundant_closure_call",
 +        group: "complexity",
 +        desc: "throwaway closures called in the expression they are defined",
 +        deprecation: None,
++        module: "redundant_closure_call",
 +    },
 +    Lint {
 +        name: "redundant_closure_for_method_calls",
 +        group: "pedantic",
 +        desc: "redundant closures for method calls",
 +        deprecation: None,
 +        module: "eta_reduction",
 +    },
 +    Lint {
 +        name: "redundant_field_names",
 +        group: "style",
 +        desc: "checks for fields in struct literals where shorthands could be used",
 +        deprecation: None,
 +        module: "redundant_field_names",
 +    },
 +    Lint {
 +        name: "redundant_pattern",
 +        group: "style",
 +        desc: "using `name @ _` in a pattern",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "redundant_pattern_matching",
 +        group: "style",
 +        desc: "use the proper utility function avoiding an `if let`",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "redundant_pub_crate",
 +        group: "nursery",
 +        desc: "Using `pub(crate)` visibility on items that are not crate visible due to the visibility of the module that contains them.",
 +        deprecation: None,
 +        module: "redundant_pub_crate",
 +    },
 +    Lint {
 +        name: "redundant_static_lifetimes",
 +        group: "style",
 +        desc: "Using explicit `\'static` lifetime for constants or statics when elision rules would allow omitting them.",
 +        deprecation: None,
 +        module: "redundant_static_lifetimes",
 +    },
 +    Lint {
 +        name: "ref_in_deref",
 +        group: "complexity",
 +        desc: "Use of reference in auto dereference expression.",
 +        deprecation: None,
 +        module: "reference",
 +    },
 +    Lint {
 +        name: "repeat_once",
 +        group: "complexity",
 +        desc: "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` ",
 +        deprecation: None,
 +        module: "repeat_once",
 +    },
 +    Lint {
 +        name: "rest_pat_in_fully_bound_structs",
 +        group: "restriction",
 +        desc: "a match on a struct that binds all fields but still uses the wildcard pattern",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "result_map_or_into_option",
 +        group: "style",
 +        desc: "using `Result.map_or(None, Some)`, which is more succinctly expressed as `ok()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "result_map_unit_fn",
 +        group: "complexity",
 +        desc: "using `result.map(f)`, where `f` is a function or closure that returns `()`",
 +        deprecation: None,
 +        module: "map_unit_fn",
 +    },
 +    Lint {
 +        name: "reversed_empty_ranges",
 +        group: "correctness",
 +        desc: "reversing the limits of range expressions, resulting in empty ranges",
 +        deprecation: None,
 +        module: "ranges",
 +    },
 +    Lint {
 +        name: "same_functions_in_if_condition",
 +        group: "pedantic",
 +        desc: "consecutive `if`s with the same function call",
 +        deprecation: None,
 +        module: "copies",
 +    },
 +    Lint {
 +        name: "search_is_some",
 +        group: "complexity",
 +        desc: "using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "serde_api_misuse",
 +        group: "correctness",
 +        desc: "various things that will negatively affect your serde experience",
 +        deprecation: None,
 +        module: "serde_api",
 +    },
 +    Lint {
 +        name: "shadow_reuse",
 +        group: "restriction",
 +        desc: "rebinding a name to an expression that re-uses the original value, e.g., `let x = x + 1`",
 +        deprecation: None,
 +        module: "shadow",
 +    },
 +    Lint {
 +        name: "shadow_same",
 +        group: "restriction",
 +        desc: "rebinding a name to itself, e.g., `let mut x = &mut x`",
 +        deprecation: None,
 +        module: "shadow",
 +    },
 +    Lint {
 +        name: "shadow_unrelated",
 +        group: "pedantic",
 +        desc: "rebinding a name without even using the original value",
 +        deprecation: None,
 +        module: "shadow",
 +    },
 +    Lint {
 +        name: "short_circuit_statement",
 +        group: "complexity",
 +        desc: "using a short circuit boolean condition as a statement",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "should_implement_trait",
 +        group: "style",
 +        desc: "defining a method that should be implementing a std trait",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "similar_names",
 +        group: "pedantic",
 +        desc: "similarly named items and bindings",
 +        deprecation: None,
 +        module: "non_expressive_names",
 +    },
 +    Lint {
 +        name: "single_char_pattern",
 +        group: "perf",
 +        desc: "using a single-character str where a char could be used, e.g., `_.split(\"x\")`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "single_component_path_imports",
 +        group: "style",
 +        desc: "imports with single component path are redundant",
 +        deprecation: None,
 +        module: "single_component_path_imports",
 +    },
 +    Lint {
 +        name: "single_match",
 +        group: "style",
 +        desc: "a `match` statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "single_match_else",
 +        group: "pedantic",
 +        desc: "a `match` statement with two arms where the second arm\'s pattern is a placeholder instead of a specific match pattern",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "skip_while_next",
 +        group: "complexity",
 +        desc: "using `skip_while(p).next()`, which is more succinctly expressed as `.find(!p)`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "slow_vector_initialization",
 +        group: "perf",
 +        desc: "slow vector initialization",
 +        deprecation: None,
 +        module: "slow_vector_initialization",
 +    },
 +    Lint {
 +        name: "string_add",
 +        group: "restriction",
 +        desc: "using `x + ..` where x is a `String` instead of `push_str()`",
 +        deprecation: None,
 +        module: "strings",
 +    },
 +    Lint {
 +        name: "string_add_assign",
 +        group: "pedantic",
 +        desc: "using `x = x + ..` where x is a `String` instead of `push_str()`",
 +        deprecation: None,
 +        module: "strings",
 +    },
 +    Lint {
 +        name: "string_extend_chars",
 +        group: "style",
 +        desc: "using `x.extend(s.chars())` where s is a `&str` or `String`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "string_lit_as_bytes",
 +        group: "style",
 +        desc: "calling `as_bytes` on a string literal instead of using a byte string literal",
 +        deprecation: None,
 +        module: "strings",
 +    },
 +    Lint {
 +        name: "struct_excessive_bools",
 +        group: "pedantic",
 +        desc: "using too many bools in a struct",
 +        deprecation: None,
 +        module: "excessive_bools",
 +    },
 +    Lint {
 +        name: "suboptimal_flops",
 +        group: "nursery",
 +        desc: "usage of sub-optimal floating point operations",
 +        deprecation: None,
 +        module: "floating_point_arithmetic",
 +    },
 +    Lint {
 +        name: "suspicious_arithmetic_impl",
 +        group: "correctness",
 +        desc: "suspicious use of operators in impl of arithmetic trait",
 +        deprecation: None,
 +        module: "suspicious_trait_impl",
 +    },
 +    Lint {
 +        name: "suspicious_assignment_formatting",
 +        group: "style",
 +        desc: "suspicious formatting of `*=`, `-=` or `!=`",
 +        deprecation: None,
 +        module: "formatting",
 +    },
 +    Lint {
 +        name: "suspicious_else_formatting",
 +        group: "style",
 +        desc: "suspicious formatting of `else`",
 +        deprecation: None,
 +        module: "formatting",
 +    },
 +    Lint {
 +        name: "suspicious_map",
 +        group: "complexity",
 +        desc: "suspicious usage of map",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "suspicious_op_assign_impl",
 +        group: "correctness",
 +        desc: "suspicious use of operators in impl of OpAssign trait",
 +        deprecation: None,
 +        module: "suspicious_trait_impl",
 +    },
 +    Lint {
 +        name: "suspicious_unary_op_formatting",
 +        group: "style",
 +        desc: "suspicious formatting of unary `-` or `!` on the RHS of a BinOp",
 +        deprecation: None,
 +        module: "formatting",
 +    },
 +    Lint {
 +        name: "tabs_in_doc_comments",
 +        group: "style",
 +        desc: "using tabs in doc comments is not recommended",
 +        deprecation: None,
 +        module: "tabs_in_doc_comments",
 +    },
 +    Lint {
 +        name: "temporary_assignment",
 +        group: "complexity",
 +        desc: "assignments to temporaries",
 +        deprecation: None,
 +        module: "temporary_assignment",
 +    },
 +    Lint {
 +        name: "temporary_cstring_as_ptr",
 +        group: "correctness",
 +        desc: "getting the inner pointer of a temporary `CString`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "to_digit_is_some",
 +        group: "style",
 +        desc: "`char.is_digit()` is clearer",
 +        deprecation: None,
 +        module: "to_digit_is_some",
 +    },
 +    Lint {
 +        name: "todo",
 +        group: "restriction",
 +        desc: "`todo!` should not be present in production code",
 +        deprecation: None,
 +        module: "panic_unimplemented",
 +    },
 +    Lint {
 +        name: "too_many_arguments",
 +        group: "complexity",
 +        desc: "functions with too many arguments",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "too_many_lines",
 +        group: "pedantic",
 +        desc: "functions with too many lines",
 +        deprecation: None,
 +        module: "functions",
 +    },
 +    Lint {
 +        name: "toplevel_ref_arg",
 +        group: "style",
 +        desc: "an entire binding declared as `ref`, in a function argument or a `let` statement",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "transmute_bytes_to_str",
 +        group: "complexity",
 +        desc: "transmutes from a `&[u8]` to a `&str`",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_float_to_int",
 +        group: "complexity",
 +        desc: "transmutes from a float to an integer",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_int_to_bool",
 +        group: "complexity",
 +        desc: "transmutes from an integer to a `bool`",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_int_to_char",
 +        group: "complexity",
 +        desc: "transmutes from an integer to a `char`",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_int_to_float",
 +        group: "complexity",
 +        desc: "transmutes from an integer to a float",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_ptr_to_ptr",
 +        group: "complexity",
 +        desc: "transmutes from a pointer to a pointer / a reference to a reference",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmute_ptr_to_ref",
 +        group: "complexity",
 +        desc: "transmutes from a pointer to a reference type",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "transmuting_null",
 +        group: "correctness",
 +        desc: "transmutes from a null pointer to a reference, which is undefined behavior",
 +        deprecation: None,
 +        module: "transmuting_null",
 +    },
 +    Lint {
 +        name: "trivial_regex",
 +        group: "style",
 +        desc: "trivial regular expressions",
 +        deprecation: None,
 +        module: "regex",
 +    },
 +    Lint {
 +        name: "trivially_copy_pass_by_ref",
 +        group: "pedantic",
 +        desc: "functions taking small copyable arguments by reference",
 +        deprecation: None,
 +        module: "trivially_copy_pass_by_ref",
 +    },
 +    Lint {
 +        name: "try_err",
 +        group: "style",
 +        desc: "return errors explicitly rather than hiding them behind a `?`",
 +        deprecation: None,
 +        module: "try_err",
 +    },
 +    Lint {
 +        name: "type_complexity",
 +        group: "complexity",
 +        desc: "usage of very complex types that might be better factored into `type` definitions",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "type_repetition_in_bounds",
 +        group: "pedantic",
 +        desc: "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`",
 +        deprecation: None,
 +        module: "trait_bounds",
 +    },
 +    Lint {
 +        name: "unicode_not_nfc",
 +        group: "pedantic",
 +        desc: "using a Unicode literal not in NFC normal form (see [Unicode tr15](http://www.unicode.org/reports/tr15/) for further information)",
 +        deprecation: None,
 +        module: "unicode",
 +    },
 +    Lint {
 +        name: "unimplemented",
 +        group: "restriction",
 +        desc: "`unimplemented!` should not be present in production code",
 +        deprecation: None,
 +        module: "panic_unimplemented",
 +    },
 +    Lint {
 +        name: "uninit_assumed_init",
 +        group: "correctness",
 +        desc: "`MaybeUninit::uninit().assume_init()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "unit_arg",
 +        group: "complexity",
 +        desc: "passing unit to a function",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "unit_cmp",
 +        group: "correctness",
 +        desc: "comparing unit values",
 +        deprecation: None,
 +        module: "types",
 +    },
++    Lint {
++        name: "unit_return_expecting_ord",
++        group: "correctness",
++        desc: "fn arguments of type Fn(...) -> Ord returning the unit type ().",
++        deprecation: None,
++        module: "unit_return_expecting_ord",
++    },
 +    Lint {
 +        name: "unknown_clippy_lints",
 +        group: "style",
 +        desc: "unknown_lints for scoped Clippy lints",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "unnecessary_cast",
 +        group: "complexity",
 +        desc: "cast to the same type, e.g., `x as i32` where `x: i32`",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "unnecessary_filter_map",
 +        group: "complexity",
 +        desc: "using `filter_map` when a more succinct alternative exists",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "unnecessary_fold",
 +        group: "style",
 +        desc: "using `fold` when a more succinct alternative exists",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "unnecessary_mut_passed",
 +        group: "style",
 +        desc: "an argument passed as a mutable reference although the callee only demands an immutable reference",
 +        deprecation: None,
 +        module: "mut_reference",
 +    },
 +    Lint {
 +        name: "unnecessary_operation",
 +        group: "complexity",
 +        desc: "outer expressions with no effect",
 +        deprecation: None,
 +        module: "no_effect",
 +    },
 +    Lint {
 +        name: "unnecessary_sort_by",
 +        group: "complexity",
 +        desc: "Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer",
 +        deprecation: None,
 +        module: "unnecessary_sort_by",
 +    },
 +    Lint {
 +        name: "unnecessary_unwrap",
 +        group: "complexity",
 +        desc: "checks for calls of `unwrap[_err]()` that cannot fail",
 +        deprecation: None,
 +        module: "unwrap",
 +    },
 +    Lint {
 +        name: "unneeded_field_pattern",
 +        group: "restriction",
 +        desc: "struct fields bound to a wildcard instead of using `..`",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "unneeded_wildcard_pattern",
 +        group: "complexity",
 +        desc: "tuple patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "unnested_or_patterns",
 +        group: "pedantic",
 +        desc: "unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`",
 +        deprecation: None,
 +        module: "unnested_or_patterns",
 +    },
 +    Lint {
 +        name: "unreachable",
 +        group: "restriction",
 +        desc: "`unreachable!` should not be present in production code",
 +        deprecation: None,
 +        module: "panic_unimplemented",
 +    },
 +    Lint {
 +        name: "unreadable_literal",
 +        group: "pedantic",
 +        desc: "long integer literal without underscores",
 +        deprecation: None,
 +        module: "literal_representation",
 +    },
 +    Lint {
 +        name: "unsafe_derive_deserialize",
 +        group: "pedantic",
 +        desc: "deriving `serde::Deserialize` on a type that has methods using `unsafe`",
 +        deprecation: None,
 +        module: "derive",
 +    },
 +    Lint {
 +        name: "unsafe_removed_from_name",
 +        group: "style",
 +        desc: "`unsafe` removed from API names on import",
 +        deprecation: None,
 +        module: "unsafe_removed_from_name",
 +    },
 +    Lint {
 +        name: "unseparated_literal_suffix",
 +        group: "pedantic",
 +        desc: "literals whose suffix is not separated by an underscore",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "unsound_collection_transmute",
 +        group: "correctness",
 +        desc: "transmute between collections of layout-incompatible types",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "unused_io_amount",
 +        group: "correctness",
 +        desc: "unused written/read amount",
 +        deprecation: None,
 +        module: "unused_io_amount",
 +    },
 +    Lint {
 +        name: "unused_self",
 +        group: "pedantic",
 +        desc: "methods that contain a `self` argument but don\'t use it",
 +        deprecation: None,
 +        module: "unused_self",
 +    },
 +    Lint {
 +        name: "unused_unit",
 +        group: "style",
 +        desc: "needless unit expression",
 +        deprecation: None,
 +        module: "returns",
 +    },
 +    Lint {
 +        name: "unwrap_used",
 +        group: "restriction",
 +        desc: "using `.unwrap()` on `Result` or `Option`, which should at least get a better message using `expect()`",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "use_debug",
 +        group: "restriction",
 +        desc: "use of `Debug`-based formatting",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "use_self",
 +        group: "nursery",
 +        desc: "Unnecessary structure name repetition whereas `Self` is applicable",
 +        deprecation: None,
 +        module: "use_self",
 +    },
 +    Lint {
 +        name: "used_underscore_binding",
 +        group: "pedantic",
 +        desc: "using a binding which is prefixed with an underscore",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "useless_asref",
 +        group: "complexity",
 +        desc: "using `as_ref` where the types before and after the call are the same",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "useless_attribute",
 +        group: "correctness",
 +        desc: "use of lint attributes on `extern crate` items",
 +        deprecation: None,
 +        module: "attrs",
 +    },
 +    Lint {
 +        name: "useless_conversion",
 +        group: "complexity",
 +        desc: "calls to `Into`, `TryInto`, `From`, `TryFrom`, `IntoIter` that performs useless conversions to the same type",
 +        deprecation: None,
 +        module: "useless_conversion",
 +    },
 +    Lint {
 +        name: "useless_format",
 +        group: "complexity",
 +        desc: "useless use of `format!`",
 +        deprecation: None,
 +        module: "format",
 +    },
 +    Lint {
 +        name: "useless_let_if_seq",
 +        group: "nursery",
 +        desc: "unidiomatic `let mut` declaration followed by initialization in `if`",
 +        deprecation: None,
 +        module: "let_if_seq",
 +    },
 +    Lint {
 +        name: "useless_transmute",
 +        group: "nursery",
 +        desc: "transmutes that have the same to and from types or could be a cast/coercion",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "useless_vec",
 +        group: "perf",
 +        desc: "useless `vec!`",
 +        deprecation: None,
 +        module: "vec",
 +    },
 +    Lint {
 +        name: "vec_box",
 +        group: "complexity",
 +        desc: "usage of `Vec<Box<T>>` where T: Sized, vector elements are already on the heap",
 +        deprecation: None,
 +        module: "types",
 +    },
 +    Lint {
 +        name: "vec_resize_to_zero",
 +        group: "correctness",
 +        desc: "emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake",
 +        deprecation: None,
 +        module: "vec_resize_to_zero",
 +    },
 +    Lint {
 +        name: "verbose_bit_mask",
 +        group: "style",
 +        desc: "expressions where a bit mask is less readable than the corresponding method call",
 +        deprecation: None,
 +        module: "bit_mask",
 +    },
 +    Lint {
 +        name: "verbose_file_reads",
 +        group: "restriction",
 +        desc: "use of `File::read_to_end` or `File::read_to_string`",
 +        deprecation: None,
 +        module: "verbose_file_reads",
 +    },
 +    Lint {
 +        name: "vtable_address_comparisons",
 +        group: "correctness",
 +        desc: "comparison with an address of a trait vtable",
 +        deprecation: None,
 +        module: "unnamed_address",
 +    },
 +    Lint {
 +        name: "while_immutable_condition",
 +        group: "correctness",
 +        desc: "variables used within while expression are not mutated in the body",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "while_let_loop",
 +        group: "complexity",
 +        desc: "`loop { if let { ... } else break }`, which can be written as a `while let` loop",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "while_let_on_iterator",
 +        group: "style",
 +        desc: "using a while-let loop instead of a for loop on an iterator",
 +        deprecation: None,
 +        module: "loops",
 +    },
 +    Lint {
 +        name: "wildcard_dependencies",
 +        group: "cargo",
 +        desc: "wildcard dependencies being used",
 +        deprecation: None,
 +        module: "wildcard_dependencies",
 +    },
 +    Lint {
 +        name: "wildcard_enum_match_arm",
 +        group: "restriction",
 +        desc: "a wildcard enum match arm using `_`",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "wildcard_imports",
 +        group: "pedantic",
 +        desc: "lint `use _::*` statements",
 +        deprecation: None,
 +        module: "wildcard_imports",
 +    },
 +    Lint {
 +        name: "wildcard_in_or_patterns",
 +        group: "complexity",
 +        desc: "a wildcard pattern used with others patterns in same match arm",
 +        deprecation: None,
 +        module: "matches",
 +    },
 +    Lint {
 +        name: "write_literal",
 +        group: "style",
 +        desc: "writing a literal with a format string",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "write_with_newline",
 +        group: "style",
 +        desc: "using `write!()` with a format string that ends in a single newline",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "writeln_empty_string",
 +        group: "style",
 +        desc: "using `writeln!(buf, \"\")` with an empty string",
 +        deprecation: None,
 +        module: "write",
 +    },
 +    Lint {
 +        name: "wrong_pub_self_convention",
 +        group: "restriction",
 +        desc: "defining a public method named with an established prefix (like \"into_\") that takes `self` with the wrong convention",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "wrong_self_convention",
 +        group: "style",
 +        desc: "defining a method named with an established prefix (like \"into_\") that takes `self` with the wrong convention",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +    Lint {
 +        name: "wrong_transmute",
 +        group: "correctness",
 +        desc: "transmutes that are confusing at best, undefined behaviour at worst and always useless",
 +        deprecation: None,
 +        module: "transmute",
 +    },
 +    Lint {
 +        name: "zero_divided_by_zero",
 +        group: "complexity",
 +        desc: "usage of `0.0 / 0.0` to obtain NaN instead of `f32::NAN` or `f64::NAN`",
 +        deprecation: None,
 +        module: "zero_div_zero",
 +    },
 +    Lint {
 +        name: "zero_prefixed_literal",
 +        group: "complexity",
 +        desc: "integer literals starting with `0`",
 +        deprecation: None,
 +        module: "misc_early",
 +    },
 +    Lint {
 +        name: "zero_ptr",
 +        group: "style",
 +        desc: "using `0 as *{const, mut} T`",
 +        deprecation: None,
 +        module: "misc",
 +    },
 +    Lint {
 +        name: "zero_width_space",
 +        group: "correctness",
 +        desc: "using a zero-width space in a string literal, which is confusing",
 +        deprecation: None,
 +        module: "unicode",
 +    },
 +    Lint {
 +        name: "zst_offset",
 +        group: "correctness",
 +        desc: "Check for offset calculations on raw pointers to zero-sized types",
 +        deprecation: None,
 +        module: "methods",
 +    },
 +];
 +// end lint list, do not remove this comment, it’s used in `update_lints`
 +}
index 2b20a4ceb4ab8d9ffcc3b658348920cbdfe53ad5,0000000000000000000000000000000000000000..29c56f3a94f5f6bc8a13bce3934e46251377b167
mode 100644,000000..100644
--- /dev/null
@@@ -1,22 -1,0 +1,22 @@@
- error: called `.nth(0)` on a `std::iter::Iterator`
++error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
 +  --> $DIR/iter_nth_zero.rs:20:14
 +   |
 +LL |     let _x = s.iter().nth(0);
-    |              ^^^^^^^^^^^^^^^ help: try calling: `s.iter().next()`
++   |              ^^^^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `s.iter().next()`
 +   |
 +   = note: `-D clippy::iter-nth-zero` implied by `-D warnings`
 +
- error: called `.nth(0)` on a `std::iter::Iterator`
++error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
 +  --> $DIR/iter_nth_zero.rs:25:14
 +   |
 +LL |     let _y = iter.nth(0);
-    |              ^^^^^^^^^^^ help: try calling: `iter.next()`
++   |              ^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter.next()`
 +
- error: called `.nth(0)` on a `std::iter::Iterator`
++error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
 +  --> $DIR/iter_nth_zero.rs:30:22
 +   |
 +LL |     let _unwrapped = iter2.nth(0).unwrap();
-    |                      ^^^^^^^^^^^^ help: try calling: `iter2.next()`
++   |                      ^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter2.next()`
 +
 +error: aborting due to 3 previous errors
 +
index 6bb1032a17299108a9a2603662e5b25531e7114f,0000000000000000000000000000000000000000..27222cc0869c83cf50a37d5c66fb63ee2ff92f62
mode 100644,000000..100644
--- /dev/null
@@@ -1,67 -1,0 +1,67 @@@
-         // NOTE: this code is here just to check that the identation is correct in the suggested fix
 +// run-rustfix
 +// edition:2018
 +#![warn(clippy::manual_async_fn)]
 +#![allow(unused)]
 +
 +use std::future::Future;
 +
 +async fn fut() -> i32 { 42 }
 +
 +async fn empty_fut()  {}
 +
 +async fn core_fut() -> i32 { 42 }
 +
 +// should be ignored
 +fn has_other_stmts() -> impl core::future::Future<Output = i32> {
 +    let _ = 42;
 +    async move { 42 }
 +}
 +
 +// should be ignored
 +fn not_fut() -> i32 {
 +    42
 +}
 +
 +// should be ignored
 +async fn already_async() -> impl Future<Output = i32> {
 +    async { 42 }
 +}
 +
 +struct S {}
 +impl S {
 +    async fn inh_fut() -> i32 {
++        // NOTE: this code is here just to check that the indentation is correct in the suggested fix
 +        let a = 42;
 +        let b = 21;
 +        if a < b {
 +            let c = 21;
 +            let d = 42;
 +            if c < d {
 +                let _ = 42;
 +            }
 +        }
 +        42
 +    }
 +
 +    async fn meth_fut(&self) -> i32 { 42 }
 +
 +    async fn empty_fut(&self)  {}
 +
 +    // should be ignored
 +    fn not_fut(&self) -> i32 {
 +        42
 +    }
 +
 +    // should be ignored
 +    fn has_other_stmts() -> impl core::future::Future<Output = i32> {
 +        let _ = 42;
 +        async move { 42 }
 +    }
 +
 +    // should be ignored
 +    async fn already_async(&self) -> impl Future<Output = i32> {
 +        async { 42 }
 +    }
 +}
 +
 +fn main() {}
index d50c919188be13c4ff4111fa17e604771453da13,0000000000000000000000000000000000000000..6a0f1b26c88388e18dfe49375799e928b578b049
mode 100644,000000..100644
--- /dev/null
@@@ -1,79 -1,0 +1,79 @@@
-             // NOTE: this code is here just to check that the identation is correct in the suggested fix
 +// run-rustfix
 +// edition:2018
 +#![warn(clippy::manual_async_fn)]
 +#![allow(unused)]
 +
 +use std::future::Future;
 +
 +fn fut() -> impl Future<Output = i32> {
 +    async { 42 }
 +}
 +
 +fn empty_fut() -> impl Future<Output = ()> {
 +    async {}
 +}
 +
 +fn core_fut() -> impl core::future::Future<Output = i32> {
 +    async move { 42 }
 +}
 +
 +// should be ignored
 +fn has_other_stmts() -> impl core::future::Future<Output = i32> {
 +    let _ = 42;
 +    async move { 42 }
 +}
 +
 +// should be ignored
 +fn not_fut() -> i32 {
 +    42
 +}
 +
 +// should be ignored
 +async fn already_async() -> impl Future<Output = i32> {
 +    async { 42 }
 +}
 +
 +struct S {}
 +impl S {
 +    fn inh_fut() -> impl Future<Output = i32> {
 +        async {
++            // NOTE: this code is here just to check that the indentation is correct in the suggested fix
 +            let a = 42;
 +            let b = 21;
 +            if a < b {
 +                let c = 21;
 +                let d = 42;
 +                if c < d {
 +                    let _ = 42;
 +                }
 +            }
 +            42
 +        }
 +    }
 +
 +    fn meth_fut(&self) -> impl Future<Output = i32> {
 +        async { 42 }
 +    }
 +
 +    fn empty_fut(&self) -> impl Future<Output = ()> {
 +        async {}
 +    }
 +
 +    // should be ignored
 +    fn not_fut(&self) -> i32 {
 +        42
 +    }
 +
 +    // should be ignored
 +    fn has_other_stmts() -> impl core::future::Future<Output = i32> {
 +        let _ = 42;
 +        async move { 42 }
 +    }
 +
 +    // should be ignored
 +    async fn already_async(&self) -> impl Future<Output = i32> {
 +        async { 42 }
 +    }
 +}
 +
 +fn main() {}
index f278ee41aa335607a9f26dd265ddb16bcc9206d7,0000000000000000000000000000000000000000..a1904c904d0f4930672ec80fc40887a33769cf2f
mode 100644,000000..100644
--- /dev/null
@@@ -1,98 -1,0 +1,98 @@@
- LL |         // NOTE: this code is here just to check that the identation is correct in the suggested fix
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:8:1
 +   |
 +LL | fn fut() -> impl Future<Output = i32> {
 +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +   = note: `-D clippy::manual-async-fn` implied by `-D warnings`
 +help: make the function `async` and return the output of the future directly
 +   |
 +LL | async fn fut() -> i32 {
 +   | ^^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL | fn fut() -> impl Future<Output = i32> { 42 }
 +   |                                       ^^^^^^
 +
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:12:1
 +   |
 +LL | fn empty_fut() -> impl Future<Output = ()> {
 +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +help: make the function `async` and remove the return type
 +   |
 +LL | async fn empty_fut()  {
 +   | ^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL | fn empty_fut() -> impl Future<Output = ()> {}
 +   |                                            ^^
 +
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:16:1
 +   |
 +LL | fn core_fut() -> impl core::future::Future<Output = i32> {
 +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +help: make the function `async` and return the output of the future directly
 +   |
 +LL | async fn core_fut() -> i32 {
 +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
 +   |                                                          ^^^^^^
 +
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:38:5
 +   |
 +LL |     fn inh_fut() -> impl Future<Output = i32> {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +help: make the function `async` and return the output of the future directly
 +   |
 +LL |     async fn inh_fut() -> i32 {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL |     fn inh_fut() -> impl Future<Output = i32> {
++LL |         // NOTE: this code is here just to check that the indentation is correct in the suggested fix
 +LL |         let a = 42;
 +LL |         let b = 21;
 +LL |         if a < b {
 +LL |             let c = 21;
 + ...
 +
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:54:5
 +   |
 +LL |     fn meth_fut(&self) -> impl Future<Output = i32> {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +help: make the function `async` and return the output of the future directly
 +   |
 +LL |     async fn meth_fut(&self) -> i32 {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL |     fn meth_fut(&self) -> impl Future<Output = i32> { 42 }
 +   |                                                     ^^^^^^
 +
 +error: this function can be simplified using the `async fn` syntax
 +  --> $DIR/manual_async_fn.rs:58:5
 +   |
 +LL |     fn empty_fut(&self) -> impl Future<Output = ()> {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
 +help: make the function `async` and remove the return type
 +   |
 +LL |     async fn empty_fut(&self)  {
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: move the body of the async block to the enclosing function
 +   |
 +LL |     fn empty_fut(&self) -> impl Future<Output = ()> {}
 +   |                                                     ^^
 +
 +error: aborting due to 6 previous errors
 +
index 2ed1b09bece746d1beb7ef6a791946efeee0f681,0000000000000000000000000000000000000000..a82b1159161903d5ba36e427cc2265f2ed5e3c14
mode 100644,000000..100644
--- /dev/null
@@@ -1,85 -1,0 +1,95 @@@
 +#![warn(clippy::needless_range_loop)]
 +
 +fn calc_idx(i: usize) -> usize {
 +    (i + i + 20) % 4
 +}
 +
 +fn main() {
 +    let ns = vec![2, 3, 5, 7];
 +
 +    for i in 3..10 {
 +        println!("{}", ns[i]);
 +    }
 +
 +    for i in 3..10 {
 +        println!("{}", ns[i % 4]);
 +    }
 +
 +    for i in 3..10 {
 +        println!("{}", ns[i % ns.len()]);
 +    }
 +
 +    for i in 3..10 {
 +        println!("{}", ns[calc_idx(i)]);
 +    }
 +
 +    for i in 3..10 {
 +        println!("{}", ns[calc_idx(i) % 4]);
 +    }
 +
 +    let mut ms = vec![1, 2, 3, 4, 5, 6];
 +    for i in 0..ms.len() {
 +        ms[i] *= 2;
 +    }
 +    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);
 +
 +    let mut ms = vec![1, 2, 3, 4, 5, 6];
 +    for i in 0..ms.len() {
 +        let x = &mut ms[i];
 +        *x *= 2;
 +    }
 +    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);
 +
 +    let g = vec![1, 2, 3, 4, 5, 6];
 +    let glen = g.len();
 +    for i in 0..glen {
 +        let x: u32 = g[i + 1..].iter().sum();
 +        println!("{}", g[i] + x);
 +    }
 +    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);
 +
 +    let mut g = vec![1, 2, 3, 4, 5, 6];
 +    let glen = g.len();
 +    for i in 0..glen {
 +        g[i] = g[i + 1..].iter().sum();
 +    }
 +    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);
 +
 +    let x = 5;
 +    let mut vec = vec![0; 9];
 +
 +    for i in x..x + 4 {
 +        vec[i] += 1;
 +    }
 +
 +    let x = 5;
 +    let mut vec = vec![0; 10];
 +
 +    for i in x..=x + 4 {
 +        vec[i] += 1;
 +    }
 +
 +    let arr = [1, 2, 3];
 +
 +    for i in 0..3 {
 +        println!("{}", arr[i]);
 +    }
 +
 +    for i in 0..2 {
 +        println!("{}", arr[i]);
 +    }
 +
 +    for i in 1..3 {
 +        println!("{}", arr[i]);
 +    }
 +}
++
++mod issue2277 {
++    pub fn example(list: &[[f64; 3]]) {
++        let mut x: [f64; 3] = [10.; 3];
++
++        for i in 0..3 {
++            x[i] = list.iter().map(|item| item[i]).sum::<f64>();
++        }
++    }
++}
index cbc4ca39161681f3edd71b684a9a91a2d8722d0b,0000000000000000000000000000000000000000..2770eb2b2ab4389e635fd779134d5bfce061a4cd
mode 100644,000000..100644
--- /dev/null
@@@ -1,204 -1,0 +1,204 @@@
- // Issue #1991: the outter loop should not warn.
 +#![allow(
 +    clippy::single_match,
 +    unused_assignments,
 +    unused_variables,
 +    clippy::while_immutable_condition
 +)]
 +
 +fn test1() {
 +    let mut x = 0;
 +    loop {
 +        // clippy::never_loop
 +        x += 1;
 +        if x == 1 {
 +            return;
 +        }
 +        break;
 +    }
 +}
 +
 +fn test2() {
 +    let mut x = 0;
 +    loop {
 +        x += 1;
 +        if x == 1 {
 +            break;
 +        }
 +    }
 +}
 +
 +fn test3() {
 +    let mut x = 0;
 +    loop {
 +        // never loops
 +        x += 1;
 +        break;
 +    }
 +}
 +
 +fn test4() {
 +    let mut x = 1;
 +    loop {
 +        x += 1;
 +        match x {
 +            5 => return,
 +            _ => (),
 +        }
 +    }
 +}
 +
 +fn test5() {
 +    let i = 0;
 +    loop {
 +        // never loops
 +        while i == 0 {
 +            // never loops
 +            break;
 +        }
 +        return;
 +    }
 +}
 +
 +fn test6() {
 +    let mut x = 0;
 +    'outer: loop {
 +        x += 1;
 +        loop {
 +            // never loops
 +            if x == 5 {
 +                break;
 +            }
 +            continue 'outer;
 +        }
 +        return;
 +    }
 +}
 +
 +fn test7() {
 +    let mut x = 0;
 +    loop {
 +        x += 1;
 +        match x {
 +            1 => continue,
 +            _ => (),
 +        }
 +        return;
 +    }
 +}
 +
 +fn test8() {
 +    let mut x = 0;
 +    loop {
 +        x += 1;
 +        match x {
 +            5 => return,
 +            _ => continue,
 +        }
 +    }
 +}
 +
 +fn test9() {
 +    let x = Some(1);
 +    while let Some(y) = x {
 +        // never loops
 +        return;
 +    }
 +}
 +
 +fn test10() {
 +    for x in 0..10 {
 +        // never loops
 +        match x {
 +            1 => break,
 +            _ => return,
 +        }
 +    }
 +}
 +
 +fn test11<F: FnMut() -> i32>(mut f: F) {
 +    loop {
 +        return match f() {
 +            1 => continue,
 +            _ => (),
 +        };
 +    }
 +}
 +
 +pub fn test12(a: bool, b: bool) {
 +    'label: loop {
 +        loop {
 +            if a {
 +                continue 'label;
 +            }
 +            if b {
 +                break;
 +            }
 +        }
 +        break;
 +    }
 +}
 +
 +pub fn test13() {
 +    let mut a = true;
 +    loop {
 +        // infinite loop
 +        while a {
 +            if true {
 +                a = false;
 +                continue;
 +            }
 +            return;
 +        }
 +    }
 +}
 +
 +pub fn test14() {
 +    let mut a = true;
 +    'outer: while a {
 +        // never loops
 +        while a {
 +            if a {
 +                a = false;
 +                continue;
 +            }
 +        }
 +        break 'outer;
 +    }
 +}
 +
++// Issue #1991: the outer loop should not warn.
 +pub fn test15() {
 +    'label: loop {
 +        while false {
 +            break 'label;
 +        }
 +    }
 +}
 +
 +// Issue #4058: `continue` in `break` expression
 +pub fn test16() {
 +    let mut n = 1;
 +    loop {
 +        break if n != 5 {
 +            n += 1;
 +            continue;
 +        };
 +    }
 +}
 +
 +fn main() {
 +    test1();
 +    test2();
 +    test3();
 +    test4();
 +    test5();
 +    test6();
 +    test7();
 +    test8();
 +    test9();
 +    test10();
 +    test11(|| 0);
 +    test12(true, false);
 +    test13();
 +    test14();
 +}
index dabb695368dba2b485cdc7de2b26defb1cdee55e,0000000000000000000000000000000000000000..f91ccfaed743d4ac9ceb35e5a7651a9f176aa2e2
mode 100644,000000..100644
--- /dev/null
@@@ -1,33 -1,0 +1,41 @@@
 +#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 +#![allow(clippy::assertions_on_constants)]
 +
 +fn panic() {
 +    let a = 2;
 +    panic!();
++    panic!("message");
++    panic!("{} {}", "panic with", "multiple arguments");
 +    let b = a + 2;
 +}
 +
 +fn todo() {
 +    let a = 2;
 +    todo!();
++    todo!("message");
++    todo!("{} {}", "panic with", "multiple arguments");
 +    let b = a + 2;
 +}
 +
 +fn unimplemented() {
 +    let a = 2;
 +    unimplemented!();
++    unimplemented!("message");
++    unimplemented!("{} {}", "panic with", "multiple arguments");
 +    let b = a + 2;
 +}
 +
 +fn unreachable() {
 +    let a = 2;
 +    unreachable!();
++    unreachable!("message");
++    unreachable!("{} {}", "panic with", "multiple arguments");
 +    let b = a + 2;
 +}
 +
 +fn main() {
 +    panic();
 +    todo();
 +    unimplemented();
 +    unreachable();
 +}
index 72319bc7e45846014e6ad49e6669a7cf194e4e8a,0000000000000000000000000000000000000000..37c11d72a574a8fdcb0b4d1dbb0e6498c26faa50
mode 100644,000000..100644
--- /dev/null
@@@ -1,34 -1,0 +1,88 @@@
-   --> $DIR/panicking_macros.rs:12:5
 +error: `panic` should not be present in production code
 +  --> $DIR/panicking_macros.rs:6:5
 +   |
 +LL |     panic!();
 +   |     ^^^^^^^^^
 +   |
 +   = note: `-D clippy::panic` implied by `-D warnings`
 +
++error: `panic` should not be present in production code
++  --> $DIR/panicking_macros.rs:7:5
++   |
++LL |     panic!("message");
++   |     ^^^^^^^^^^^^^^^^^^
++   |
++   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
++
++error: `panic` should not be present in production code
++  --> $DIR/panicking_macros.rs:8:5
++   |
++LL |     panic!("{} {}", "panic with", "multiple arguments");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++   |
++   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
++
 +error: `todo` should not be present in production code
-   --> $DIR/panicking_macros.rs:18:5
++  --> $DIR/panicking_macros.rs:14:5
 +   |
 +LL |     todo!();
 +   |     ^^^^^^^^
 +   |
 +   = note: `-D clippy::todo` implied by `-D warnings`
 +
++error: `todo` should not be present in production code
++  --> $DIR/panicking_macros.rs:15:5
++   |
++LL |     todo!("message");
++   |     ^^^^^^^^^^^^^^^^^
++
++error: `todo` should not be present in production code
++  --> $DIR/panicking_macros.rs:16:5
++   |
++LL |     todo!("{} {}", "panic with", "multiple arguments");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++
 +error: `unimplemented` should not be present in production code
- error: `unreachable` should not be present in production code
++  --> $DIR/panicking_macros.rs:22:5
 +   |
 +LL |     unimplemented!();
 +   |     ^^^^^^^^^^^^^^^^^
 +   |
 +   = note: `-D clippy::unimplemented` implied by `-D warnings`
 +
- error: aborting due to 4 previous errors
++error: `unimplemented` should not be present in production code
++  --> $DIR/panicking_macros.rs:23:5
++   |
++LL |     unimplemented!("message");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
++
++error: `unimplemented` should not be present in production code
 +  --> $DIR/panicking_macros.rs:24:5
 +   |
++LL |     unimplemented!("{} {}", "panic with", "multiple arguments");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++
++error: `unreachable` should not be present in production code
++  --> $DIR/panicking_macros.rs:30:5
++   |
 +LL |     unreachable!();
 +   |     ^^^^^^^^^^^^^^^
 +   |
 +   = note: `-D clippy::unreachable` implied by `-D warnings`
 +
++error: `unreachable` should not be present in production code
++  --> $DIR/panicking_macros.rs:31:5
++   |
++LL |     unreachable!("message");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^
++   |
++   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
++
++error: `unreachable` should not be present in production code
++  --> $DIR/panicking_macros.rs:32:5
++   |
++LL |     unreachable!("{} {}", "panic with", "multiple arguments");
++   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++
++error: aborting due to 12 previous errors
 +
index 17b1f1bd0bf300171fd79a797ff0df0a765f1697,0000000000000000000000000000000000000000..4d284ae1319d321a4d867e91f10e71ae317bacd9
mode 100644,000000..100644
--- /dev/null
@@@ -1,53 -1,0 +1,53 @@@
-     // Odd functions shoud not trigger an error
 +// run-rustfix
 +#![warn(clippy::precedence)]
 +#![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)]
 +#![allow(clippy::identity_op)]
 +#![allow(clippy::eq_op)]
 +
 +macro_rules! trip {
 +    ($a:expr) => {
 +        match $a & 0b1111_1111u8 {
 +            0 => println!("a is zero ({})", $a),
 +            _ => println!("a is {}", $a),
 +        }
 +    };
 +}
 +
 +fn main() {
 +    1 << (2 + 3);
 +    (1 + 2) << 3;
 +    4 >> (1 + 1);
 +    (1 + 3) >> 2;
 +    1 ^ (1 - 1);
 +    3 | (2 - 1);
 +    3 & (5 - 2);
 +    -(1i32.abs());
 +    -(1f32.abs());
 +
 +    // These should not trigger an error
 +    let _ = (-1i32).abs();
 +    let _ = (-1f32).abs();
 +    let _ = -(1i32).abs();
 +    let _ = -(1f32).abs();
 +    let _ = -(1i32.abs());
 +    let _ = -(1f32.abs());
 +
++    // Odd functions should not trigger an error
 +    let _ = -1f64.asin();
 +    let _ = -1f64.asinh();
 +    let _ = -1f64.atan();
 +    let _ = -1f64.atanh();
 +    let _ = -1f64.cbrt();
 +    let _ = -1f64.fract();
 +    let _ = -1f64.round();
 +    let _ = -1f64.signum();
 +    let _ = -1f64.sin();
 +    let _ = -1f64.sinh();
 +    let _ = -1f64.tan();
 +    let _ = -1f64.tanh();
 +    let _ = -1f64.to_degrees();
 +    let _ = -1f64.to_radians();
 +
 +    let b = 3;
 +    trip!(b * 8);
 +}
index 2d0891fd3c20c1c90631e6a582d14f50eafcdf95,0000000000000000000000000000000000000000..2d08e82f349ade91eb20d8fa8adb3f040a6d2908
mode 100644,000000..100644
--- /dev/null
@@@ -1,53 -1,0 +1,53 @@@
-     // Odd functions shoud not trigger an error
 +// run-rustfix
 +#![warn(clippy::precedence)]
 +#![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)]
 +#![allow(clippy::identity_op)]
 +#![allow(clippy::eq_op)]
 +
 +macro_rules! trip {
 +    ($a:expr) => {
 +        match $a & 0b1111_1111u8 {
 +            0 => println!("a is zero ({})", $a),
 +            _ => println!("a is {}", $a),
 +        }
 +    };
 +}
 +
 +fn main() {
 +    1 << 2 + 3;
 +    1 + 2 << 3;
 +    4 >> 1 + 1;
 +    1 + 3 >> 2;
 +    1 ^ 1 - 1;
 +    3 | 2 - 1;
 +    3 & 5 - 2;
 +    -1i32.abs();
 +    -1f32.abs();
 +
 +    // These should not trigger an error
 +    let _ = (-1i32).abs();
 +    let _ = (-1f32).abs();
 +    let _ = -(1i32).abs();
 +    let _ = -(1f32).abs();
 +    let _ = -(1i32.abs());
 +    let _ = -(1f32.abs());
 +
++    // Odd functions should not trigger an error
 +    let _ = -1f64.asin();
 +    let _ = -1f64.asinh();
 +    let _ = -1f64.atan();
 +    let _ = -1f64.atanh();
 +    let _ = -1f64.cbrt();
 +    let _ = -1f64.fract();
 +    let _ = -1f64.round();
 +    let _ = -1f64.signum();
 +    let _ = -1f64.sin();
 +    let _ = -1f64.sinh();
 +    let _ = -1f64.tan();
 +    let _ = -1f64.tanh();
 +    let _ = -1f64.to_degrees();
 +    let _ = -1f64.to_radians();
 +
 +    let b = 3;
 +    trip!(b * 8);
 +}
index 764c10a6d398feaa87957ed4bdbe7f353f7fb657,0000000000000000000000000000000000000000..cdeefda4c234c071e573445af3e10e1f0e404702
mode 100644,000000..100644
--- /dev/null
@@@ -1,172 -1,0 +1,187 @@@
 +// run-rustfix
 +// rustfix-only-machine-applicable
 +
 +use std::ffi::OsString;
 +use std::path::Path;
 +
 +fn main() {
 +    let _s = ["lorem", "ipsum"].join(" ");
 +
 +    let s = String::from("foo");
 +    let _s = s;
 +
 +    let s = String::from("foo");
 +    let _s = s;
 +
 +    let s = String::from("foo");
 +    let _s = s;
 +
 +    let _s = Path::new("/a/b/").join("c");
 +
 +    let _s = Path::new("/a/b/").join("c");
 +
 +    let _s = OsString::new();
 +
 +    let _s = OsString::new();
 +
 +    // Check that lint level works
 +    #[allow(clippy::redundant_clone)]
 +    let _s = String::new().to_string();
 +
 +    let tup = (String::from("foo"),);
 +    let _t = tup.0;
 +
 +    let tup_ref = &(String::from("foo"),);
 +    let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed
 +
 +    {
 +        let x = String::new();
 +        let y = &x;
 +
 +        let _x = x.clone(); // ok; `x` is borrowed by `y`
 +
 +        let _ = y.len();
 +    }
 +
 +    let x = (String::new(),);
 +    let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x`
 +
 +    with_branch(Alpha, true);
 +    cannot_double_move(Alpha);
 +    cannot_move_from_type_with_drop();
 +    borrower_propagation();
 +    not_consumed();
 +    issue_5405();
++    manually_drop();
 +}
 +
 +#[derive(Clone)]
 +struct Alpha;
 +fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {
 +    if b {
 +        (a.clone(), a)
 +    } else {
 +        (Alpha, a)
 +    }
 +}
 +
 +fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {
 +    (a.clone(), a)
 +}
 +
 +struct TypeWithDrop {
 +    x: String,
 +}
 +
 +impl Drop for TypeWithDrop {
 +    fn drop(&mut self) {}
 +}
 +
 +fn cannot_move_from_type_with_drop() -> String {
 +    let s = TypeWithDrop { x: String::new() };
 +    s.x.clone() // removing this `clone()` summons E0509
 +}
 +
 +fn borrower_propagation() {
 +    let s = String::new();
 +    let t = String::new();
 +
 +    {
 +        fn b() -> bool {
 +            unimplemented!()
 +        }
 +        let _u = if b() { &s } else { &t };
 +
 +        // ok; `s` and `t` are possibly borrowed
 +        let _s = s.clone();
 +        let _t = t.clone();
 +    }
 +
 +    {
 +        let _u = || s.len();
 +        let _v = [&t; 32];
 +        let _s = s.clone(); // ok
 +        let _t = t.clone(); // ok
 +    }
 +
 +    {
 +        let _u = {
 +            let u = Some(&s);
 +            let _ = s.clone(); // ok
 +            u
 +        };
 +        let _s = s.clone(); // ok
 +    }
 +
 +    {
 +        use std::convert::identity as id;
 +        let _u = id(id(&s));
 +        let _s = s.clone(); // ok, `u` borrows `s`
 +    }
 +
 +    let _s = s;
 +    let _t = t;
 +
 +    #[derive(Clone)]
 +    struct Foo {
 +        x: usize,
 +    }
 +
 +    {
 +        let f = Foo { x: 123 };
 +        let _x = Some(f.x);
 +        let _f = f;
 +    }
 +
 +    {
 +        let f = Foo { x: 123 };
 +        let _x = &f.x;
 +        let _f = f.clone(); // ok
 +    }
 +}
 +
 +fn not_consumed() {
 +    let x = std::path::PathBuf::from("home");
 +    let y = x.join("matthias");
 +    // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is
 +    // redundant. (It also does not consume the PathBuf)
 +
 +    println!("x: {:?}, y: {:?}", x, y);
 +
 +    let mut s = String::new();
 +    s.clone().push_str("foo"); // OK, removing this `clone()` will change the behavior.
 +    s.push_str("bar");
 +    assert_eq!(s, "bar");
 +
 +    let t = Some(s);
 +    // OK
 +    if let Some(x) = t.clone() {
 +        println!("{}", x);
 +    }
 +    if let Some(x) = t {
 +        println!("{}", x);
 +    }
 +}
 +
 +#[allow(clippy::clone_on_copy)]
 +fn issue_5405() {
 +    let a: [String; 1] = [String::from("foo")];
 +    let _b: String = a[0].clone();
 +
 +    let c: [usize; 2] = [2, 3];
 +    let _d: usize = c[1].clone();
 +}
++
++fn manually_drop() {
++    use std::mem::ManuallyDrop;
++    use std::sync::Arc;
++
++    let a = ManuallyDrop::new(Arc::new("Hello!".to_owned()));
++    let _ = a.clone(); // OK
++
++    let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));
++    unsafe {
++        Arc::from_raw(p);
++        Arc::from_raw(p);
++    }
++}
index 839747b131d77da22c7d559d0133f7006bd2d246,0000000000000000000000000000000000000000..acb7ffb305f2a8890b981bfed1c4f5303d8da232
mode 100644,000000..100644
--- /dev/null
@@@ -1,172 -1,0 +1,187 @@@
 +// run-rustfix
 +// rustfix-only-machine-applicable
 +
 +use std::ffi::OsString;
 +use std::path::Path;
 +
 +fn main() {
 +    let _s = ["lorem", "ipsum"].join(" ").to_string();
 +
 +    let s = String::from("foo");
 +    let _s = s.clone();
 +
 +    let s = String::from("foo");
 +    let _s = s.to_string();
 +
 +    let s = String::from("foo");
 +    let _s = s.to_owned();
 +
 +    let _s = Path::new("/a/b/").join("c").to_owned();
 +
 +    let _s = Path::new("/a/b/").join("c").to_path_buf();
 +
 +    let _s = OsString::new().to_owned();
 +
 +    let _s = OsString::new().to_os_string();
 +
 +    // Check that lint level works
 +    #[allow(clippy::redundant_clone)]
 +    let _s = String::new().to_string();
 +
 +    let tup = (String::from("foo"),);
 +    let _t = tup.0.clone();
 +
 +    let tup_ref = &(String::from("foo"),);
 +    let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed
 +
 +    {
 +        let x = String::new();
 +        let y = &x;
 +
 +        let _x = x.clone(); // ok; `x` is borrowed by `y`
 +
 +        let _ = y.len();
 +    }
 +
 +    let x = (String::new(),);
 +    let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x`
 +
 +    with_branch(Alpha, true);
 +    cannot_double_move(Alpha);
 +    cannot_move_from_type_with_drop();
 +    borrower_propagation();
 +    not_consumed();
 +    issue_5405();
++    manually_drop();
 +}
 +
 +#[derive(Clone)]
 +struct Alpha;
 +fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {
 +    if b {
 +        (a.clone(), a.clone())
 +    } else {
 +        (Alpha, a)
 +    }
 +}
 +
 +fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {
 +    (a.clone(), a)
 +}
 +
 +struct TypeWithDrop {
 +    x: String,
 +}
 +
 +impl Drop for TypeWithDrop {
 +    fn drop(&mut self) {}
 +}
 +
 +fn cannot_move_from_type_with_drop() -> String {
 +    let s = TypeWithDrop { x: String::new() };
 +    s.x.clone() // removing this `clone()` summons E0509
 +}
 +
 +fn borrower_propagation() {
 +    let s = String::new();
 +    let t = String::new();
 +
 +    {
 +        fn b() -> bool {
 +            unimplemented!()
 +        }
 +        let _u = if b() { &s } else { &t };
 +
 +        // ok; `s` and `t` are possibly borrowed
 +        let _s = s.clone();
 +        let _t = t.clone();
 +    }
 +
 +    {
 +        let _u = || s.len();
 +        let _v = [&t; 32];
 +        let _s = s.clone(); // ok
 +        let _t = t.clone(); // ok
 +    }
 +
 +    {
 +        let _u = {
 +            let u = Some(&s);
 +            let _ = s.clone(); // ok
 +            u
 +        };
 +        let _s = s.clone(); // ok
 +    }
 +
 +    {
 +        use std::convert::identity as id;
 +        let _u = id(id(&s));
 +        let _s = s.clone(); // ok, `u` borrows `s`
 +    }
 +
 +    let _s = s.clone();
 +    let _t = t.clone();
 +
 +    #[derive(Clone)]
 +    struct Foo {
 +        x: usize,
 +    }
 +
 +    {
 +        let f = Foo { x: 123 };
 +        let _x = Some(f.x);
 +        let _f = f.clone();
 +    }
 +
 +    {
 +        let f = Foo { x: 123 };
 +        let _x = &f.x;
 +        let _f = f.clone(); // ok
 +    }
 +}
 +
 +fn not_consumed() {
 +    let x = std::path::PathBuf::from("home");
 +    let y = x.clone().join("matthias");
 +    // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is
 +    // redundant. (It also does not consume the PathBuf)
 +
 +    println!("x: {:?}, y: {:?}", x, y);
 +
 +    let mut s = String::new();
 +    s.clone().push_str("foo"); // OK, removing this `clone()` will change the behavior.
 +    s.push_str("bar");
 +    assert_eq!(s, "bar");
 +
 +    let t = Some(s);
 +    // OK
 +    if let Some(x) = t.clone() {
 +        println!("{}", x);
 +    }
 +    if let Some(x) = t {
 +        println!("{}", x);
 +    }
 +}
 +
 +#[allow(clippy::clone_on_copy)]
 +fn issue_5405() {
 +    let a: [String; 1] = [String::from("foo")];
 +    let _b: String = a[0].clone();
 +
 +    let c: [usize; 2] = [2, 3];
 +    let _d: usize = c[1].clone();
 +}
++
++fn manually_drop() {
++    use std::mem::ManuallyDrop;
++    use std::sync::Arc;
++
++    let a = ManuallyDrop::new(Arc::new("Hello!".to_owned()));
++    let _ = a.clone(); // OK
++
++    let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));
++    unsafe {
++        Arc::from_raw(p);
++        Arc::from_raw(p);
++    }
++}
index eced198283ce8f5db36ef3fa7c4c2f93d38ec859,0000000000000000000000000000000000000000..89b39254299107df27cc468f9b761d3f07d269f0
mode 100644,000000..100644
--- /dev/null
@@@ -1,171 -1,0 +1,171 @@@
-   --> $DIR/redundant_clone.rs:61:22
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:8:42
 +   |
 +LL |     let _s = ["lorem", "ipsum"].join(" ").to_string();
 +   |                                          ^^^^^^^^^^^^ help: remove this
 +   |
 +   = note: `-D clippy::redundant-clone` implied by `-D warnings`
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:8:14
 +   |
 +LL |     let _s = ["lorem", "ipsum"].join(" ").to_string();
 +   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:11:15
 +   |
 +LL |     let _s = s.clone();
 +   |               ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:11:14
 +   |
 +LL |     let _s = s.clone();
 +   |              ^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:14:15
 +   |
 +LL |     let _s = s.to_string();
 +   |               ^^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:14:14
 +   |
 +LL |     let _s = s.to_string();
 +   |              ^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:17:15
 +   |
 +LL |     let _s = s.to_owned();
 +   |               ^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:17:14
 +   |
 +LL |     let _s = s.to_owned();
 +   |              ^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:19:42
 +   |
 +LL |     let _s = Path::new("/a/b/").join("c").to_owned();
 +   |                                          ^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:19:14
 +   |
 +LL |     let _s = Path::new("/a/b/").join("c").to_owned();
 +   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:21:42
 +   |
 +LL |     let _s = Path::new("/a/b/").join("c").to_path_buf();
 +   |                                          ^^^^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:21:14
 +   |
 +LL |     let _s = Path::new("/a/b/").join("c").to_path_buf();
 +   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:23:29
 +   |
 +LL |     let _s = OsString::new().to_owned();
 +   |                             ^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:23:14
 +   |
 +LL |     let _s = OsString::new().to_owned();
 +   |              ^^^^^^^^^^^^^^^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:25:29
 +   |
 +LL |     let _s = OsString::new().to_os_string();
 +   |                             ^^^^^^^^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:25:14
 +   |
 +LL |     let _s = OsString::new().to_os_string();
 +   |              ^^^^^^^^^^^^^^^
 +
 +error: redundant clone
 +  --> $DIR/redundant_clone.rs:32:19
 +   |
 +LL |     let _t = tup.0.clone();
 +   |                   ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
 +  --> $DIR/redundant_clone.rs:32:14
 +   |
 +LL |     let _t = tup.0.clone();
 +   |              ^^^^^
 +
 +error: redundant clone
-   --> $DIR/redundant_clone.rs:61:21
++  --> $DIR/redundant_clone.rs:62:22
 +   |
 +LL |         (a.clone(), a.clone())
 +   |                      ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
-   --> $DIR/redundant_clone.rs:121:15
++  --> $DIR/redundant_clone.rs:62:21
 +   |
 +LL |         (a.clone(), a.clone())
 +   |                     ^
 +
 +error: redundant clone
-   --> $DIR/redundant_clone.rs:121:14
++  --> $DIR/redundant_clone.rs:122:15
 +   |
 +LL |     let _s = s.clone();
 +   |               ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
-   --> $DIR/redundant_clone.rs:122:15
++  --> $DIR/redundant_clone.rs:122:14
 +   |
 +LL |     let _s = s.clone();
 +   |              ^
 +
 +error: redundant clone
-   --> $DIR/redundant_clone.rs:122:14
++  --> $DIR/redundant_clone.rs:123:15
 +   |
 +LL |     let _t = t.clone();
 +   |               ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
-   --> $DIR/redundant_clone.rs:132:19
++  --> $DIR/redundant_clone.rs:123:14
 +   |
 +LL |     let _t = t.clone();
 +   |              ^
 +
 +error: redundant clone
-   --> $DIR/redundant_clone.rs:132:18
++  --> $DIR/redundant_clone.rs:133:19
 +   |
 +LL |         let _f = f.clone();
 +   |                   ^^^^^^^^ help: remove this
 +   |
 +note: this value is dropped without further use
-   --> $DIR/redundant_clone.rs:144:14
++  --> $DIR/redundant_clone.rs:133:18
 +   |
 +LL |         let _f = f.clone();
 +   |                  ^
 +
 +error: redundant clone
-   --> $DIR/redundant_clone.rs:144:13
++  --> $DIR/redundant_clone.rs:145:14
 +   |
 +LL |     let y = x.clone().join("matthias");
 +   |              ^^^^^^^^ help: remove this
 +   |
 +note: cloned value is neither consumed nor mutated
++  --> $DIR/redundant_clone.rs:145:13
 +   |
 +LL |     let y = x.clone().join("matthias");
 +   |             ^^^^^^^^^
 +
 +error: aborting due to 14 previous errors
 +
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3dd365620ccbf1b4f4eef131819ce9da695f84dd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++// non rustfixable, see redundant_closure_call_fixable.rs
++
++#![warn(clippy::redundant_closure_call)]
++
++fn main() {
++    let mut i = 1;
++
++    // lint here
++    let mut k = (|m| m + 1)(i);
++
++    // lint here
++    k = (|a, b| a * b)(1, 5);
++
++    // don't lint these
++    #[allow(clippy::needless_return)]
++    (|| return 2)();
++    (|| -> Option<i32> { None? })();
++    (|| -> Result<i32, i32> { Err(2)? })();
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..79f276634619e277c24cef3069afe85953948210
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,16 @@@
++error: try not to call a closure in the expression where it is declared.
++  --> $DIR/redundant_closure_call_early.rs:9:17
++   |
++LL |     let mut k = (|m| m + 1)(i);
++   |                 ^^^^^^^^^^^^^^
++   |
++   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`
++
++error: try not to call a closure in the expression where it is declared.
++  --> $DIR/redundant_closure_call_early.rs:12:9
++   |
++LL |     k = (|a, b| a * b)(1, 5);
++   |         ^^^^^^^^^^^^^^^^^^^^
++
++error: aborting due to 2 previous errors
++
index e7737f9dd856fe6719da3275e182d4df6f865e8c,0000000000000000000000000000000000000000..644161d9f5d885eb24da0c187bfcd5e63ffa1352
mode 100644,000000..100644
--- /dev/null
@@@ -1,10 -1,0 +1,10 @@@
- error: Try not to call a closure in the expression where it is declared.
++error: try not to call a closure in the expression where it is declared.
 +  --> $DIR/redundant_closure_call_fixable.rs:7:13
 +   |
 +LL |     let a = (|| 42)();
-    |             ^^^^^^^^^ help: Try doing something like: : `42`
++   |             ^^^^^^^^^ help: try doing something like: `42`
 +   |
 +   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`
 +
 +error: aborting due to previous error
 +
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e29a1dce0c7e8f040f7dd3f262e505fbf4d21d9a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,27 @@@
++// non rustfixable, see redundant_closure_call_fixable.rs
++
++#![warn(clippy::redundant_closure_call)]
++
++fn main() {
++    let mut i = 1;
++
++    // don't lint here, the closure is used more than once
++    let closure = |i| i + 1;
++    i = closure(3);
++    i = closure(4);
++
++    // lint here
++    let redun_closure = || 1;
++    i = redun_closure();
++
++    // shadowed closures are supported, lint here
++    let shadowed_closure = || 1;
++    i = shadowed_closure();
++    let shadowed_closure = || 2;
++    i = shadowed_closure();
++
++    // don't lint here
++    let shadowed_closure = || 2;
++    i = shadowed_closure();
++    i = shadowed_closure();
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7c8865f1bd375e02a14c5ab99fadd78c88c0f83e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++error: closure called just once immediately after it was declared
++  --> $DIR/redundant_closure_call_late.rs:15:5
++   |
++LL |     i = redun_closure();
++   |     ^^^^^^^^^^^^^^^^^^^
++   |
++   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`
++
++error: closure called just once immediately after it was declared
++  --> $DIR/redundant_closure_call_late.rs:19:5
++   |
++LL |     i = shadowed_closure();
++   |     ^^^^^^^^^^^^^^^^^^^^^^
++
++error: closure called just once immediately after it was declared
++  --> $DIR/redundant_closure_call_late.rs:21:5
++   |
++LL |     i = shadowed_closure();
++   |     ^^^^^^^^^^^^^^^^^^^^^^
++
++error: aborting due to 3 previous errors
++
index ce8582d2b221cd21c891bfd38af0d20bfd073ec4,0000000000000000000000000000000000000000..adbff8af8d9ca087d2039df3d8b9855b2018ceaa
mode 100644,000000..100644
--- /dev/null
@@@ -1,165 -1,0 +1,168 @@@
 +// run-rustfix
 +
 +#![warn(clippy::all)]
 +#![warn(clippy::redundant_pattern_matching)]
 +#![allow(
 +    clippy::unit_arg,
 +    unused_must_use,
 +    clippy::needless_bool,
 +    clippy::match_like_matches_macro,
 +    deprecated
 +)]
 +
 +fn main() {
++    let result: Result<usize, usize> = Err(5);
++    if result.is_ok() {}
++
 +    if Ok::<i32, i32>(42).is_ok() {}
 +
 +    if Err::<i32, i32>(42).is_err() {}
 +
 +    if None::<()>.is_none() {}
 +
 +    if Some(42).is_some() {}
 +
 +    if Some(42).is_some() {
 +        foo();
 +    } else {
 +        bar();
 +    }
 +
 +    while Some(42).is_some() {}
 +
 +    while Some(42).is_none() {}
 +
 +    while None::<()>.is_none() {}
 +
 +    while Ok::<i32, i32>(10).is_ok() {}
 +
 +    while Ok::<i32, i32>(10).is_err() {}
 +
 +    let mut v = vec![1, 2, 3];
 +    while v.pop().is_some() {
 +        foo();
 +    }
 +
 +    if Ok::<i32, i32>(42).is_ok() {}
 +
 +    if Err::<i32, i32>(42).is_err() {}
 +
 +    if None::<i32>.is_none() {}
 +
 +    if Some(42).is_some() {}
 +
 +    if let Ok(x) = Ok::<i32, i32>(42) {
 +        println!("{}", x);
 +    }
 +
 +    Ok::<i32, i32>(42).is_ok();
 +
 +    Ok::<i32, i32>(42).is_err();
 +
 +    Err::<i32, i32>(42).is_err();
 +
 +    Err::<i32, i32>(42).is_ok();
 +
 +    Some(42).is_some();
 +
 +    None::<()>.is_none();
 +
 +    let _ = None::<()>.is_none();
 +
 +    let _ = if Ok::<usize, ()>(4).is_ok() { true } else { false };
 +
 +    let opt = Some(false);
 +    let x = if opt.is_some() { true } else { false };
 +    takes_bool(x);
 +
 +    issue5504();
 +    issue5697();
 +
 +    let _ = if gen_opt().is_some() {
 +        1
 +    } else if gen_opt().is_none() {
 +        2
 +    } else if gen_res().is_ok() {
 +        3
 +    } else if gen_res().is_err() {
 +        4
 +    } else {
 +        5
 +    };
 +}
 +
 +fn gen_opt() -> Option<()> {
 +    None
 +}
 +
 +fn gen_res() -> Result<(), ()> {
 +    Ok(())
 +}
 +
 +fn takes_bool(_: bool) {}
 +
 +fn foo() {}
 +
 +fn bar() {}
 +
 +macro_rules! m {
 +    () => {
 +        Some(42u32)
 +    };
 +}
 +
 +fn issue5504() {
 +    fn result_opt() -> Result<Option<i32>, i32> {
 +        Err(42)
 +    }
 +
 +    fn try_result_opt() -> Result<i32, i32> {
 +        while r#try!(result_opt()).is_some() {}
 +        if r#try!(result_opt()).is_some() {}
 +        Ok(42)
 +    }
 +
 +    try_result_opt();
 +
 +    if m!().is_some() {}
 +    while m!().is_some() {}
 +}
 +
 +// None of these should be linted because none of the suggested methods
 +// are `const fn` without toggling a feature.
 +const fn issue5697() {
 +    if let Ok(_) = Ok::<i32, i32>(42) {}
 +
 +    if let Err(_) = Err::<i32, i32>(42) {}
 +
 +    if let Some(_) = Some(42) {}
 +
 +    if let None = None::<()> {}
 +
 +    while let Ok(_) = Ok::<i32, i32>(10) {}
 +
 +    while let Err(_) = Ok::<i32, i32>(10) {}
 +
 +    while let Some(_) = Some(42) {}
 +
 +    while let None = None::<()> {}
 +
 +    match Ok::<i32, i32>(42) {
 +        Ok(_) => true,
 +        Err(_) => false,
 +    };
 +
 +    match Err::<i32, i32>(42) {
 +        Ok(_) => false,
 +        Err(_) => true,
 +    };
 +    match Some(42) {
 +        Some(_) => true,
 +        None => false,
 +    };
 +
 +    match None::<()> {
 +        Some(_) => false,
 +        None => true,
 +    };
 +}
index a3a9aa40e3b9c8ec7fd2b7a708c34bf5d93377ab,0000000000000000000000000000000000000000..4c2870e7803cb965d108e09ee3adbf3869e2e401
mode 100644,000000..100644
--- /dev/null
@@@ -1,186 -1,0 +1,189 @@@
 +// run-rustfix
 +
 +#![warn(clippy::all)]
 +#![warn(clippy::redundant_pattern_matching)]
 +#![allow(
 +    clippy::unit_arg,
 +    unused_must_use,
 +    clippy::needless_bool,
 +    clippy::match_like_matches_macro,
 +    deprecated
 +)]
 +
 +fn main() {
++    let result: Result<usize, usize> = Err(5);
++    if let Ok(_) = &result {}
++
 +    if let Ok(_) = Ok::<i32, i32>(42) {}
 +
 +    if let Err(_) = Err::<i32, i32>(42) {}
 +
 +    if let None = None::<()> {}
 +
 +    if let Some(_) = Some(42) {}
 +
 +    if let Some(_) = Some(42) {
 +        foo();
 +    } else {
 +        bar();
 +    }
 +
 +    while let Some(_) = Some(42) {}
 +
 +    while let None = Some(42) {}
 +
 +    while let None = None::<()> {}
 +
 +    while let Ok(_) = Ok::<i32, i32>(10) {}
 +
 +    while let Err(_) = Ok::<i32, i32>(10) {}
 +
 +    let mut v = vec![1, 2, 3];
 +    while let Some(_) = v.pop() {
 +        foo();
 +    }
 +
 +    if Ok::<i32, i32>(42).is_ok() {}
 +
 +    if Err::<i32, i32>(42).is_err() {}
 +
 +    if None::<i32>.is_none() {}
 +
 +    if Some(42).is_some() {}
 +
 +    if let Ok(x) = Ok::<i32, i32>(42) {
 +        println!("{}", x);
 +    }
 +
 +    match Ok::<i32, i32>(42) {
 +        Ok(_) => true,
 +        Err(_) => false,
 +    };
 +
 +    match Ok::<i32, i32>(42) {
 +        Ok(_) => false,
 +        Err(_) => true,
 +    };
 +
 +    match Err::<i32, i32>(42) {
 +        Ok(_) => false,
 +        Err(_) => true,
 +    };
 +
 +    match Err::<i32, i32>(42) {
 +        Ok(_) => true,
 +        Err(_) => false,
 +    };
 +
 +    match Some(42) {
 +        Some(_) => true,
 +        None => false,
 +    };
 +
 +    match None::<()> {
 +        Some(_) => false,
 +        None => true,
 +    };
 +
 +    let _ = match None::<()> {
 +        Some(_) => false,
 +        None => true,
 +    };
 +
 +    let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
 +
 +    let opt = Some(false);
 +    let x = if let Some(_) = opt { true } else { false };
 +    takes_bool(x);
 +
 +    issue5504();
 +    issue5697();
 +
 +    let _ = if let Some(_) = gen_opt() {
 +        1
 +    } else if let None = gen_opt() {
 +        2
 +    } else if let Ok(_) = gen_res() {
 +        3
 +    } else if let Err(_) = gen_res() {
 +        4
 +    } else {
 +        5
 +    };
 +}
 +
 +fn gen_opt() -> Option<()> {
 +    None
 +}
 +
 +fn gen_res() -> Result<(), ()> {
 +    Ok(())
 +}
 +
 +fn takes_bool(_: bool) {}
 +
 +fn foo() {}
 +
 +fn bar() {}
 +
 +macro_rules! m {
 +    () => {
 +        Some(42u32)
 +    };
 +}
 +
 +fn issue5504() {
 +    fn result_opt() -> Result<Option<i32>, i32> {
 +        Err(42)
 +    }
 +
 +    fn try_result_opt() -> Result<i32, i32> {
 +        while let Some(_) = r#try!(result_opt()) {}
 +        if let Some(_) = r#try!(result_opt()) {}
 +        Ok(42)
 +    }
 +
 +    try_result_opt();
 +
 +    if let Some(_) = m!() {}
 +    while let Some(_) = m!() {}
 +}
 +
 +// None of these should be linted because none of the suggested methods
 +// are `const fn` without toggling a feature.
 +const fn issue5697() {
 +    if let Ok(_) = Ok::<i32, i32>(42) {}
 +
 +    if let Err(_) = Err::<i32, i32>(42) {}
 +
 +    if let Some(_) = Some(42) {}
 +
 +    if let None = None::<()> {}
 +
 +    while let Ok(_) = Ok::<i32, i32>(10) {}
 +
 +    while let Err(_) = Ok::<i32, i32>(10) {}
 +
 +    while let Some(_) = Some(42) {}
 +
 +    while let None = None::<()> {}
 +
 +    match Ok::<i32, i32>(42) {
 +        Ok(_) => true,
 +        Err(_) => false,
 +    };
 +
 +    match Err::<i32, i32>(42) {
 +        Ok(_) => false,
 +        Err(_) => true,
 +    };
 +    match Some(42) {
 +        Some(_) => true,
 +        None => false,
 +    };
 +
 +    match None::<()> {
 +        Some(_) => false,
 +        None => true,
 +    };
 +}
index 25d1476062e7f599e7fe37dfddab9c1ce80bc1c0,0000000000000000000000000000000000000000..d3c9ceaa3d7c18b0bee5a9cd15e1e451c2f1885d
mode 100644,000000..100644
--- /dev/null
@@@ -1,194 -1,0 +1,200 @@@
-   --> $DIR/redundant_pattern_matching.rs:14:12
 +error: redundant pattern matching, consider using `is_ok()`
- LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
-    |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
++  --> $DIR/redundant_pattern_matching.rs:15:12
 +   |
-   --> $DIR/redundant_pattern_matching.rs:16:12
++LL |     if let Ok(_) = &result {}
++   |     -------^^^^^---------- help: try this: `if result.is_ok()`
 +   |
 +   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 +
++error: redundant pattern matching, consider using `is_ok()`
++  --> $DIR/redundant_pattern_matching.rs:17:12
++   |
++LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
++   |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
++
 +error: redundant pattern matching, consider using `is_err()`
-   --> $DIR/redundant_pattern_matching.rs:18:12
++  --> $DIR/redundant_pattern_matching.rs:19:12
 +   |
 +LL |     if let Err(_) = Err::<i32, i32>(42) {}
 +   |     -------^^^^^^---------------------- help: try this: `if Err::<i32, i32>(42).is_err()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:20:12
++  --> $DIR/redundant_pattern_matching.rs:21:12
 +   |
 +LL |     if let None = None::<()> {}
 +   |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:22:12
++  --> $DIR/redundant_pattern_matching.rs:23:12
 +   |
 +LL |     if let Some(_) = Some(42) {}
 +   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:28:15
++  --> $DIR/redundant_pattern_matching.rs:25:12
 +   |
 +LL |     if let Some(_) = Some(42) {
 +   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:30:15
++  --> $DIR/redundant_pattern_matching.rs:31:15
 +   |
 +LL |     while let Some(_) = Some(42) {}
 +   |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:32:15
++  --> $DIR/redundant_pattern_matching.rs:33:15
 +   |
 +LL |     while let None = Some(42) {}
 +   |     ----------^^^^----------- help: try this: `while Some(42).is_none()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:34:15
++  --> $DIR/redundant_pattern_matching.rs:35:15
 +   |
 +LL |     while let None = None::<()> {}
 +   |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
 +
 +error: redundant pattern matching, consider using `is_ok()`
-   --> $DIR/redundant_pattern_matching.rs:36:15
++  --> $DIR/redundant_pattern_matching.rs:37:15
 +   |
 +LL |     while let Ok(_) = Ok::<i32, i32>(10) {}
 +   |     ----------^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_ok()`
 +
 +error: redundant pattern matching, consider using `is_err()`
-   --> $DIR/redundant_pattern_matching.rs:39:15
++  --> $DIR/redundant_pattern_matching.rs:39:15
 +   |
 +LL |     while let Err(_) = Ok::<i32, i32>(10) {}
 +   |     ----------^^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_err()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:55:5
++  --> $DIR/redundant_pattern_matching.rs:42:15
 +   |
 +LL |     while let Some(_) = v.pop() {
 +   |     ----------^^^^^^^---------- help: try this: `while v.pop().is_some()`
 +
 +error: redundant pattern matching, consider using `is_ok()`
-   --> $DIR/redundant_pattern_matching.rs:60:5
++  --> $DIR/redundant_pattern_matching.rs:58:5
 +   |
 +LL | /     match Ok::<i32, i32>(42) {
 +LL | |         Ok(_) => true,
 +LL | |         Err(_) => false,
 +LL | |     };
 +   | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 +
 +error: redundant pattern matching, consider using `is_err()`
-   --> $DIR/redundant_pattern_matching.rs:65:5
++  --> $DIR/redundant_pattern_matching.rs:63:5
 +   |
 +LL | /     match Ok::<i32, i32>(42) {
 +LL | |         Ok(_) => false,
 +LL | |         Err(_) => true,
 +LL | |     };
 +   | |_____^ help: try this: `Ok::<i32, i32>(42).is_err()`
 +
 +error: redundant pattern matching, consider using `is_err()`
-   --> $DIR/redundant_pattern_matching.rs:70:5
++  --> $DIR/redundant_pattern_matching.rs:68:5
 +   |
 +LL | /     match Err::<i32, i32>(42) {
 +LL | |         Ok(_) => false,
 +LL | |         Err(_) => true,
 +LL | |     };
 +   | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 +
 +error: redundant pattern matching, consider using `is_ok()`
-   --> $DIR/redundant_pattern_matching.rs:75:5
++  --> $DIR/redundant_pattern_matching.rs:73:5
 +   |
 +LL | /     match Err::<i32, i32>(42) {
 +LL | |         Ok(_) => true,
 +LL | |         Err(_) => false,
 +LL | |     };
 +   | |_____^ help: try this: `Err::<i32, i32>(42).is_ok()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:80:5
++  --> $DIR/redundant_pattern_matching.rs:78:5
 +   |
 +LL | /     match Some(42) {
 +LL | |         Some(_) => true,
 +LL | |         None => false,
 +LL | |     };
 +   | |_____^ help: try this: `Some(42).is_some()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:85:13
++  --> $DIR/redundant_pattern_matching.rs:83:5
 +   |
 +LL | /     match None::<()> {
 +LL | |         Some(_) => false,
 +LL | |         None => true,
 +LL | |     };
 +   | |_____^ help: try this: `None::<()>.is_none()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:90:20
++  --> $DIR/redundant_pattern_matching.rs:88:13
 +   |
 +LL |       let _ = match None::<()> {
 +   |  _____________^
 +LL | |         Some(_) => false,
 +LL | |         None => true,
 +LL | |     };
 +   | |_____^ help: try this: `None::<()>.is_none()`
 +
 +error: redundant pattern matching, consider using `is_ok()`
-   --> $DIR/redundant_pattern_matching.rs:93:20
++  --> $DIR/redundant_pattern_matching.rs:93:20
 +   |
 +LL |     let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
 +   |             -------^^^^^--------------------- help: try this: `if Ok::<usize, ()>(4).is_ok()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:99:20
++  --> $DIR/redundant_pattern_matching.rs:96:20
 +   |
 +LL |     let x = if let Some(_) = opt { true } else { false };
 +   |             -------^^^^^^^------ help: try this: `if opt.is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:101:19
++  --> $DIR/redundant_pattern_matching.rs:102:20
 +   |
 +LL |     let _ = if let Some(_) = gen_opt() {
 +   |             -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
 +
 +error: redundant pattern matching, consider using `is_none()`
-   --> $DIR/redundant_pattern_matching.rs:103:19
++  --> $DIR/redundant_pattern_matching.rs:104:19
 +   |
 +LL |     } else if let None = gen_opt() {
 +   |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
 +
 +error: redundant pattern matching, consider using `is_ok()`
-   --> $DIR/redundant_pattern_matching.rs:105:19
++  --> $DIR/redundant_pattern_matching.rs:106:19
 +   |
 +LL |     } else if let Ok(_) = gen_res() {
 +   |            -------^^^^^------------ help: try this: `if gen_res().is_ok()`
 +
 +error: redundant pattern matching, consider using `is_err()`
-   --> $DIR/redundant_pattern_matching.rs:138:19
++  --> $DIR/redundant_pattern_matching.rs:108:19
 +   |
 +LL |     } else if let Err(_) = gen_res() {
 +   |            -------^^^^^^------------ help: try this: `if gen_res().is_err()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:139:16
++  --> $DIR/redundant_pattern_matching.rs:141:19
 +   |
 +LL |         while let Some(_) = r#try!(result_opt()) {}
 +   |         ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:145:12
++  --> $DIR/redundant_pattern_matching.rs:142:16
 +   |
 +LL |         if let Some(_) = r#try!(result_opt()) {}
 +   |         -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
-   --> $DIR/redundant_pattern_matching.rs:146:15
++  --> $DIR/redundant_pattern_matching.rs:148:12
 +   |
 +LL |     if let Some(_) = m!() {}
 +   |     -------^^^^^^^------- help: try this: `if m!().is_some()`
 +
 +error: redundant pattern matching, consider using `is_some()`
- error: aborting due to 28 previous errors
++  --> $DIR/redundant_pattern_matching.rs:149:15
 +   |
 +LL |     while let Some(_) = m!() {}
 +   |     ----------^^^^^^^------- help: try this: `while m!().is_some()`
 +
++error: aborting due to 29 previous errors
 +
index 7fa58cf76499b8016b9c062a647ef041cc5d2444,0000000000000000000000000000000000000000..8a831375b412dacdd4f705df37df47b507ca5823
mode 100644,000000..100644
--- /dev/null
@@@ -1,138 -1,0 +1,138 @@@
- error: `x` is shadowed by `y`
 +error: `x` is shadowed by itself in `&mut x`
 +  --> $DIR/shadow.rs:26:5
 +   |
 +LL |     let x = &mut x;
 +   |     ^^^^^^^^^^^^^^^
 +   |
 +   = note: `-D clippy::shadow-same` implied by `-D warnings`
 +note: previous binding is here
 +  --> $DIR/shadow.rs:25:13
 +   |
 +LL |     let mut x = 1;
 +   |             ^
 +
 +error: `x` is shadowed by itself in `{ x }`
 +  --> $DIR/shadow.rs:27:5
 +   |
 +LL |     let x = { x };
 +   |     ^^^^^^^^^^^^^^
 +   |
 +note: previous binding is here
 +  --> $DIR/shadow.rs:26:9
 +   |
 +LL |     let x = &mut x;
 +   |         ^
 +
 +error: `x` is shadowed by itself in `(&*x)`
 +  --> $DIR/shadow.rs:28:5
 +   |
 +LL |     let x = (&*x);
 +   |     ^^^^^^^^^^^^^^
 +   |
 +note: previous binding is here
 +  --> $DIR/shadow.rs:27:9
 +   |
 +LL |     let x = { x };
 +   |         ^
 +
 +error: `x` is shadowed by `{ *x + 1 }` which reuses the original value
 +  --> $DIR/shadow.rs:29:9
 +   |
 +LL |     let x = { *x + 1 };
 +   |         ^
 +   |
 +   = note: `-D clippy::shadow-reuse` implied by `-D warnings`
 +note: initialization happens here
 +  --> $DIR/shadow.rs:29:13
 +   |
 +LL |     let x = { *x + 1 };
 +   |             ^^^^^^^^^^
 +note: previous binding is here
 +  --> $DIR/shadow.rs:28:9
 +   |
 +LL |     let x = (&*x);
 +   |         ^
 +
 +error: `x` is shadowed by `id(x)` which reuses the original value
 +  --> $DIR/shadow.rs:30:9
 +   |
 +LL |     let x = id(x);
 +   |         ^
 +   |
 +note: initialization happens here
 +  --> $DIR/shadow.rs:30:13
 +   |
 +LL |     let x = id(x);
 +   |             ^^^^^
 +note: previous binding is here
 +  --> $DIR/shadow.rs:29:9
 +   |
 +LL |     let x = { *x + 1 };
 +   |         ^
 +
 +error: `x` is shadowed by `(1, x)` which reuses the original value
 +  --> $DIR/shadow.rs:31:9
 +   |
 +LL |     let x = (1, x);
 +   |         ^
 +   |
 +note: initialization happens here
 +  --> $DIR/shadow.rs:31:13
 +   |
 +LL |     let x = (1, x);
 +   |             ^^^^^^
 +note: previous binding is here
 +  --> $DIR/shadow.rs:30:9
 +   |
 +LL |     let x = id(x);
 +   |         ^
 +
 +error: `x` is shadowed by `first(x)` which reuses the original value
 +  --> $DIR/shadow.rs:32:9
 +   |
 +LL |     let x = first(x);
 +   |         ^
 +   |
 +note: initialization happens here
 +  --> $DIR/shadow.rs:32:13
 +   |
 +LL |     let x = first(x);
 +   |             ^^^^^^^^
 +note: previous binding is here
 +  --> $DIR/shadow.rs:31:9
 +   |
 +LL |     let x = (1, x);
 +   |         ^
 +
++error: `x` is being shadowed
 +  --> $DIR/shadow.rs:34:9
 +   |
 +LL |     let x = y;
 +   |         ^
 +   |
 +   = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
 +note: initialization happens here
 +  --> $DIR/shadow.rs:34:13
 +   |
 +LL |     let x = y;
 +   |             ^
 +note: previous binding is here
 +  --> $DIR/shadow.rs:32:9
 +   |
 +LL |     let x = first(x);
 +   |         ^
 +
 +error: `x` shadows a previous declaration
 +  --> $DIR/shadow.rs:36:5
 +   |
 +LL |     let x;
 +   |     ^^^^^^
 +   |
 +note: previous binding is here
 +  --> $DIR/shadow.rs:34:9
 +   |
 +LL |     let x = y;
 +   |         ^
 +
 +error: aborting due to 9 previous errors
 +
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bdb4710cc69723ca836eef19c18d2f4b06151167
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,36 @@@
++#![warn(clippy::unit_return_expecting_ord)]
++#![allow(clippy::needless_return)]
++#![allow(clippy::unused_unit)]
++#![feature(is_sorted)]
++
++struct Struct {
++    field: isize,
++}
++
++fn double(i: isize) -> isize {
++    i * 2
++}
++
++fn unit(_i: isize) {}
++
++fn main() {
++    let mut structs = vec![Struct { field: 2 }, Struct { field: 1 }];
++    structs.sort_by_key(|s| {
++        double(s.field);
++    });
++    structs.sort_by_key(|s| double(s.field));
++    structs.is_sorted_by_key(|s| {
++        double(s.field);
++    });
++    structs.is_sorted_by_key(|s| {
++        if s.field > 0 {
++            ()
++        } else {
++            return ();
++        }
++    });
++    structs.sort_by_key(|s| {
++        return double(s.field);
++    });
++    structs.sort_by_key(|s| unit(s.field));
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e63d58746090b73d36947e98efb4de0963b88dc7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++error: this closure returns the unit type which also implements Ord
++  --> $DIR/unit_return_expecting_ord.rs:18:25
++   |
++LL |     structs.sort_by_key(|s| {
++   |                         ^^^
++   |
++   = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings`
++help: probably caused by this trailing semicolon
++  --> $DIR/unit_return_expecting_ord.rs:19:24
++   |
++LL |         double(s.field);
++   |                        ^
++
++error: this closure returns the unit type which also implements PartialOrd
++  --> $DIR/unit_return_expecting_ord.rs:22:30
++   |
++LL |     structs.is_sorted_by_key(|s| {
++   |                              ^^^
++   |
++help: probably caused by this trailing semicolon
++  --> $DIR/unit_return_expecting_ord.rs:23:24
++   |
++LL |         double(s.field);
++   |                        ^
++
++error: this closure returns the unit type which also implements PartialOrd
++  --> $DIR/unit_return_expecting_ord.rs:25:30
++   |
++LL |     structs.is_sorted_by_key(|s| {
++   |                              ^^^
++
++error: this closure returns the unit type which also implements Ord
++  --> $DIR/unit_return_expecting_ord.rs:35:25
++   |
++LL |     structs.sort_by_key(|s| unit(s.field));
++   |                         ^^^
++
++error: aborting due to 4 previous errors
++
index fdd4bc581f305a21281c8d6da8e642cc54dbf455,0000000000000000000000000000000000000000..813cdaecaa91a8864f8f285a8f3c3130c0cb5bc4
mode 100644,000000..100644
--- /dev/null
@@@ -1,58 -1,0 +1,67 @@@
 +// run-rustfix
 +
 +#![deny(clippy::useless_conversion)]
 +
 +fn test_generic<T: Copy>(val: T) -> T {
 +    let _ = val;
 +    val
 +}
 +
 +fn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {
 +    // ok
 +    let _: i32 = val.into();
 +    let _: U = val.into();
 +    let _ = U::from(val);
 +}
 +
 +fn test_questionmark() -> Result<(), ()> {
 +    {
 +        let _: i32 = 0i32;
 +        Ok(Ok(()))
 +    }??;
 +    Ok(())
 +}
 +
 +fn test_issue_3913() -> Result<(), std::io::Error> {
 +    use std::fs;
 +    use std::path::Path;
 +
 +    let path = Path::new(".");
 +    for _ in fs::read_dir(path)? {}
 +
 +    Ok(())
 +}
 +
++fn test_issue_5833() -> Result<(), ()> {
++    let text = "foo\r\nbar\n\nbaz\n";
++    let lines = text.lines();
++    if Some("ok") == lines.into_iter().next() {}
++
++    Ok(())
++}
++
 +fn main() {
 +    test_generic(10i32);
 +    test_generic2::<i32, i32>(10i32);
 +    test_questionmark().unwrap();
 +    test_issue_3913().unwrap();
++    test_issue_5833().unwrap();
 +
 +    let _: String = "foo".into();
 +    let _: String = From::from("foo");
 +    let _ = String::from("foo");
 +    #[allow(clippy::useless_conversion)]
 +    {
 +        let _: String = "foo".into();
 +        let _ = String::from("foo");
 +        let _ = "".lines().into_iter();
 +    }
 +
 +    let _: String = "foo".to_string();
 +    let _: String = "foo".to_string();
 +    let _ = "foo".to_string();
 +    let _ = format!("A: {:04}", 123);
 +    let _ = "".lines();
 +    let _ = vec![1, 2, 3].into_iter();
 +    let _: String = format!("Hello {}", "world");
 +}
index 4cae745e7c0211f2a886c21760451f459192fd59,0000000000000000000000000000000000000000..540fea23b36b98e0061e4a7566b0666e04254516
mode 100644,000000..100644
--- /dev/null
@@@ -1,58 -1,0 +1,67 @@@
 +// run-rustfix
 +
 +#![deny(clippy::useless_conversion)]
 +
 +fn test_generic<T: Copy>(val: T) -> T {
 +    let _ = T::from(val);
 +    val.into()
 +}
 +
 +fn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {
 +    // ok
 +    let _: i32 = val.into();
 +    let _: U = val.into();
 +    let _ = U::from(val);
 +}
 +
 +fn test_questionmark() -> Result<(), ()> {
 +    {
 +        let _: i32 = 0i32.into();
 +        Ok(Ok(()))
 +    }??;
 +    Ok(())
 +}
 +
 +fn test_issue_3913() -> Result<(), std::io::Error> {
 +    use std::fs;
 +    use std::path::Path;
 +
 +    let path = Path::new(".");
 +    for _ in fs::read_dir(path)? {}
 +
 +    Ok(())
 +}
 +
++fn test_issue_5833() -> Result<(), ()> {
++    let text = "foo\r\nbar\n\nbaz\n";
++    let lines = text.lines();
++    if Some("ok") == lines.into_iter().next() {}
++
++    Ok(())
++}
++
 +fn main() {
 +    test_generic(10i32);
 +    test_generic2::<i32, i32>(10i32);
 +    test_questionmark().unwrap();
 +    test_issue_3913().unwrap();
++    test_issue_5833().unwrap();
 +
 +    let _: String = "foo".into();
 +    let _: String = From::from("foo");
 +    let _ = String::from("foo");
 +    #[allow(clippy::useless_conversion)]
 +    {
 +        let _: String = "foo".into();
 +        let _ = String::from("foo");
 +        let _ = "".lines().into_iter();
 +    }
 +
 +    let _: String = "foo".to_string().into();
 +    let _: String = From::from("foo".to_string());
 +    let _ = String::from("foo".to_string());
 +    let _ = String::from(format!("A: {:04}", 123));
 +    let _ = "".lines().into_iter();
 +    let _ = vec![1, 2, 3].into_iter().into_iter();
 +    let _: String = format!("Hello {}", "world").into();
 +}
index 84ec53702788c12592f02387ec2deaef7f5c36c0,0000000000000000000000000000000000000000..b958b0354520326577fdfcf17d56e932a6b813df
mode 100644,000000..100644
--- /dev/null
@@@ -1,68 -1,0 +1,68 @@@
-   --> $DIR/useless_conversion.rs:51:21
 +error: useless conversion to the same type
 +  --> $DIR/useless_conversion.rs:6:13
 +   |
 +LL |     let _ = T::from(val);
 +   |             ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`
 +   |
 +note: the lint level is defined here
 +  --> $DIR/useless_conversion.rs:3:9
 +   |
 +LL | #![deny(clippy::useless_conversion)]
 +   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: useless conversion to the same type
 +  --> $DIR/useless_conversion.rs:7:5
 +   |
 +LL |     val.into()
 +   |     ^^^^^^^^^^ help: consider removing `.into()`: `val`
 +
 +error: useless conversion to the same type
 +  --> $DIR/useless_conversion.rs:19:22
 +   |
 +LL |         let _: i32 = 0i32.into();
 +   |                      ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:52:21
++  --> $DIR/useless_conversion.rs:60:21
 +   |
 +LL |     let _: String = "foo".to_string().into();
 +   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:53:13
++  --> $DIR/useless_conversion.rs:61:21
 +   |
 +LL |     let _: String = From::from("foo".to_string());
 +   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:54:13
++  --> $DIR/useless_conversion.rs:62:13
 +   |
 +LL |     let _ = String::from("foo".to_string());
 +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:55:13
++  --> $DIR/useless_conversion.rs:63:13
 +   |
 +LL |     let _ = String::from(format!("A: {:04}", 123));
 +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:56:13
++  --> $DIR/useless_conversion.rs:64:13
 +   |
 +LL |     let _ = "".lines().into_iter();
 +   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
 +
 +error: useless conversion to the same type
-   --> $DIR/useless_conversion.rs:57:21
++  --> $DIR/useless_conversion.rs:65:13
 +   |
 +LL |     let _ = vec![1, 2, 3].into_iter().into_iter();
 +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
 +
 +error: useless conversion to the same type
++  --> $DIR/useless_conversion.rs:66:21
 +   |
 +LL |     let _: String = format!("Hello {}", "world").into();
 +   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
 +
 +error: aborting due to 10 previous errors
 +
index 0263e2f5f20c113920111ee6b41e62f89a1944ed,0000000000000000000000000000000000000000..7ed27439ec6e4432372224dd696d485024918b96
mode 100644,000000..100644
--- /dev/null
@@@ -1,15 -1,0 +1,15 @@@
-     // applicable here, but only implemented for integer litterals for now
 +#![warn(clippy::vec_resize_to_zero)]
 +
 +fn main() {
 +    // applicable here
 +    vec![1, 2, 3, 4, 5].resize(0, 5);
 +
 +    // not applicable
 +    vec![1, 2, 3, 4, 5].resize(2, 5);
 +
++    // applicable here, but only implemented for integer literals for now
 +    vec!["foo", "bar", "baz"].resize(0, "bar");
 +
 +    // not applicable
 +    vec!["foo", "bar", "baz"].resize(2, "bar")
 +}