]> git.lizzy.rs Git - rust.git/commitdiff
Merge commit '1fcc74cc9e03bc91eaa80ecf92976b0b14b3aeb6' into clippyup
authorflip1995 <philipp.krones@embecosm.com>
Sat, 2 Jan 2021 15:29:43 +0000 (16:29 +0100)
committerflip1995 <philipp.krones@embecosm.com>
Sat, 2 Jan 2021 15:29:43 +0000 (16:29 +0100)
39 files changed:
1  2 
src/tools/clippy/.github/ISSUE_TEMPLATE/false_negative.md
src/tools/clippy/.github/ISSUE_TEMPLATE/false_positive.md
src/tools/clippy/.github/workflows/clippy.yml
src/tools/clippy/CHANGELOG.md
src/tools/clippy/Cargo.toml
src/tools/clippy/README.md
src/tools/clippy/clippy_dev/src/ra_setup.rs
src/tools/clippy/clippy_lints/Cargo.toml
src/tools/clippy/clippy_lints/src/default.rs
src/tools/clippy/clippy_lints/src/from_over_into.rs
src/tools/clippy/clippy_lints/src/large_enum_variant.rs
src/tools/clippy/clippy_lints/src/lib.rs
src/tools/clippy/clippy_lints/src/macro_use.rs
src/tools/clippy/clippy_lints/src/manual_async_fn.rs
src/tools/clippy/clippy_lints/src/map_err_ignore.rs
src/tools/clippy/clippy_lints/src/ptr.rs
src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
src/tools/clippy/clippy_lints/src/unused_unit.rs
src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
src/tools/clippy/clippy_lints/src/utils/mod.rs
src/tools/clippy/clippy_lints/src/utils/ptr.rs
src/tools/clippy/rust-toolchain
src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
src/tools/clippy/tests/ui/field_reassign_with_default.rs
src/tools/clippy/tests/ui/field_reassign_with_default.stderr
src/tools/clippy/tests/ui/from_over_into.rs
src/tools/clippy/tests/ui/from_over_into.stderr
src/tools/clippy/tests/ui/large_enum_variant.rs
src/tools/clippy/tests/ui/large_enum_variant.stderr
src/tools/clippy/tests/ui/map_err.stderr
src/tools/clippy/tests/ui/min_rust_version_attr.rs
src/tools/clippy/tests/ui/min_rust_version_attr.stderr
src/tools/clippy/tests/ui/ptr_arg.rs
src/tools/clippy/tests/ui/ptr_arg.stderr
src/tools/clippy/tests/ui/unused_unit.fixed
src/tools/clippy/tests/ui/unused_unit.rs
src/tools/clippy/tests/ui/unused_unit.stderr
src/tools/clippy/tests/versioncheck.rs
src/tools/clippy/util/gh-pages/index.html

index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f46828fec91b25594d06952716e4357053ab4df4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,35 @@@
++---
++name: Bug Report (False Negative)
++about: Create a bug report about missing warnings from a lint
++labels: L-bug, L-false-negative
++---
++<!--
++Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
++along with any information you feel relevant to replicating the bug.
++-->
++Lint name:
++
++
++I tried this code:
++
++```rust
++<code>
++```
++
++I expected to see this happen: *explanation*
++
++Instead, this happened: *explanation*
++
++### Meta
++
++- `cargo clippy -V`: e.g. clippy 0.0.212 (f455e46 2020-06-20)
++- `rustc -Vv`:
++  ```
++  rustc 1.46.0-nightly (f455e46ea 2020-06-20)
++  binary: rustc
++  commit-hash: f455e46eae1a227d735091091144601b467e1565
++  commit-date: 2020-06-20
++  host: x86_64-unknown-linux-gnu
++  release: 1.46.0-nightly
++  LLVM version: 10.0
++  ```
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..92a7373fc27d51f372cd389d1952800635400535
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,35 @@@
++---
++name: Bug Report (False Positive)
++about: Create a bug report about a wrongly emitted lint warning
++labels: L-bug, L-false-positive
++---
++<!--
++Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
++along with any information you feel relevant to replicating the bug.
++-->
++Lint name:
++
++
++I tried this code:
++
++```rust
++<code>
++```
++
++I expected to see this happen: *explanation*
++
++Instead, this happened: *explanation*
++
++### Meta
++
++- `cargo clippy -V`: e.g. clippy 0.0.212 (f455e46 2020-06-20)
++- `rustc -Vv`:
++  ```
++  rustc 1.46.0-nightly (f455e46ea 2020-06-20)
++  binary: rustc
++  commit-hash: f455e46eae1a227d735091091144601b467e1565
++  commit-date: 2020-06-20
++  host: x86_64-unknown-linux-gnu
++  release: 1.46.0-nightly
++  LLVM version: 10.0
++  ```
index 530e60001f726b1a7525c42c667aa4b0684b4faf,0000000000000000000000000000000000000000..9d5e12aac5f7b73701396d4703666d75cd4e12e8
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,85 @@@
 +name: Clippy Test
 +
 +on:
 +  push:
 +    # Ignore bors branches, since they are covered by `clippy_bors.yml`
 +    branches-ignore:
 +      - auto
 +      - try
 +    # Don't run Clippy tests, when only textfiles were modified
 +    paths-ignore:
 +    - 'COPYRIGHT'
 +    - 'LICENSE-*'
 +    - '**.md'
 +    - '**.txt'
 +  pull_request:
 +    # Don't run Clippy tests, when only textfiles were modified
 +    paths-ignore:
 +    - 'COPYRIGHT'
 +    - 'LICENSE-*'
 +    - '**.md'
 +    - '**.txt'
 +
 +env:
 +  RUST_BACKTRACE: 1
 +  CARGO_TARGET_DIR: '${{ github.workspace }}/target'
 +  NO_FMT_TEST: 1
 +
 +jobs:
 +  base:
 +    runs-on: ubuntu-latest
 +
 +    steps:
 +    # Setup
 +    - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
 +      with:
 +        github_token: "${{ secrets.github_token }}"
 +
 +    - name: Checkout
 +      uses: actions/checkout@v2.3.3
 +
 +    - name: Install toolchain
 +      run: rustup show active-toolchain
 +
 +    # Run
 +    - name: Set LD_LIBRARY_PATH (Linux)
 +      run: |
 +        SYSROOT=$(rustc --print sysroot)
 +        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
 +
 +    - name: Build
 +      run: cargo build --features deny-warnings,internal-lints
 +
++    - name: Test "--fix -Zunstable-options"
++      run: cargo run --features deny-warnings,internal-lints --bin cargo-clippy -- clippy --fix -Zunstable-options
++
 +    - name: Test
 +      run: cargo test --features deny-warnings,internal-lints
 +
 +    - name: Test clippy_lints
 +      run: cargo test --features deny-warnings,internal-lints
 +      working-directory: clippy_lints
 +
 +    - name: Test rustc_tools_util
 +      run: cargo test --features deny-warnings
 +      working-directory: rustc_tools_util
 +
 +    - name: Test clippy_dev
 +      run: cargo test --features deny-warnings
 +      working-directory: clippy_dev
 +
 +    - name: Test cargo-clippy
 +      run: ../target/debug/cargo-clippy
 +      working-directory: clippy_workspace_tests
 +
 +    - name: Test clippy-driver
 +      run: bash .github/driver.sh
 +      env:
 +        OS: ${{ runner.os }}
 +
 +    - name: Test cargo dev new lint
 +      run: |
 +        cargo dev new_lint --name new_early_pass --pass early
 +        cargo dev new_lint --name new_late_pass --pass late
 +        cargo check
 +        git reset --hard HEAD
index af3b1c1db2aedb79bcb117754f4e1f82fb4d2298,0000000000000000000000000000000000000000..de8da99cdee12385b27570510ace9d77e5c54979
mode 100644,000000..100644
--- /dev/null
@@@ -1,2176 -1,0 +1,2177 @@@
 +# 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
 +
 +[b20d4c1...master](https://github.com/rust-lang/rust-clippy/compare/b20d4c1...master)
 +
 +## Rust 1.49
 +
 +Current beta, release 2020-12-31
 +
 +[e636b88...b20d4c1](https://github.com/rust-lang/rust-clippy/compare/e636b88...b20d4c1)
 +
 +### New Lints
 +
 +* [`field_reassign_with_default`] [#5911](https://github.com/rust-lang/rust-clippy/pull/5911)
 +* [`await_holding_refcell_ref`] [#6029](https://github.com/rust-lang/rust-clippy/pull/6029)
 +* [`disallowed_method`] [#6081](https://github.com/rust-lang/rust-clippy/pull/6081)
 +* [`inline_asm_x86_att_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
 +* [`inline_asm_x86_intel_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
 +* [`from_iter_instead_of_collect`] [#6101](https://github.com/rust-lang/rust-clippy/pull/6101)
 +* [`mut_mutex_lock`] [#6103](https://github.com/rust-lang/rust-clippy/pull/6103)
 +* [`single_element_loop`] [#6109](https://github.com/rust-lang/rust-clippy/pull/6109)
 +* [`manual_unwrap_or`] [#6123](https://github.com/rust-lang/rust-clippy/pull/6123)
 +* [`large_types_passed_by_value`] [#6135](https://github.com/rust-lang/rust-clippy/pull/6135)
 +* [`result_unit_err`] [#6157](https://github.com/rust-lang/rust-clippy/pull/6157)
 +* [`ref_option_ref`] [#6165](https://github.com/rust-lang/rust-clippy/pull/6165)
 +* [`manual_range_contains`] [#6177](https://github.com/rust-lang/rust-clippy/pull/6177)
 +* [`unusual_byte_groupings`] [#6183](https://github.com/rust-lang/rust-clippy/pull/6183)
 +* [`comparison_to_empty`] [#6226](https://github.com/rust-lang/rust-clippy/pull/6226)
 +* [`map_collect_result_unit`] [#6227](https://github.com/rust-lang/rust-clippy/pull/6227)
 +* [`manual_ok_or`] [#6233](https://github.com/rust-lang/rust-clippy/pull/6233)
 +
 +### Moves and Deprecations
 +
 +* Rename `single_char_push_str` to [`single_char_add_str`]
 +  [#6037](https://github.com/rust-lang/rust-clippy/pull/6037)
 +* Rename `zero_width_space` to [`invisible_characters`]
 +  [#6105](https://github.com/rust-lang/rust-clippy/pull/6105)
 +* Deprecate [`drop_bounds`] (uplifted)
 +  [#6111](https://github.com/rust-lang/rust-clippy/pull/6111)
 +* Move [`string_lit_as_bytes`] to `nursery`
 +  [#6117](https://github.com/rust-lang/rust-clippy/pull/6117)
 +* Move [`rc_buffer`] to `restriction`
 +  [#6128](https://github.com/rust-lang/rust-clippy/pull/6128)
 +
 +### Enhancements
 +
 +* [`manual_memcpy`]: Also lint when there are loop counters (and produce a
 +  reliable suggestion)
 +  [#5727](https://github.com/rust-lang/rust-clippy/pull/5727)
 +* [`single_char_add_str`]: Also lint on `String::insert_str`
 +  [#6037](https://github.com/rust-lang/rust-clippy/pull/6037)
 +* [`invisible_characters`]: Also lint the characters `\u{AD}` and `\u{2060}`
 +  [#6105](https://github.com/rust-lang/rust-clippy/pull/6105)
 +* [`eq_op`]: Also lint on the `assert_*!` macro family
 +  [#6167](https://github.com/rust-lang/rust-clippy/pull/6167)
 +* [`items_after_statements`]: Also lint in local macro expansions
 +  [#6176](https://github.com/rust-lang/rust-clippy/pull/6176)
 +* [`unnecessary_cast`]: Also lint casts on integer and float literals
 +  [#6187](https://github.com/rust-lang/rust-clippy/pull/6187)
 +* [`manual_unwrap_or`]: Also lint `Result::unwrap_or`
 +  [#6190](https://github.com/rust-lang/rust-clippy/pull/6190)
 +* [`match_like_matches_macro`]: Also lint when `match` has more than two arms
 +  [#6216](https://github.com/rust-lang/rust-clippy/pull/6216)
 +* [`integer_arithmetic`]: Better handle `/` an `%` operators
 +  [#6229](https://github.com/rust-lang/rust-clippy/pull/6229)
 +
 +### False Positive Fixes
 +
 +* [`needless_lifetimes`]: Bail out if the function has a `where` clause with the
 +  lifetime [#5978](https://github.com/rust-lang/rust-clippy/pull/5978)
 +* [`explicit_counter_loop`]: No longer lints, when loop counter is used after it
 +  is incremented [#6076](https://github.com/rust-lang/rust-clippy/pull/6076)
 +* [`or_fun_call`]: Revert changes addressing the handling of `const fn`
 +  [#6077](https://github.com/rust-lang/rust-clippy/pull/6077)
 +* [`needless_range_loop`]: No longer lints, when the iterable is used in the
 +  range [#6102](https://github.com/rust-lang/rust-clippy/pull/6102)
 +* [`inconsistent_digit_grouping`]: Fix bug when using floating point exponent
 +  [#6104](https://github.com/rust-lang/rust-clippy/pull/6104)
 +* [`mistyped_literal_suffixes`]: No longer lints on the fractional part of a
 +  float (e.g. `713.32_64`)
 +  [#6114](https://github.com/rust-lang/rust-clippy/pull/6114)
 +* [`invalid_regex`]: No longer lint on unicode characters within `bytes::Regex`
 +  [#6132](https://github.com/rust-lang/rust-clippy/pull/6132)
 +* [`boxed_local`]: No longer lints on `extern fn` arguments
 +  [#6133](https://github.com/rust-lang/rust-clippy/pull/6133)
 +* [`needless_lifetimes`]: Fix regression, where lifetime is used in `where`
 +  clause [#6198](https://github.com/rust-lang/rust-clippy/pull/6198)
 +
 +### Suggestion Fixes/Improvements
 +
 +* [`unnecessary_sort_by`]: Avoid dereferencing the suggested closure parameter
 +  [#6078](https://github.com/rust-lang/rust-clippy/pull/6078)
 +* [`needless_arbitrary_self_type`]: Correctly handle expanded code
 +  [#6093](https://github.com/rust-lang/rust-clippy/pull/6093)
 +* [`useless_format`]: Preserve raw strings in suggestion
 +  [#6151](https://github.com/rust-lang/rust-clippy/pull/6151)
 +* [`empty_loop`]: Suggest alternatives
 +  [#6162](https://github.com/rust-lang/rust-clippy/pull/6162)
 +* [`borrowed_box`]: Correctly add parentheses in suggestion
 +  [#6200](https://github.com/rust-lang/rust-clippy/pull/6200)
 +* [`unused_unit`]: Improve suggestion formatting
 +  [#6247](https://github.com/rust-lang/rust-clippy/pull/6247)
 +
 +### Documentation Improvements
 +
 +* Some doc improvements:
 +    * [`rc_buffer`] [#6090](https://github.com/rust-lang/rust-clippy/pull/6090)
 +    * [`empty_loop`] [#6162](https://github.com/rust-lang/rust-clippy/pull/6162)
 +* [`doc_markdown`]: Document problematic link text style
 +  [#6107](https://github.com/rust-lang/rust-clippy/pull/6107)
 +
 +## Rust 1.48
 +
 +Current stable, released 2020-11-19
 +
 +[09bd400...e636b88](https://github.com/rust-lang/rust-clippy/compare/09bd400...e636b88)
 +
 +### New lints
 +
 +* [`self_assignment`] [#5894](https://github.com/rust-lang/rust-clippy/pull/5894)
 +* [`unnecessary_lazy_evaluations`] [#5720](https://github.com/rust-lang/rust-clippy/pull/5720)
 +* [`manual_strip`] [#6038](https://github.com/rust-lang/rust-clippy/pull/6038)
 +* [`map_err_ignore`] [#5998](https://github.com/rust-lang/rust-clippy/pull/5998)
 +* [`rc_buffer`] [#6044](https://github.com/rust-lang/rust-clippy/pull/6044)
 +* [`to_string_in_display`] [#5831](https://github.com/rust-lang/rust-clippy/pull/5831)
 +* `single_char_push_str` [#5881](https://github.com/rust-lang/rust-clippy/pull/5881)
 +
 +### Moves and Deprecations
 +
 +* Downgrade [`verbose_bit_mask`] to pedantic
 +  [#6036](https://github.com/rust-lang/rust-clippy/pull/6036)
 +
 +### Enhancements
 +
 +* Extend [`precedence`] to handle chains of methods combined with unary negation
 +  [#5928](https://github.com/rust-lang/rust-clippy/pull/5928)
 +* [`useless_vec`]: add a configuration value for the maximum allowed size on the stack
 +  [#5907](https://github.com/rust-lang/rust-clippy/pull/5907)
 +* [`suspicious_arithmetic_impl`]: extend to implementations of `BitAnd`, `BitOr`, `BitXor`, `Rem`, `Shl`, and `Shr`
 +  [#5884](https://github.com/rust-lang/rust-clippy/pull/5884)
 +* [`invalid_atomic_ordering`]: detect misuse of `compare_exchange`, `compare_exchange_weak`, and `fetch_update`
 +  [#6025](https://github.com/rust-lang/rust-clippy/pull/6025)
 +* Avoid [`redundant_pattern_matching`] triggering in macros
 +  [#6069](https://github.com/rust-lang/rust-clippy/pull/6069)
 +* [`option_if_let_else`]: distinguish pure from impure `else` expressions
 +  [#5937](https://github.com/rust-lang/rust-clippy/pull/5937)
 +* [`needless_doctest_main`]: parse doctests instead of using textual search
 +  [#5912](https://github.com/rust-lang/rust-clippy/pull/5912)
 +* [`wildcard_imports`]: allow `prelude` to appear in any segment of an import
 +  [#5929](https://github.com/rust-lang/rust-clippy/pull/5929)
 +* Re-enable [`len_zero`] for ranges now that `range_is_empty` is stable
 +  [#5961](https://github.com/rust-lang/rust-clippy/pull/5961)
 +* [`option_as_ref_deref`]: catch fully-qualified calls to `Deref::deref` and `DerefMut::deref_mut`
 +  [#5933](https://github.com/rust-lang/rust-clippy/pull/5933)
 +
 +### False Positive Fixes
 +
 +* [`useless_attribute`]: permit allowing [`wildcard_imports`] and [`enum_glob_use`]
 +  [#5994](https://github.com/rust-lang/rust-clippy/pull/5994)
 +* [`transmute_ptr_to_ptr`]: avoid suggesting dereferencing raw pointers in const contexts
 +  [#5999](https://github.com/rust-lang/rust-clippy/pull/5999)
 +* [`redundant_closure_call`]: take into account usages of the closure in nested functions and closures
 +  [#5920](https://github.com/rust-lang/rust-clippy/pull/5920)
 +* Fix false positive in [`borrow_interior_mutable_const`] when referencing a field behind a pointer
 +  [#5949](https://github.com/rust-lang/rust-clippy/pull/5949)
 +* [`doc_markdown`]: allow using "GraphQL" without backticks
 +  [#5996](https://github.com/rust-lang/rust-clippy/pull/5996)
 +* [`to_string_in_display`]: avoid linting when calling `to_string()` on anything that is not `self`
 +  [#5971](https://github.com/rust-lang/rust-clippy/pull/5971)
 +* [`indexing_slicing`] and [`out_of_bounds_indexing`] treat references to arrays as arrays
 +  [#6034](https://github.com/rust-lang/rust-clippy/pull/6034)
 +* [`should_implement_trait`]: ignore methods with lifetime parameters
 +  [#5725](https://github.com/rust-lang/rust-clippy/pull/5725)
 +* [`needless_return`]: avoid linting if a temporary borrows a local variable
 +  [#5903](https://github.com/rust-lang/rust-clippy/pull/5903)
 +* Restrict [`unnecessary_sort_by`] to non-reference, Copy types
 +  [#6006](https://github.com/rust-lang/rust-clippy/pull/6006)
 +* Avoid suggesting `from_bits`/`to_bits` in const contexts in [`transmute_int_to_float`]
 +  [#5919](https://github.com/rust-lang/rust-clippy/pull/5919)
 +* [`declare_interior_mutable_const`] and [`borrow_interior_mutable_const`]: improve detection of interior mutable types
 +  [#6046](https://github.com/rust-lang/rust-clippy/pull/6046)
 +
 +### Suggestion Fixes/Improvements
 +
 +* [`let_and_return`]: add a cast to the suggestion when the return expression has adjustments
 +  [#5946](https://github.com/rust-lang/rust-clippy/pull/5946)
 +* [`useless_conversion`]: show the type in the error message
 +  [#6035](https://github.com/rust-lang/rust-clippy/pull/6035)
 +* [`unnecessary_mut_passed`]: discriminate between functions and methods in the error message
 +  [#5892](https://github.com/rust-lang/rust-clippy/pull/5892)
 +* [`float_cmp`] and [`float_cmp_const`]: change wording to make margin of error less ambiguous
 +  [#6043](https://github.com/rust-lang/rust-clippy/pull/6043)
 +* [`default_trait_access`]: do not use unnecessary type parameters in the suggestion
 +  [#5993](https://github.com/rust-lang/rust-clippy/pull/5993)
 +* [`collapsible_if`]: don't use expanded code in the suggestion
 +  [#5992](https://github.com/rust-lang/rust-clippy/pull/5992)
 +* Do not suggest empty format strings in [`print_with_newline`] and [`write_with_newline`]
 +  [#6042](https://github.com/rust-lang/rust-clippy/pull/6042)
 +* [`unit_arg`]: improve the readability of the suggestion
 +  [#5931](https://github.com/rust-lang/rust-clippy/pull/5931)
 +* [`stable_sort_primitive`]: print the type that is being sorted in the lint message
 +  [#5935](https://github.com/rust-lang/rust-clippy/pull/5935)
 +* Show line count and max lines in [`too_many_lines`] lint message
 +  [#6009](https://github.com/rust-lang/rust-clippy/pull/6009)
 +* Keep parentheses in the suggestion of [`useless_conversion`] where applicable
 +  [#5900](https://github.com/rust-lang/rust-clippy/pull/5900)
 +* [`option_map_unit_fn`] and [`result_map_unit_fn`]: print the unit type `()` explicitly
 +  [#6024](https://github.com/rust-lang/rust-clippy/pull/6024)
 +* [`redundant_allocation`]: suggest replacing `Rc<Box<T>>` with `Rc<T>`
 +  [#5899](https://github.com/rust-lang/rust-clippy/pull/5899)
 +* Make lint messages adhere to rustc dev guide conventions
 +  [#5893](https://github.com/rust-lang/rust-clippy/pull/5893)
 +
 +### ICE Fixes
 +
 +* Fix ICE in [`repeat_once`]
 +  [#5948](https://github.com/rust-lang/rust-clippy/pull/5948)
 +
 +### Documentation Improvements
 +
 +* [`mutable_key_type`]: explain potential for false positives when the interior mutable type is not accessed in the `Hash` implementation
 +  [#6019](https://github.com/rust-lang/rust-clippy/pull/6019)
 +* [`unnecessary_mut_passed`]: fix typo
 +  [#5913](https://github.com/rust-lang/rust-clippy/pull/5913)
 +* Add example of false positive to [`ptr_arg`] docs.
 +  [#5885](https://github.com/rust-lang/rust-clippy/pull/5885)
 +* [`box_vec`], [`vec_box`] and [`borrowed_box`]: add link to the documentation of `Box`
 +  [#6023](https://github.com/rust-lang/rust-clippy/pull/6023)
 +
 +## Rust 1.47
 +
 +Released 2020-10-08
 +
 +[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400)
 +
 +### New lints
 +
 +* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)
 +* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)
 +* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)
 +* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)
 +* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)
 +* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)
 +* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)
 +* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)
 +* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)
 +* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)
 +* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)
 +* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)
 +
 +### Moves and Deprecations
 +
 +* Deprecate [`regex_macro`] lint
 +  [#5760](https://github.com/rust-lang/rust-clippy/pull/5760)
 +* Move [`range_minus_one`] to `pedantic`
 +  [#5752](https://github.com/rust-lang/rust-clippy/pull/5752)
 +
 +### Enhancements
 +
 +* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls
 +  [#5837](https://github.com/rust-lang/rust-clippy/pull/5837)
 +* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting
 +  [#5811](https://github.com/rust-lang/rust-clippy/pull/5811)
 +* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]
 +  [#5443](https://github.com/rust-lang/rust-clippy/pull/5443)
 +* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]
 +  [#5701](https://github.com/rust-lang/rust-clippy/pull/5701)
 +* Make it possible to allow [`unsafe_derive_deserialize`]
 +  [#5870](https://github.com/rust-lang/rust-clippy/pull/5870)
 +* Catch `ord.min(a).max(b)` where a < b in [`min_max`]
 +  [#5871](https://github.com/rust-lang/rust-clippy/pull/5871)
 +* Make [`clone_on_copy`] suggestion machine applicable
 +  [#5745](https://github.com/rust-lang/rust-clippy/pull/5745)
 +* Enable [`len_zero`] on ranges now that `is_empty` is stable on them
 +  [#5961](https://github.com/rust-lang/rust-clippy/pull/5961)
 +
 +### False Positive Fixes
 +
 +* Avoid triggering [`or_fun_call`] with const fns that take no arguments
 +  [#5889](https://github.com/rust-lang/rust-clippy/pull/5889)
 +* Fix [`redundant_closure_call`] false positive for closures that have multiple calls
 +  [#5800](https://github.com/rust-lang/rust-clippy/pull/5800)
 +* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]
 +  [#5824](https://github.com/rust-lang/rust-clippy/pull/5824)
 +* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]
 +  [#5771](https://github.com/rust-lang/rust-clippy/pull/5771)
 +* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled
 +  [#5758](https://github.com/rust-lang/rust-clippy/pull/5758)
 +* Avoid linting if key borrows in [`unnecessary_sort_by`]
 +  [#5756](https://github.com/rust-lang/rust-clippy/pull/5756)
 +* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]
 +  [#5857](https://github.com/rust-lang/rust-clippy/pull/5857)
 +* Take input lifetimes into account in `manual_async_fn`
 +  [#5859](https://github.com/rust-lang/rust-clippy/pull/5859)
 +* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option
 +  [#5761](https://github.com/rust-lang/rust-clippy/pull/5761)
 +* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation
 +  [#5820](https://github.com/rust-lang/rust-clippy/pull/5820)
 +
 +### Suggestion Fixes/Improvements
 +
 +* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet
 +  [#5788](https://github.com/rust-lang/rust-clippy/pull/5788)
 +* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]
 +  [#5846](https://github.com/rust-lang/rust-clippy/pull/5846)
 +* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]
 +  [#5793](https://github.com/rust-lang/rust-clippy/pull/5793)
 +* Drop borrow operator in suggestions of [`redundant_pattern_matching`]
 +  [#5815](https://github.com/rust-lang/rust-clippy/pull/5815)
 +* Add suggestion for [`iter_skip_next`]
 +  [#5843](https://github.com/rust-lang/rust-clippy/pull/5843)
 +* Improve [`collapsible_if`] fix suggestion
 +  [#5732](https://github.com/rust-lang/rust-clippy/pull/5732)
 +
 +### ICE Fixes
 +
 +* Fix ICE caused by [`needless_collect`]
 +  [#5877](https://github.com/rust-lang/rust-clippy/pull/5877)
 +* Fix ICE caused by [`unnested_or_patterns`]
 +  [#5784](https://github.com/rust-lang/rust-clippy/pull/5784)
 +
 +### Documentation Improvements
 +
 +* Fix grammar of [`await_holding_lock`] documentation
 +  [#5748](https://github.com/rust-lang/rust-clippy/pull/5748)
 +
 +### Others
 +
 +* Make lints adhere to the rustc dev guide
 +  [#5888](https://github.com/rust-lang/rust-clippy/pull/5888)
 +
 +## Rust 1.46
 +
 +Released 2020-08-27
 +
 +[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa)
 +
 +### 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
 +
 +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
 +
 +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
 +[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
 +[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
 +[`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref
 +[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
 +[`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
 +[`collapsible_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match
 +[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
 +[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty
 +[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
 +[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
 +[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
 +[`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
 +[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
 +[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
 +[`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
 +[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
 +[`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
 +[`float_equality_without_abs`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_equality_without_abs
 +[`fn_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_address_comparisons
 +[`fn_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
 +[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect
++[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into
 +[`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_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_att_syntax
 +[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_intel_syntax
 +[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body
 +[`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
 +[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters
 +[`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
 +[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value
 +[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
 +[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
 +[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
 +[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
 +[`let_underscore_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_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or
 +[`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains
 +[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic
 +[`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip
 +[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap
 +[`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or
 +[`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_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit
 +[`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
 +[`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_err_ignore
 +[`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten
 +[`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity
 +[`map_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_mutex_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mutex_lock
 +[`mut_range_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_range_bound
 +[`mutable_key_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type
 +[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic
 +[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
 +[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount
 +[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
 +[`needless_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_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn
 +[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
 +[`panicking_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_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr
 +[`print_stdout`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout
 +[`print_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_with_newline
 +[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string
 +[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
 +[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq
 +[`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
 +[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer
 +[`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_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else
 +[`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
 +[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref
 +[`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
 +[`result_unit_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err
 +[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges
 +[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition
 +[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
 +[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
 +[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
 +[`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_add_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str
 +[`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_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop
 +[`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match
 +[`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
 +[`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count
 +[`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
 +[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive
 +[`str_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_to_string
 +[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add
 +[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign
 +[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars
 +[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes
 +[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
 +[`string_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_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings
 +[`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
 +[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display
 +[`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
 +[`trait_duplication_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#trait_duplication_in_bounds
 +[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_bytes_to_str
 +[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_float_to_int
 +[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool
 +[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char
 +[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float
 +[`transmute_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
 +[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmutes_expressible_as_ptr_casts
 +[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmuting_null
 +[`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
 +[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops
 +[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc
 +[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
 +[`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_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
 +[`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
 +[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps
 +[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern
 +[`unneeded_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
 +[`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings
 +[`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_in_result
 +[`unwrap_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_sized_map_values`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_sized_map_values
 +[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 +<!-- end autogenerated links to lint list -->
index a765390c6032d4c83694367683988b4b1c5e3bc0,0000000000000000000000000000000000000000..e60aa472846cfcee8f204bd28ec0fdfb0b4481a3
mode 100644,000000..100644
--- /dev/null
@@@ -1,57 -1,0 +1,57 @@@
- version = "0.0.212"
 +[package]
 +name = "clippy"
- clippy_lints = { version = "0.0.212", path = "clippy_lints" }
++version = "0.1.51"
 +authors = [
 +      "Manish Goregaokar <manishsmail@gmail.com>",
 +      "Andre Bogus <bogusandre@gmail.com>",
 +      "Georg Brandl <georg@python.org>",
 +      "Martin Carton <cartonmartin@gmail.com>",
 +      "Oliver Schneider <clippy-iethah7aipeen8neex1a@oli-obk.de>"
 +]
 +description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 +repository = "https://github.com/rust-lang/rust-clippy"
 +readme = "README.md"
 +license = "MIT OR Apache-2.0"
 +keywords = ["clippy", "lint", "plugin"]
 +categories = ["development-tools", "development-tools::cargo-plugins"]
 +build = "build.rs"
 +edition = "2018"
 +publish = false
 +
 +[[bin]]
 +name = "cargo-clippy"
 +test = false
 +path = "src/main.rs"
 +
 +[[bin]]
 +name = "clippy-driver"
 +path = "src/driver.rs"
 +
 +[dependencies]
 +# begin automatic update
++clippy_lints = { version = "0.1.50", path = "clippy_lints" }
 +# end automatic update
 +semver = "0.11"
 +rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
 +tempfile = { version = "3.1.0", optional = true }
 +
 +[dev-dependencies]
 +cargo_metadata = "0.12"
 +compiletest_rs = { version = "0.5.0", features = ["tmp"] }
 +tester = "0.7"
 +clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
 +serde = { version = "1.0", features = ["derive"] }
 +derive-new = "0.5"
 +
 +# A noop dependency that changes in the Rust repository, it's a bit of a hack.
 +# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
 +# for more information.
 +rustc-workspace-hack = "1.0.0"
 +
 +[build-dependencies]
 +rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
 +
 +[features]
 +deny-warnings = []
 +integration = ["tempfile"]
 +internal-lints = ["clippy_lints/internal-lints"]
index aaa55e11c7db1b1ee9086584b3b9c581aabad966,0000000000000000000000000000000000000000..a4928e17e6a947a3bbcb02a3e43ae9575ddc6cf8
mode 100644,000000..100644
--- /dev/null
@@@ -1,252 -1,0 +1,229 @@@
- Category | Description | Default level
- -- | -- | --
- `clippy::all` | all lints that are on by default (correctness, style, complexity, perf) | **warn/deny**
- `clippy::correctness` | code that is outright wrong or very useless | **deny**
- `clippy::style` | code that should be written in a more idiomatic way | **warn**
- `clippy::complexity` | code that does something simple but in a complex way | **warn**
- `clippy::perf` | code that can be written to run faster | **warn**
- `clippy::pedantic` | lints which are rather strict or might have false positives | allow
- `clippy::nursery` | new lints that are still under development | allow
- `clippy::cargo` | lints for the cargo manifest | allow
 +# 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 400 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 +
 +Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
 +You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.
 +
- ### 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!
++| Category              | Description                                                             | Default level |
++| --------------------- | ----------------------------------------------------------------------- | ------------- |
++| `clippy::all`         | all lints that are on by default (correctness, style, complexity, perf) | **warn/deny** |
++| `clippy::correctness` | code that is outright wrong or very useless                             | **deny**      |
++| `clippy::style`       | code that should be written in a more idiomatic way                     | **warn**      |
++| `clippy::complexity`  | code that does something simple but in a complex way                    | **warn**      |
++| `clippy::perf`        | code that can be written to run faster                                  | **warn**      |
++| `clippy::pedantic`    | lints which are rather strict or might have false positives             | allow         |
++| `clippy::nursery`     | new lints that are still under development                              | allow         |
++| `clippy::cargo`       | lints for the cargo manifest                                            | allow         |
 +
 +More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!
 +
 +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
 +```
 +
 +#### Workspaces
 +
 +All the usual workspace options should work with Clippy. For example the following command
 +will run Clippy on the `example` crate:
 +
 +```terminal
 +cargo clippy -p example
 +```
 +
 +As with `cargo check`, this includes dependencies that are members of the workspace, like path dependencies.
 +If you want to run Clippy **only** on the given crate, use the `--no-deps` option like this:
 +
 +```terminal
 +cargo clippy -p example -- --no-deps 
 +```
 +
- 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.
- ```
 +### 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.
 +```
 +
 +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: `allow` means to suppress the lint for your code. With `warn` the lint
 +will only emit a warning, while with `deny` the lint will emit an error, when
 +triggering for your code. An error causes clippy to exit with an error code, so
 +is useful in scripts like CI/CD.
 +
 +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:
 +
 +To allow `lint_name`, run
 +
 +```terminal
 +cargo clippy -- -A clippy::lint_name
 +```
 +
 +And to warn on `lint_name`, run
 +
 +```terminal
 +cargo clippy -- -W clippy::lint_name
 +```
 +
 +This also works with lint groups. For example you
 +can run Clippy with warnings for all lints enabled:
 +```terminal
 +cargo clippy -- -W clippy::pedantic
 +```
 +
 +If you care only about a single lint, you can allow all others and then explicitly warn on
 +the lint(s) you are interested in:
 +```terminal
 +cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::...
 +```
 +Note that if you've run clippy before, this may only take effect after you've modified a file or ran `cargo clean`.
 +
 +### Specifying the minimum supported Rust version
 +
 +Projects that intend to support old versions of Rust can disable lints pertaining to newer features by
 +specifying the minimum supported Rust version (MSRV) in the clippy configuration file.
 +
 +```toml
 +msrv = "1.30.0"
 +```
 +
 +The MSRV can also be specified as an inner attribute, like below.
 +
 +```rust
 +#![feature(custom_inner_attributes)]
 +#![clippy::msrv = "1.30.0"]
 +
 +fn main() {
 +  ...
 +}
 +```
 +
 +You can also omit the patch version when specifying the MSRV, so `msrv = 1.30`
 +is equivalent to `msrv = 1.30.0`.
 +
 +Note: `custom_inner_attributes` is an unstable feature so it has to be enabled explicitly.
 +
 +Lints that recognize this configuration option can be found [here](https://rust-lang.github.io/rust-clippy/master/index.html#msrv)
 +
 +## 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 40bf4a9505a88632027b1878405dd49ad8e0bc19,0000000000000000000000000000000000000000..5f5048e79e7825162beb876071fa887e233298f8
mode 100644,000000..100644
--- /dev/null
@@@ -1,100 -1,0 +1,100 @@@
- use std::path::PathBuf;
 +#![allow(clippy::filter_map)]
 +
 +use std::fs;
 +use std::fs::File;
 +use std::io::prelude::*;
-     rustc_source_dir: &PathBuf,
++use std::path::{Path, PathBuf};
 +
 +// This module takes an absolute path to a rustc repo and alters the dependencies to point towards
 +// the respective rustc subcrates instead of using extern crate xyz.
 +// This allows rust analyzer to analyze rustc internals and show proper information inside clippy
 +// code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details
 +
 +pub fn run(rustc_path: Option<&str>) {
 +    // we can unwrap here because the arg is required by clap
 +    let rustc_path = PathBuf::from(rustc_path.unwrap());
 +    assert!(rustc_path.is_dir(), "path is not a directory");
 +    let rustc_source_basedir = rustc_path.join("compiler");
 +    assert!(
 +        rustc_source_basedir.is_dir(),
 +        "are you sure the path leads to a rustc repo?"
 +    );
 +
 +    let clippy_root_manifest = fs::read_to_string("Cargo.toml").expect("failed to read ./Cargo.toml");
 +    let clippy_root_lib_rs = fs::read_to_string("src/driver.rs").expect("failed to read ./src/driver.rs");
 +    inject_deps_into_manifest(
 +        &rustc_source_basedir,
 +        "Cargo.toml",
 +        &clippy_root_manifest,
 +        &clippy_root_lib_rs,
 +    )
 +    .expect("Failed to inject deps into ./Cargo.toml");
 +
 +    let clippy_lints_manifest =
 +        fs::read_to_string("clippy_lints/Cargo.toml").expect("failed to read ./clippy_lints/Cargo.toml");
 +    let clippy_lints_lib_rs =
 +        fs::read_to_string("clippy_lints/src/lib.rs").expect("failed to read ./clippy_lints/src/lib.rs");
 +    inject_deps_into_manifest(
 +        &rustc_source_basedir,
 +        "clippy_lints/Cargo.toml",
 +        &clippy_lints_manifest,
 +        &clippy_lints_lib_rs,
 +    )
 +    .expect("Failed to inject deps into ./clippy_lints/Cargo.toml");
 +}
 +
 +fn inject_deps_into_manifest(
++    rustc_source_dir: &Path,
 +    manifest_path: &str,
 +    cargo_toml: &str,
 +    lib_rs: &str,
 +) -> std::io::Result<()> {
 +    // do not inject deps if we have aleady done so
 +    if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
 +        eprintln!(
 +            "cargo dev ra_setup: warning: deps already found inside {}, doing nothing.",
 +            manifest_path
 +        );
 +        return Ok(());
 +    }
 +
 +    let extern_crates = lib_rs
 +        .lines()
 +        // get the deps
 +        .filter(|line| line.starts_with("extern crate"))
 +        // we have something like "extern crate foo;", we only care about the "foo"
 +        //              ↓          ↓
 +        // extern crate rustc_middle;
 +        .map(|s| &s[13..(s.len() - 1)]);
 +
 +    let new_deps = extern_crates.map(|dep| {
 +        // format the dependencies that are going to be put inside the Cargo.toml
 +        format!(
 +            "{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
 +            dep = dep,
 +            source_path = rustc_source_dir.display()
 +        )
 +    });
 +
 +    // format a new [dependencies]-block with the new deps we need to inject
 +    let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
 +    new_deps.for_each(|dep_line| {
 +        all_deps.push_str(&dep_line);
 +    });
 +    all_deps.push_str("\n[dependencies]\n");
 +
 +    // replace "[dependencies]" with
 +    // [dependencies]
 +    // dep1 = { path = ... }
 +    // dep2 = { path = ... }
 +    // etc
 +    let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);
 +
 +    // println!("{}", new_manifest);
 +    let mut file = File::create(manifest_path)?;
 +    file.write_all(new_manifest.as_bytes())?;
 +
 +    println!("Dependency paths injected: {}", manifest_path);
 +
 +    Ok(())
 +}
index 7697eba650aca9499c95b1adf6e885ec9f885797,0000000000000000000000000000000000000000..a9516560a61952c9bb6d58acd168805cccd1f35a
mode 100644,000000..100644
--- /dev/null
@@@ -1,41 -1,0 +1,41 @@@
- version = "0.0.212"
 +[package]
 +name = "clippy_lints"
 +# begin automatic update
++version = "0.1.51"
 +# end automatic update
 +authors = [
 +      "Manish Goregaokar <manishsmail@gmail.com>",
 +      "Andre Bogus <bogusandre@gmail.com>",
 +      "Georg Brandl <georg@python.org>",
 +      "Martin Carton <cartonmartin@gmail.com>"
 +]
 +description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 +repository = "https://github.com/rust-lang/rust-clippy"
 +readme = "README.md"
 +license = "MIT OR Apache-2.0"
 +keywords = ["clippy", "lint", "plugin"]
 +edition = "2018"
 +
 +[dependencies]
 +cargo_metadata = "0.12"
 +if_chain = "1.0.0"
 +itertools = "0.9"
 +pulldown-cmark = { version = "0.8", default-features = false }
 +quine-mc_cluskey = "0.2.2"
 +regex-syntax = "0.6"
 +serde = { version = "1.0", features = ["derive"] }
 +smallvec = { version = "1", features = ["union"] }
 +toml = "0.5.3"
 +unicode-normalization = "0.1"
 +semver = "0.11"
 +rustc-semver="1.1.0"
 +# NOTE: cargo requires serde feat in its url dep
 +# see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
 +url = { version =  "2.1.0", features = ["serde"] }
 +quote = "1"
 +syn = { version = "1", features = ["full"] }
 +
 +[features]
 +deny-warnings = []
 +# build clippy with internal lints enabled, off by default
 +internal-lints = []
index f69f6f1412af97d0c35cfc044b887dd6111def9e,0000000000000000000000000000000000000000..b0d7c7b3baab1b71fa6d0b82090b08aadc9c37c0
mode 100644,000000..100644
--- /dev/null
@@@ -1,303 -1,0 +1,257 @@@
- use rustc_middle::ty::{self, Adt, Ty};
 +use crate::utils::{any_parent_is_automatically_derived, contains_name, match_def_path, paths, qpath_res, snippet};
 +use crate::utils::{span_lint_and_note, span_lint_and_sugg};
 +use if_chain::if_chain;
 +use rustc_data_structures::fx::FxHashSet;
 +use rustc_errors::Applicability;
 +use rustc_hir::def::Res;
 +use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
 +use rustc_lint::{LateContext, LateLintPass};
-         // find all binding statements like `let mut _ = T::default()` where `T::default()` is the
-         // `default` method of the `Default` trait, and store statement index in current block being
-         // checked and the name of the bound variable
-         let binding_statements_using_default = enumerate_bindings_using_default(cx, block);
++use rustc_middle::ty;
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_span::symbol::{Ident, Symbol};
 +use rustc_span::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for literal calls to `Default::default()`.
 +    ///
 +    /// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is
 +    /// being gotten than the generic `Default`.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// // Bad
 +    /// let s: String = Default::default();
 +    ///
 +    /// // Good
 +    /// let s = String::default();
 +    /// ```
 +    pub DEFAULT_TRAIT_ACCESS,
 +    pedantic,
 +    "checks for literal calls to `Default::default()`"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for immediate reassignment of fields initialized
 +    /// with Default::default().
 +    ///
 +    /// **Why is this bad?**It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
 +    ///
 +    /// **Known problems:** Assignments to patterns that are of tuple type are not linted.
 +    ///
 +    /// **Example:**
 +    /// Bad:
 +    /// ```
 +    /// # #[derive(Default)]
 +    /// # struct A { i: i32 }
 +    /// let mut a: A = Default::default();
 +    /// a.i = 42;
 +    /// ```
 +    /// Use instead:
 +    /// ```
 +    /// # #[derive(Default)]
 +    /// # struct A { i: i32 }
 +    /// let a = A {
 +    ///     i: 42,
 +    ///     .. Default::default()
 +    /// };
 +    /// ```
 +    pub FIELD_REASSIGN_WITH_DEFAULT,
 +    style,
 +    "binding initialized with Default should have its fields set in the initializer"
 +}
 +
 +#[derive(Default)]
 +pub struct Default {
 +    // Spans linted by `field_reassign_with_default`.
 +    reassigned_linted: FxHashSet<Span>,
 +}
 +
 +impl_lint_pass!(Default => [DEFAULT_TRAIT_ACCESS, FIELD_REASSIGN_WITH_DEFAULT]);
 +
 +impl LateLintPass<'_> for Default {
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if_chain! {
 +            // Avoid cases already linted by `field_reassign_with_default`
 +            if !self.reassigned_linted.contains(&expr.span);
 +            if let ExprKind::Call(ref path, ..) = expr.kind;
 +            if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
 +            if let ExprKind::Path(ref qpath) = path.kind;
 +            if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
 +            if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
 +            // Detect and ignore <Foo as Default>::default() because these calls do explicitly name the type.
 +            if let QPath::Resolved(None, _path) = qpath;
 +            then {
 +                let expr_ty = cx.typeck_results().expr_ty(expr);
 +                if let ty::Adt(def, ..) = expr_ty.kind() {
 +                    // TODO: Work out a way to put "whatever the imported way of referencing
 +                    // this type in this file" rather than a fully-qualified type.
 +                    let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
 +                    span_lint_and_sugg(
 +                        cx,
 +                        DEFAULT_TRAIT_ACCESS,
 +                        expr.span,
 +                        &format!("calling `{}` is more clear than this expression", replacement),
 +                        "try",
 +                        replacement,
 +                        Applicability::Unspecified, // First resolve the TODO above
 +                    );
 +                }
 +            }
 +        }
 +    }
 +
 +    fn check_block<'tcx>(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
-         for (stmt_idx, binding_name, binding_type, span) in binding_statements_using_default {
-             // the last statement of a block cannot trigger the lint
-             if stmt_idx == block.stmts.len() - 1 {
-                 break;
-             }
 +        // start from the `let mut _ = _::default();` and look at all the following
 +        // statements, see if they re-assign the fields of the binding
-                 // interrupt if the statement is a let binding (`Local`) that shadows the original
-                 // binding
-                 if stmt_shadows_binding(consecutive_statement, binding_name) {
-                     break;
-                 }
++        let stmts_head = match block.stmts {
++            // Skip the last statement since there cannot possibly be any following statements that re-assign fields.
++            [head @ .., _] if !head.is_empty() => head,
++            _ => return,
++        };
++        for (stmt_idx, stmt) in stmts_head.iter().enumerate() {
++            // find all binding statements like `let mut _ = T::default()` where `T::default()` is the
++            // `default` method of the `Default` trait, and store statement index in current block being
++            // checked and the name of the bound variable
++            let (local, variant, binding_name, binding_type, span) = if_chain! {
++                // only take `let ...` statements
++                if let StmtKind::Local(local) = stmt.kind;
++                if let Some(expr) = local.init;
++                // only take bindings to identifiers
++                if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
++                // only when assigning `... = Default::default()`
++                if is_expr_default(expr, cx);
++                let binding_type = cx.typeck_results().node_type(binding_id);
++                if let Some(adt) = binding_type.ty_adt_def();
++                if adt.is_struct();
++                let variant = adt.non_enum_variant();
++                if adt.did.is_local() || !variant.is_field_list_non_exhaustive();
++                let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id();
++                if variant
++                    .fields
++                    .iter()
++                    .all(|field| field.vis.is_accessible_from(module_did, cx.tcx));
++                then {
++                    (local, variant, ident.name, binding_type, expr.span)
++                } else {
++                    continue;
++                }
++            };
 +
 +            // find all "later statement"'s where the fields of the binding set as
 +            // Default::default() get reassigned, unless the reassignment refers to the original binding
 +            let mut first_assign = None;
 +            let mut assigned_fields = Vec::new();
 +            let mut cancel_lint = false;
 +            for consecutive_statement in &block.stmts[stmt_idx + 1..] {
-                 else if let Some((field_ident, assign_rhs)) =
-                     field_reassigned_by_stmt(consecutive_statement, binding_name)
-                 {
 +                // find out if and which field was set by this `consecutive_statement`
-                 // interrupt also if no field was assigned, since we only want to look at consecutive statements
++                if let Some((field_ident, assign_rhs)) = field_reassigned_by_stmt(consecutive_statement, binding_name) {
 +                    // interrupt and cancel lint if assign_rhs references the original binding
 +                    if contains_name(binding_name, assign_rhs) {
 +                        cancel_lint = true;
 +                        break;
 +                    }
 +
 +                    // if the field was previously assigned, replace the assignment, otherwise insert the assignment
 +                    if let Some(prev) = assigned_fields
 +                        .iter_mut()
 +                        .find(|(field_name, _)| field_name == &field_ident.name)
 +                    {
 +                        *prev = (field_ident.name, assign_rhs);
 +                    } else {
 +                        assigned_fields.push((field_ident.name, assign_rhs));
 +                    }
 +
 +                    // also set first instance of error for help message
 +                    if first_assign.is_none() {
 +                        first_assign = Some(consecutive_statement);
 +                    }
 +                }
-                 // take the original assignment as span
-                 let stmt = &block.stmts[stmt_idx];
-                 if let StmtKind::Local(preceding_local) = &stmt.kind {
-                     // filter out fields like `= Default::default()`, because the FRU already covers them
-                     let assigned_fields = assigned_fields
-                         .into_iter()
-                         .filter(|(_, rhs)| !is_expr_default(rhs, cx))
-                         .collect::<Vec<(Symbol, &Expr<'_>)>>();
++                // interrupt if no field was assigned, since we only want to look at consecutive statements
 +                else {
 +                    break;
 +                }
 +            }
 +
 +            // if there are incorrectly assigned fields, do a span_lint_and_note to suggest
 +            // construction using `Ty { fields, ..Default::default() }`
 +            if !assigned_fields.is_empty() && !cancel_lint {
-                     // if all fields of the struct are not assigned, add `.. Default::default()` to the suggestion.
-                     let ext_with_default = !fields_of_type(binding_type)
-                         .iter()
-                         .all(|field| assigned_fields.iter().any(|(a, _)| a == &field.name));
++                // if all fields of the struct are not assigned, add `.. Default::default()` to the suggestion.
++                let ext_with_default = !variant
++                    .fields
++                    .iter()
++                    .all(|field| assigned_fields.iter().any(|(a, _)| a == &field.ident.name));
 +
-                     let field_list = assigned_fields
-                         .into_iter()
-                         .map(|(field, rhs)| {
-                             // extract and store the assigned value for help message
-                             let value_snippet = snippet(cx, rhs.span, "..");
-                             format!("{}: {}", field, value_snippet)
-                         })
-                         .collect::<Vec<String>>()
-                         .join(", ");
-                     let sugg = if ext_with_default {
-                         if field_list.is_empty() {
-                             format!("{}::default()", binding_type)
-                         } else {
-                             format!("{} {{ {}, ..Default::default() }}", binding_type, field_list)
-                         }
++                let field_list = assigned_fields
++                    .into_iter()
++                    .map(|(field, rhs)| {
++                        // extract and store the assigned value for help message
++                        let value_snippet = snippet(cx, rhs.span, "..");
++                        format!("{}: {}", field, value_snippet)
++                    })
++                    .collect::<Vec<String>>()
++                    .join(", ");
 +
-                         format!("{} {{ {} }}", binding_type, field_list)
-                     };
++                let sugg = if ext_with_default {
++                    if field_list.is_empty() {
++                        format!("{}::default()", binding_type)
 +                    } else {
-                     // span lint once per statement that binds default
-                     span_lint_and_note(
-                         cx,
-                         FIELD_REASSIGN_WITH_DEFAULT,
-                         first_assign.unwrap().span,
-                         "field assignment outside of initializer for an instance created with Default::default()",
-                         Some(preceding_local.span),
-                         &format!(
-                             "consider initializing the variable with `{}` and removing relevant reassignments",
-                             sugg
-                         ),
-                     );
-                     self.reassigned_linted.insert(span);
-                 }
++                        format!("{} {{ {}, ..Default::default() }}", binding_type, field_list)
++                    }
++                } else {
++                    format!("{} {{ {} }}", binding_type, field_list)
++                };
 +
- /// Returns the block indices, identifiers and types of bindings set as `Default::default()`, except
- /// for when the pattern type is a tuple.
- fn enumerate_bindings_using_default<'tcx>(
-     cx: &LateContext<'tcx>,
-     block: &Block<'tcx>,
- ) -> Vec<(usize, Symbol, Ty<'tcx>, Span)> {
-     block
-         .stmts
-         .iter()
-         .enumerate()
-         .filter_map(|(idx, stmt)| {
-             if_chain! {
-                 // only take `let ...` statements
-                 if let StmtKind::Local(ref local) = stmt.kind;
-                 // only take bindings to identifiers
-                 if let PatKind::Binding(_, _, ident, _) = local.pat.kind;
-                 // that are not tuples
-                 let ty = cx.typeck_results().pat_ty(local.pat);
-                 if !matches!(ty.kind(), ty::Tuple(_));
-                 // only when assigning `... = Default::default()`
-                 if let Some(ref expr) = local.init;
-                 if is_expr_default(expr, cx);
-                 then {
-                     Some((idx, ident.name, ty, expr.span))
-                 } else {
-                     None
-                 }
-             }
-         })
-         .collect()
- }
- fn stmt_shadows_binding(this: &Stmt<'_>, shadowed: Symbol) -> bool {
-     if let StmtKind::Local(local) = &this.kind {
-         if let PatKind::Binding(_, _, ident, _) = local.pat.kind {
-             return ident.name == shadowed;
-         }
-     }
-     false
- }
++                // span lint once per statement that binds default
++                span_lint_and_note(
++                    cx,
++                    FIELD_REASSIGN_WITH_DEFAULT,
++                    first_assign.unwrap().span,
++                    "field assignment outside of initializer for an instance created with Default::default()",
++                    Some(local.span),
++                    &format!(
++                        "consider initializing the variable with `{}` and removing relevant reassignments",
++                        sugg
++                    ),
++                );
++                self.reassigned_linted.insert(span);
 +            }
 +        }
 +    }
 +}
 +
 +/// Checks if the given expression is the `default` method belonging to the `Default` trait.
 +fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool {
 +    if_chain! {
 +        if let ExprKind::Call(ref fn_expr, _) = &expr.kind;
 +        if let ExprKind::Path(qpath) = &fn_expr.kind;
 +        if let Res::Def(_, def_id) = qpath_res(cx, qpath, fn_expr.hir_id);
 +        then {
 +            // right hand side of assignment is `Default::default`
 +            match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD)
 +        } else {
 +            false
 +        }
 +    }
 +}
 +
- /// Returns the vec of fields for a struct and an empty vec for non-struct ADTs.
- fn fields_of_type(ty: Ty<'_>) -> Vec<Ident> {
-     if let Adt(adt, _) = ty.kind() {
-         if adt.is_struct() {
-             let variant = &adt.non_enum_variant();
-             return variant.fields.iter().map(|f| f.ident).collect();
-         }
-     }
-     vec![]
- }
 +/// Returns the reassigned field and the assigning expression (right-hand side of assign).
 +fn field_reassigned_by_stmt<'tcx>(this: &Stmt<'tcx>, binding_name: Symbol) -> Option<(Ident, &'tcx Expr<'tcx>)> {
 +    if_chain! {
 +        // only take assignments
 +        if let StmtKind::Semi(ref later_expr) = this.kind;
 +        if let ExprKind::Assign(ref assign_lhs, ref assign_rhs, _) = later_expr.kind;
 +        // only take assignments to fields where the left-hand side field is a field of
 +        // the same binding as the previous statement
 +        if let ExprKind::Field(ref binding, field_ident) = assign_lhs.kind;
 +        if let ExprKind::Path(QPath::Resolved(_, path)) = binding.kind;
 +        if let Some(second_binding_name) = path.segments.last();
 +        if second_binding_name.ident.name == binding_name;
 +        then {
 +            Some((field_ident, assign_rhs))
 +        } else {
 +            None
 +        }
 +    }
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1e7e5f53cc2a35dcbcaf2b6586871e52445ed158
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,83 @@@
++use crate::utils::paths::INTO;
++use crate::utils::{match_def_path, meets_msrv, span_lint_and_help};
++use if_chain::if_chain;
++use rustc_hir as hir;
++use rustc_lint::{LateContext, LateLintPass, LintContext};
++use rustc_semver::RustcVersion;
++use rustc_session::{declare_tool_lint, impl_lint_pass};
++
++const FROM_OVER_INTO_MSRV: RustcVersion = RustcVersion::new(1, 41, 0);
++
++declare_clippy_lint! {
++    /// **What it does:** Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
++    ///
++    /// **Why is this bad?** According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
++    ///
++    /// **Known problems:** None.
++    ///
++    /// **Example:**
++    ///
++    /// ```rust
++    /// struct StringWrapper(String);
++    ///
++    /// impl Into<StringWrapper> for String {
++    ///     fn into(self) -> StringWrapper {
++    ///         StringWrapper(self)
++    ///     }
++    /// }
++    /// ```
++    /// Use instead:
++    /// ```rust
++    /// struct StringWrapper(String);
++    ///
++    /// impl From<String> for StringWrapper {
++    ///     fn from(s: String) -> StringWrapper {
++    ///         StringWrapper(s)
++    ///     }
++    /// }
++    /// ```
++    pub FROM_OVER_INTO,
++    style,
++    "Warns on implementations of `Into<..>` to use `From<..>`"
++}
++
++pub struct FromOverInto {
++    msrv: Option<RustcVersion>,
++}
++
++impl FromOverInto {
++    #[must_use]
++    pub fn new(msrv: Option<RustcVersion>) -> Self {
++        FromOverInto { msrv }
++    }
++}
++
++impl_lint_pass!(FromOverInto => [FROM_OVER_INTO]);
++
++impl LateLintPass<'_> for FromOverInto {
++    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
++        if !meets_msrv(self.msrv.as_ref(), &FROM_OVER_INTO_MSRV) {
++            return;
++        }
++
++        let impl_def_id = cx.tcx.hir().local_def_id(item.hir_id);
++        if_chain! {
++            if let hir::ItemKind::Impl{ .. } = &item.kind;
++            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id);
++            if match_def_path(cx, impl_trait_ref.def_id, &INTO);
++
++            then {
++                span_lint_and_help(
++                    cx,
++                    FROM_OVER_INTO,
++                    item.span,
++                    "an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true",
++                    None,
++                    "consider to implement `From` instead",
++                );
++            }
++        }
++    }
++
++    extract_msrv_attr!(LateContext);
++}
index 3c7880d74ee6490ff27eec53f633337531e53542,0000000000000000000000000000000000000000..ad9b4f357a74dbbe8a489176075d158c0b45cb38
mode 100644,000000..100644
--- /dev/null
@@@ -1,134 -1,0 +1,138 @@@
 +//! lint when there is a large size difference between variants on an enum
 +
 +use crate::utils::{snippet_opt, span_lint_and_then};
 +use rustc_errors::Applicability;
 +use rustc_hir::{Item, ItemKind, VariantData};
 +use rustc_lint::{LateContext, LateLintPass};
++use rustc_middle::lint::in_external_macro;
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_target::abi::LayoutOf;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for large size differences between variants on
 +    /// `enum`s.
 +    ///
 +    /// **Why is this bad?** Enum size is bounded by the largest variant. Having a
 +    /// large variant can penalize the memory layout of that enum.
 +    ///
 +    /// **Known problems:** This lint obviously cannot take the distribution of
 +    /// variants in your running program into account. It is possible that the
 +    /// smaller variants make up less than 1% of all instances, in which case
 +    /// the overhead is negligible and the boxing is counter-productive. Always
 +    /// measure the change this lint suggests.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// // Bad
 +    /// enum Test {
 +    ///     A(i32),
 +    ///     B([i32; 8000]),
 +    /// }
 +    ///
 +    /// // Possibly better
 +    /// enum Test2 {
 +    ///     A(i32),
 +    ///     B(Box<[i32; 8000]>),
 +    /// }
 +    /// ```
 +    pub LARGE_ENUM_VARIANT,
 +    perf,
 +    "large size difference between variants on an enum"
 +}
 +
 +#[derive(Copy, Clone)]
 +pub struct LargeEnumVariant {
 +    maximum_size_difference_allowed: u64,
 +}
 +
 +impl LargeEnumVariant {
 +    #[must_use]
 +    pub fn new(maximum_size_difference_allowed: u64) -> Self {
 +        Self {
 +            maximum_size_difference_allowed,
 +        }
 +    }
 +}
 +
 +impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
 +
 +impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
 +    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
++        if in_external_macro(cx.tcx.sess, item.span) {
++            return;
++        }
 +        let did = cx.tcx.hir().local_def_id(item.hir_id);
 +        if let ItemKind::Enum(ref def, _) = item.kind {
 +            let ty = cx.tcx.type_of(did);
 +            let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
 +
 +            let mut largest_variant: Option<(_, _)> = None;
 +            let mut second_variant: Option<(_, _)> = None;
 +
 +            for (i, variant) in adt.variants.iter().enumerate() {
 +                let size: u64 = variant
 +                    .fields
 +                    .iter()
 +                    .filter_map(|f| {
 +                        let ty = cx.tcx.type_of(f.did);
 +                        // don't count generics by filtering out everything
 +                        // that does not have a layout
 +                        cx.layout_of(ty).ok().map(|l| l.size.bytes())
 +                    })
 +                    .sum();
 +
 +                let grouped = (size, (i, variant));
 +
 +                if grouped.0 >= largest_variant.map_or(0, |x| x.0) {
 +                    second_variant = largest_variant;
 +                    largest_variant = Some(grouped);
 +                }
 +            }
 +
 +            if let (Some(largest), Some(second)) = (largest_variant, second_variant) {
 +                let difference = largest.0 - second.0;
 +
 +                if difference > self.maximum_size_difference_allowed {
 +                    let (i, variant) = largest.1;
 +
 +                    let help_text = "consider boxing the large fields to reduce the total size of the enum";
 +                    span_lint_and_then(
 +                        cx,
 +                        LARGE_ENUM_VARIANT,
 +                        def.variants[i].span,
 +                        "large size difference between variants",
 +                        |diag| {
 +                            diag.span_label(
 +                                def.variants[(largest.1).0].span,
 +                                &format!("this variant is {} bytes", largest.0),
 +                            );
 +                            diag.span_note(
 +                                def.variants[(second.1).0].span,
 +                                &format!("and the second-largest variant is {} bytes:", second.0),
 +                            );
 +                            if variant.fields.len() == 1 {
 +                                let span = match def.variants[i].data {
 +                                    VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => {
 +                                        fields[0].ty.span
 +                                    },
 +                                    VariantData::Unit(..) => unreachable!(),
 +                                };
 +                                if let Some(snip) = snippet_opt(cx, span) {
 +                                    diag.span_suggestion(
 +                                        span,
 +                                        help_text,
 +                                        format!("Box<{}>", snip),
 +                                        Applicability::MaybeIncorrect,
 +                                    );
 +                                    return;
 +                                }
 +                            }
 +                            diag.span_help(def.variants[i].span, help_text);
 +                        },
 +                    );
 +                }
 +            }
 +        }
 +    }
 +}
index 02ba422a2f5b8c0287913a80aad522f5256c8152,0000000000000000000000000000000000000000..35b057d7b6a4153b7d0372b5c40b3fe9f9544bc6
mode 100644,000000..100644
--- /dev/null
@@@ -1,2036 -1,0 +1,2041 @@@
 +// 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(in_band_lifetimes)]
 +#![feature(once_cell)]
 +#![feature(or_patterns)]
 +#![feature(rustc_private)]
 +#![feature(stmt_expr_attributes)]
 +#![feature(control_flow_enum)]
 +#![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_driver;
 +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 crate::utils::parse_msrv;
 +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 asm_syntax;
 +mod assertions_on_constants;
 +mod assign_ops;
 +mod async_yields_async;
 +mod atomic_ordering;
 +mod attrs;
 +mod await_holding_invalid;
 +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 collapsible_match;
 +mod comparison_chain;
 +mod copies;
 +mod copy_iterator;
 +mod create_dir;
 +mod dbg_macro;
 +mod default;
 +mod dereference;
 +mod derive;
 +mod disallowed_method;
 +mod doc;
 +mod double_comparison;
 +mod double_parens;
 +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_equality_without_abs;
 +mod float_literal;
 +mod floating_point_arithmetic;
 +mod format;
 +mod formatting;
++mod from_over_into;
 +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_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 manual_ok_or;
 +mod manual_strip;
 +mod manual_unwrap_or;
 +mod map_clone;
 +mod map_err_ignore;
 +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_mutex_lock;
 +mod mut_reference;
 +mod mutable_debug_assertion;
 +mod mutex_atomic;
 +mod needless_arbitrary_self_type;
 +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_in_result_fn;
 +mod panic_unimplemented;
 +mod partialeq_ne_impl;
 +mod pass_by_ref_or_value;
 +mod path_buf_push_overwrite;
 +mod pattern_type_mismatch;
 +mod precedence;
 +mod ptr;
 +mod ptr_eq;
 +mod ptr_offset_with_cast;
 +mod question_mark;
 +mod ranges;
 +mod redundant_clone;
 +mod redundant_closure_call;
 +mod redundant_else;
 +mod redundant_field_names;
 +mod redundant_pub_crate;
 +mod redundant_static_lifetimes;
 +mod ref_option_ref;
 +mod reference;
 +mod regex;
 +mod repeat_once;
 +mod returns;
 +mod self_assignment;
 +mod serde_api;
 +mod shadow;
 +mod single_component_path_imports;
 +mod size_of_in_element_count;
 +mod slow_vector_initialization;
 +mod stable_sort_primitive;
 +mod strings;
 +mod suspicious_operation_groupings;
 +mod suspicious_trait_impl;
 +mod swap;
 +mod tabs_in_doc_comments;
 +mod temporary_assignment;
 +mod to_digit_is_some;
 +mod to_string_in_display;
 +mod trait_bounds;
 +mod transmute;
 +mod transmuting_null;
 +mod try_err;
 +mod types;
 +mod undropped_manually_drops;
 +mod unicode;
 +mod unit_return_expecting_ord;
 +mod unnamed_address;
 +mod unnecessary_sort_by;
 +mod unnecessary_wraps;
 +mod unnested_or_patterns;
 +mod unsafe_removed_from_name;
 +mod unused_io_amount;
 +mod unused_self;
 +mod unused_unit;
 +mod unwrap;
 +mod unwrap_in_result;
 +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;
 +mod zero_sized_map_values;
 +// end lints modules, do not remove this comment, it’s used in `update_lints`
 +
 +pub use crate::utils::conf::Conf;
 +
 +/// 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::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::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",
 +        "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",
 +    );
 +    store.register_removed(
 +        "clippy::drop_bounds",
 +        "this lint has been uplifted to rustc and is now called `drop_bounds`",
 +    );
 +    store.register_removed(
 +        "clippy::temporary_cstring_as_ptr",
 +        "this lint has been uplifted to rustc and is now called `temporary_cstring_as_ptr`",
 +    );
 +    store.register_removed(
 +        "clippy::panic_params",
 +        "this lint has been uplifted to rustc and is now called `panic_fmt`",
 +    );
 +    // 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(&[
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::CLIPPY_LINTS_INTERNAL,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::COMPILER_LINT_FUNCTIONS,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::DEFAULT_LINT,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::INTERNING_DEFINED_SYMBOL,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::INVALID_PATHS,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::LINT_WITHOUT_LINT_PASS,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::OUTER_EXPN_EXPN_DATA,
 +        #[cfg(feature = "internal-lints")]
 +        &utils::internal_lints::PRODUCE_ICE,
 +        &approx_const::APPROX_CONSTANT,
 +        &arithmetic::FLOAT_ARITHMETIC,
 +        &arithmetic::INTEGER_ARITHMETIC,
 +        &as_conversions::AS_CONVERSIONS,
 +        &asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
 +        &asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
 +        &assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
 +        &assign_ops::ASSIGN_OP_PATTERN,
 +        &assign_ops::MISREFACTORED_ASSIGN_OP,
 +        &async_yields_async::ASYNC_YIELDS_ASYNC,
 +        &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_invalid::AWAIT_HOLDING_LOCK,
 +        &await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
 +        &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,
 +        &collapsible_match::COLLAPSIBLE_MATCH,
 +        &comparison_chain::COMPARISON_CHAIN,
 +        &copies::IFS_SAME_COND,
 +        &copies::IF_SAME_THEN_ELSE,
 +        &copies::SAME_FUNCTIONS_IN_IF_CONDITION,
 +        &copy_iterator::COPY_ITERATOR,
 +        &create_dir::CREATE_DIR,
 +        &dbg_macro::DBG_MACRO,
 +        &default::DEFAULT_TRAIT_ACCESS,
 +        &default::FIELD_REASSIGN_WITH_DEFAULT,
 +        &dereference::EXPLICIT_DEREF_METHODS,
 +        &derive::DERIVE_HASH_XOR_EQ,
 +        &derive::DERIVE_ORD_XOR_PARTIAL_ORD,
 +        &derive::EXPL_IMPL_CLONE_ON_COPY,
 +        &derive::UNSAFE_DERIVE_DESERIALIZE,
 +        &disallowed_method::DISALLOWED_METHOD,
 +        &doc::DOC_MARKDOWN,
 +        &doc::MISSING_ERRORS_DOC,
 +        &doc::MISSING_SAFETY_DOC,
 +        &doc::NEEDLESS_DOCTEST_MAIN,
 +        &double_comparison::DOUBLE_COMPARISONS,
 +        &double_parens::DOUBLE_PARENS,
 +        &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_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS,
 +        &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,
++        &from_over_into::FROM_OVER_INTO,
 +        &functions::DOUBLE_MUST_USE,
 +        &functions::MUST_USE_CANDIDATE,
 +        &functions::MUST_USE_UNIT,
 +        &functions::NOT_UNSAFE_PTR_ARG_DEREF,
 +        &functions::RESULT_UNIT_ERR,
 +        &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::COMPARISON_TO_EMPTY,
 +        &len_zero::LEN_WITHOUT_IS_EMPTY,
 +        &len_zero::LEN_ZERO,
 +        &let_if_seq::USELESS_LET_IF_SEQ,
 +        &let_underscore::LET_UNDERSCORE_DROP,
 +        &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,
 +        &literal_representation::UNUSUAL_BYTE_GROUPINGS,
 +        &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::SAME_ITEM_PUSH,
 +        &loops::SINGLE_ELEMENT_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,
 +        &manual_ok_or::MANUAL_OK_OR,
 +        &manual_strip::MANUAL_STRIP,
 +        &manual_unwrap_or::MANUAL_UNWRAP_OR,
 +        &map_clone::MAP_CLONE,
 +        &map_err_ignore::MAP_ERR_IGNORE,
 +        &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_SAME_ARMS,
 +        &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::FROM_ITER_INSTEAD_OF_COLLECT,
 +        &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_COLLECT_RESULT_UNIT,
 +        &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_ADD_STR,
 +        &methods::SINGLE_CHAR_PATTERN,
 +        &methods::SKIP_WHILE_NEXT,
 +        &methods::STRING_EXTEND_CHARS,
 +        &methods::SUSPICIOUS_MAP,
 +        &methods::UNINIT_ASSUMED_INIT,
 +        &methods::UNNECESSARY_FILTER_MAP,
 +        &methods::UNNECESSARY_FOLD,
 +        &methods::UNNECESSARY_LAZY_EVALUATIONS,
 +        &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,
 +        &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_mutex_lock::MUT_MUTEX_LOCK,
 +        &mut_reference::UNNECESSARY_MUT_PASSED,
 +        &mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
 +        &mutex_atomic::MUTEX_ATOMIC,
 +        &mutex_atomic::MUTEX_INTEGER,
 +        &needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
 +        &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_in_result_fn::PANIC_IN_RESULT_FN,
 +        &panic_unimplemented::PANIC,
 +        &panic_unimplemented::TODO,
 +        &panic_unimplemented::UNIMPLEMENTED,
 +        &panic_unimplemented::UNREACHABLE,
 +        &partialeq_ne_impl::PARTIALEQ_NE_IMPL,
 +        &pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
 +        &pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
 +        &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_eq::PTR_EQ,
 +        &ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
 +        &question_mark::QUESTION_MARK,
 +        &ranges::MANUAL_RANGE_CONTAINS,
 +        &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_else::REDUNDANT_ELSE,
 +        &redundant_field_names::REDUNDANT_FIELD_NAMES,
 +        &redundant_pub_crate::REDUNDANT_PUB_CRATE,
 +        &redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
 +        &ref_option_ref::REF_OPTION_REF,
 +        &reference::DEREF_ADDROF,
 +        &reference::REF_IN_DEREF,
 +        &regex::INVALID_REGEX,
 +        &regex::TRIVIAL_REGEX,
 +        &repeat_once::REPEAT_ONCE,
 +        &returns::LET_AND_RETURN,
 +        &returns::NEEDLESS_RETURN,
 +        &self_assignment::SELF_ASSIGNMENT,
 +        &serde_api::SERDE_API_MISUSE,
 +        &shadow::SHADOW_REUSE,
 +        &shadow::SHADOW_SAME,
 +        &shadow::SHADOW_UNRELATED,
 +        &single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
 +        &size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
 +        &slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
 +        &stable_sort_primitive::STABLE_SORT_PRIMITIVE,
 +        &strings::STRING_ADD,
 +        &strings::STRING_ADD_ASSIGN,
 +        &strings::STRING_FROM_UTF8_AS_BYTES,
 +        &strings::STRING_LIT_AS_BYTES,
 +        &strings::STRING_TO_STRING,
 +        &strings::STR_TO_STRING,
 +        &suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS,
 +        &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,
 +        &to_string_in_display::TO_STRING_IN_DISPLAY,
 +        &trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS,
 +        &trait_bounds::TYPE_REPETITION_IN_BOUNDS,
 +        &transmute::CROSSPOINTER_TRANSMUTE,
 +        &transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
 +        &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,
 +        &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::RC_BUFFER,
 +        &types::REDUNDANT_ALLOCATION,
 +        &types::TYPE_COMPLEXITY,
 +        &types::UNIT_ARG,
 +        &types::UNIT_CMP,
 +        &types::UNNECESSARY_CAST,
 +        &types::VEC_BOX,
 +        &undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
 +        &unicode::INVISIBLE_CHARACTERS,
 +        &unicode::NON_ASCII_LITERAL,
 +        &unicode::UNICODE_NOT_NFC,
 +        &unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
 +        &unnamed_address::FN_ADDRESS_COMPARISONS,
 +        &unnamed_address::VTABLE_ADDRESS_COMPARISONS,
 +        &unnecessary_sort_by::UNNECESSARY_SORT_BY,
 +        &unnecessary_wraps::UNNECESSARY_WRAPS,
 +        &unnested_or_patterns::UNNESTED_OR_PATTERNS,
 +        &unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
 +        &unused_io_amount::UNUSED_IO_AMOUNT,
 +        &unused_self::UNUSED_SELF,
 +        &unused_unit::UNUSED_UNIT,
 +        &unwrap::PANICKING_UNWRAP,
 +        &unwrap::UNNECESSARY_UNWRAP,
 +        &unwrap_in_result::UNWRAP_IN_RESULT,
 +        &use_self::USE_SELF,
 +        &useless_conversion::USELESS_CONVERSION,
 +        &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_STDERR,
 +        &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,
 +        &zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
 +    ]);
 +    // end register lints, do not remove this comment, it’s used in `update_lints`
 +
 +    // all the internal lints
 +    #[cfg(feature = "internal-lints")]
 +    {
 +        store.register_early_pass(|| box utils::internal_lints::ClippyLintsInternal);
 +        store.register_early_pass(|| box utils::internal_lints::ProduceIce);
 +        store.register_late_pass(|| box utils::inspector::DeepCodeInspector);
 +        store.register_late_pass(|| box utils::internal_lints::CollapsibleCalls);
 +        store.register_late_pass(|| box utils::internal_lints::CompilerLintFunctions::new());
 +        store.register_late_pass(|| box utils::internal_lints::InvalidPaths);
 +        store.register_late_pass(|| box utils::internal_lints::InterningDefinedSymbol::default());
 +        store.register_late_pass(|| box utils::internal_lints::LintWithoutLintPass::default());
 +        store.register_late_pass(|| box utils::internal_lints::MatchTypeOnDiagItem);
 +        store.register_late_pass(|| box utils::internal_lints::OuterExpnDataPass);
 +    }
 +    store.register_late_pass(|| box utils::author::Author);
 +    store.register_late_pass(|| box await_holding_invalid::AwaitHolding);
 +    store.register_late_pass(|| box serde_api::SerdeAPI);
 +    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 ptr_eq::PtrEq);
 +    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 collapsible_match::CollapsibleMatch);
 +    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);
 +
 +    let msrv = conf.msrv.as_ref().and_then(|s| {
 +        parse_msrv(s, None, None).or_else(|| {
 +            sess.err(&format!("error reading Clippy's configuration file. `{}` is not a valid Rust version", s));
 +            None
 +        })
 +    });
 +
 +    store.register_late_pass(move || box methods::Methods::new(msrv));
 +    store.register_late_pass(move || box matches::Matches::new(msrv));
 +    store.register_early_pass(move || box manual_non_exhaustive::ManualNonExhaustive::new(msrv));
 +    store.register_late_pass(move || box manual_strip::ManualStrip::new(msrv));
 +    store.register_early_pass(move || box redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv));
 +    store.register_early_pass(move || box redundant_field_names::RedundantFieldNames::new(msrv));
 +    store.register_late_pass(move || box checked_conversions::CheckedConversions::new(msrv));
 +    store.register_late_pass(move || box mem_replace::MemReplace::new(msrv));
 +    store.register_late_pass(move || box ranges::Ranges::new(msrv));
++    store.register_late_pass(move || box from_over_into::FromOverInto::new(msrv));
 +    store.register_late_pass(move || box use_self::UseSelf::new(msrv));
 +    store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv));
 +
 +    store.register_late_pass(|| box size_of_in_element_count::SizeOfInElementCount);
 +    store.register_late_pass(|| box map_clone::MapClone);
 +    store.register_late_pass(|| box map_err_ignore::MapErrIgnore);
 +    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 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 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(move || box vec::UselessVec{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 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 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 pass_by_ref_or_value = pass_by_ref_or_value::PassByRefOrValue::new(
 +        conf.trivial_copy_size_limit,
 +        conf.pass_by_value_size_limit,
 +        &sess.target,
 +    );
 +    store.register_late_pass(move || box pass_by_ref_or_value);
 +    store.register_late_pass(|| box ref_option_ref::RefOptionRef);
 +    store.register_late_pass(|| box try_err::TryErr);
 +    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_early_pass(|| box suspicious_operation_groupings::SuspiciousOperationGroupings);
 +    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 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 unnecessary_wraps::UnnecessaryWraps);
 +    store.register_late_pass(|| box types::RefToMut);
 +    store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants);
 +    store.register_late_pass(|| box transmuting_null::TransmutingNull);
 +    store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);
 +    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_late_pass(|| box to_string_in_display::ToStringInDisplay::new());
 +    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 unused_unit::UnusedUnit);
 +    store.register_late_pass(|| box returns::Return);
 +    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_else::RedundantElse);
 +    store.register_late_pass(|| box create_dir::CreateDir);
 +    store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
 +    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);
 +    let literal_representation_lint_fraction_readability = conf.unreadable_literal_lint_fractions;
 +    store.register_early_pass(move || box literal_representation::LiteralDigitGrouping::new(literal_representation_lint_fraction_readability));
 +    let literal_representation_threshold = conf.literal_representation_threshold;
 +    store.register_early_pass(move || box literal_representation::DecimalLiteralRepresentation::new(literal_representation_threshold));
 +    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 default::Default::default());
 +    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_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 if_let_mutex::IfLetMutex);
 +    store.register_late_pass(|| box mut_mutex_lock::MutMutexLock);
 +    store.register_late_pass(|| box match_on_vec_items::MatchOnVecItems);
 +    store.register_late_pass(|| box manual_async_fn::ManualAsyncFn);
 +    store.register_late_pass(|| box vec_resize_to_zero::VecResizeToZero);
 +    store.register_late_pass(|| box panic_in_result_fn::PanicInResultFn);
 +    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 stable_sort_primitive::StableSortPrimitive);
 +    store.register_late_pass(|| box repeat_once::RepeatOnce);
 +    store.register_late_pass(|| box unwrap_in_result::UnwrapInResult);
 +    store.register_late_pass(|| box self_assignment::SelfAssignment);
 +    store.register_late_pass(|| box manual_unwrap_or::ManualUnwrapOr);
 +    store.register_late_pass(|| box manual_ok_or::ManualOkOr);
 +    store.register_late_pass(|| box float_equality_without_abs::FloatEqualityWithoutAbs);
 +    store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
 +    let disallowed_methods = conf.disallowed_methods.iter().cloned().collect::<FxHashSet<_>>();
 +    store.register_late_pass(move || box disallowed_method::DisallowedMethod::new(&disallowed_methods));
 +    store.register_early_pass(|| box asm_syntax::InlineAsmX86AttSyntax);
 +    store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
 +    store.register_late_pass(|| box undropped_manually_drops::UndroppedManuallyDrops);
 +    store.register_late_pass(|| box strings::StrToString);
 +    store.register_late_pass(|| box strings::StringToString);
 +    store.register_late_pass(|| box zero_sized_map_values::ZeroSizedMapValues);
 +
 +    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(&asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
 +        LintId::of(&asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
 +        LintId::of(&create_dir::CREATE_DIR),
 +        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(&map_err_ignore::MAP_ERR_IGNORE),
 +        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_in_result_fn::PANIC_IN_RESULT_FN),
 +        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(&strings::STRING_TO_STRING),
 +        LintId::of(&strings::STR_TO_STRING),
 +        LintId::of(&types::RC_BUFFER),
 +        LintId::of(&unwrap_in_result::UNWRAP_IN_RESULT),
 +        LintId::of(&verbose_file_reads::VERBOSE_FILE_READS),
 +        LintId::of(&write::PRINT_STDERR),
 +        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_invalid::AWAIT_HOLDING_LOCK),
 +        LintId::of(&await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
 +        LintId::of(&bit_mask::VERBOSE_BIT_MASK),
 +        LintId::of(&checked_conversions::CHECKED_CONVERSIONS),
 +        LintId::of(&copies::SAME_FUNCTIONS_IN_IF_CONDITION),
 +        LintId::of(&copy_iterator::COPY_ITERATOR),
 +        LintId::of(&default::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(&let_underscore::LET_UNDERSCORE_DROP),
 +        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(&manual_ok_or::MANUAL_OK_OR),
 +        LintId::of(&match_on_vec_items::MATCH_ON_VEC_ITEMS),
 +        LintId::of(&matches::MATCH_BOOL),
 +        LintId::of(&matches::MATCH_SAME_ARMS),
 +        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(&pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
 +        LintId::of(&pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
 +        LintId::of(&ranges::RANGE_MINUS_ONE),
 +        LintId::of(&ranges::RANGE_PLUS_ONE),
 +        LintId::of(&redundant_else::REDUNDANT_ELSE),
 +        LintId::of(&ref_option_ref::REF_OPTION_REF),
 +        LintId::of(&shadow::SHADOW_UNRELATED),
 +        LintId::of(&strings::STRING_ADD_ASSIGN),
 +        LintId::of(&trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
 +        LintId::of(&trait_bounds::TYPE_REPETITION_IN_BOUNDS),
 +        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),
 +        LintId::of(&zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
 +    ]);
 +
 +    #[cfg(feature = "internal-lints")]
 +    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::INTERNING_DEFINED_SYMBOL),
 +        LintId::of(&utils::internal_lints::INVALID_PATHS),
 +        LintId::of(&utils::internal_lints::LINT_WITHOUT_LINT_PASS),
 +        LintId::of(&utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
 +        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(&async_yields_async::ASYNC_YIELDS_ASYNC),
 +        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(&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(&collapsible_match::COLLAPSIBLE_MATCH),
 +        LintId::of(&comparison_chain::COMPARISON_CHAIN),
 +        LintId::of(&copies::IFS_SAME_COND),
 +        LintId::of(&copies::IF_SAME_THEN_ELSE),
 +        LintId::of(&default::FIELD_REASSIGN_WITH_DEFAULT),
 +        LintId::of(&derive::DERIVE_HASH_XOR_EQ),
 +        LintId::of(&derive::DERIVE_ORD_XOR_PARTIAL_ORD),
 +        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_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_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
 +        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(&from_over_into::FROM_OVER_INTO),
 +        LintId::of(&functions::DOUBLE_MUST_USE),
 +        LintId::of(&functions::MUST_USE_UNIT),
 +        LintId::of(&functions::NOT_UNSAFE_PTR_ARG_DEREF),
 +        LintId::of(&functions::RESULT_UNIT_ERR),
 +        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::COMPARISON_TO_EMPTY),
 +        LintId::of(&len_zero::LEN_WITHOUT_IS_EMPTY),
 +        LintId::of(&len_zero::LEN_ZERO),
 +        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(&literal_representation::UNUSUAL_BYTE_GROUPINGS),
 +        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::SAME_ITEM_PUSH),
 +        LintId::of(&loops::SINGLE_ELEMENT_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(&manual_strip::MANUAL_STRIP),
 +        LintId::of(&manual_unwrap_or::MANUAL_UNWRAP_OR),
 +        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::FROM_ITER_INSTEAD_OF_COLLECT),
 +        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::MAP_COLLECT_RESULT_UNIT),
 +        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_ADD_STR),
 +        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::UNINIT_ASSUMED_INIT),
 +        LintId::of(&methods::UNNECESSARY_FILTER_MAP),
 +        LintId::of(&methods::UNNECESSARY_FOLD),
 +        LintId::of(&methods::UNNECESSARY_LAZY_EVALUATIONS),
 +        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_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_mutex_lock::MUT_MUTEX_LOCK),
 +        LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
 +        LintId::of(&mutex_atomic::MUTEX_ATOMIC),
 +        LintId::of(&needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
 +        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(&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_eq::PTR_EQ),
 +        LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
 +        LintId::of(&question_mark::QUESTION_MARK),
 +        LintId::of(&ranges::MANUAL_RANGE_CONTAINS),
 +        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::LET_AND_RETURN),
 +        LintId::of(&returns::NEEDLESS_RETURN),
 +        LintId::of(&self_assignment::SELF_ASSIGNMENT),
 +        LintId::of(&serde_api::SERDE_API_MISUSE),
 +        LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
 +        LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
 +        LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
 +        LintId::of(&stable_sort_primitive::STABLE_SORT_PRIMITIVE),
 +        LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
 +        LintId::of(&suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
 +        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(&to_string_in_display::TO_STRING_IN_DISPLAY),
 +        LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),
 +        LintId::of(&transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
 +        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(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
 +        LintId::of(&unicode::INVISIBLE_CHARACTERS),
 +        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(&unnecessary_wraps::UNNECESSARY_WRAPS),
 +        LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
 +        LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
 +        LintId::of(&unused_unit::UNUSED_UNIT),
 +        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(&blacklisted_name::BLACKLISTED_NAME),
 +        LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
 +        LintId::of(&collapsible_if::COLLAPSIBLE_IF),
 +        LintId::of(&collapsible_match::COLLAPSIBLE_MATCH),
 +        LintId::of(&comparison_chain::COMPARISON_CHAIN),
 +        LintId::of(&default::FIELD_REASSIGN_WITH_DEFAULT),
 +        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(&from_over_into::FROM_OVER_INTO),
 +        LintId::of(&functions::DOUBLE_MUST_USE),
 +        LintId::of(&functions::MUST_USE_UNIT),
 +        LintId::of(&functions::RESULT_UNIT_ERR),
 +        LintId::of(&if_let_some_result::IF_LET_SOME_RESULT),
 +        LintId::of(&inherent_to_string::INHERENT_TO_STRING),
 +        LintId::of(&len_zero::COMPARISON_TO_EMPTY),
 +        LintId::of(&len_zero::LEN_WITHOUT_IS_EMPTY),
 +        LintId::of(&len_zero::LEN_ZERO),
 +        LintId::of(&literal_representation::INCONSISTENT_DIGIT_GROUPING),
 +        LintId::of(&literal_representation::UNUSUAL_BYTE_GROUPINGS),
 +        LintId::of(&loops::EMPTY_LOOP),
 +        LintId::of(&loops::FOR_KV_MAP),
 +        LintId::of(&loops::NEEDLESS_RANGE_LOOP),
 +        LintId::of(&loops::SAME_ITEM_PUSH),
 +        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::FROM_ITER_INSTEAD_OF_COLLECT),
 +        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::MAP_COLLECT_RESULT_UNIT),
 +        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::SINGLE_CHAR_ADD_STR),
 +        LintId::of(&methods::STRING_EXTEND_CHARS),
 +        LintId::of(&methods::UNNECESSARY_FOLD),
 +        LintId::of(&methods::UNNECESSARY_LAZY_EVALUATIONS),
 +        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_mutex_lock::MUT_MUTEX_LOCK),
 +        LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
 +        LintId::of(&neg_multiply::NEG_MULTIPLY),
 +        LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
 +        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(&ptr::CMP_NULL),
 +        LintId::of(&ptr::PTR_ARG),
 +        LintId::of(&ptr_eq::PTR_EQ),
 +        LintId::of(&question_mark::QUESTION_MARK),
 +        LintId::of(&ranges::MANUAL_RANGE_CONTAINS),
 +        LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
 +        LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
 +        LintId::of(&regex::TRIVIAL_REGEX),
 +        LintId::of(&returns::LET_AND_RETURN),
 +        LintId::of(&returns::NEEDLESS_RETURN),
 +        LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
 +        LintId::of(&suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
 +        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(&unused_unit::UNUSED_UNIT),
 +        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::SINGLE_ELEMENT_LOOP),
 +        LintId::of(&loops::WHILE_LET_LOOP),
 +        LintId::of(&manual_strip::MANUAL_STRIP),
 +        LintId::of(&manual_unwrap_or::MANUAL_UNWRAP_OR),
 +        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_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
 +        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(&strings::STRING_FROM_UTF8_AS_BYTES),
 +        LintId::of(&swap::MANUAL_SWAP),
 +        LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT),
 +        LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),
 +        LintId::of(&transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
 +        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(&unnecessary_wraps::UNNECESSARY_WRAPS),
 +        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(&async_yields_async::ASYNC_YIELDS_ASYNC),
 +        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(&derive::DERIVE_ORD_XOR_PARTIAL_ORD),
 +        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(&float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
 +        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::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(&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(&self_assignment::SELF_ASSIGNMENT),
 +        LintId::of(&serde_api::SERDE_API_MISUSE),
 +        LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
 +        LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
 +        LintId::of(&swap::ALMOST_SWAPPED),
 +        LintId::of(&to_string_in_display::TO_STRING_IN_DISPLAY),
 +        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(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
 +        LintId::of(&unicode::INVISIBLE_CHARACTERS),
 +        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(&stable_sort_primitive::STABLE_SORT_PRIMITIVE),
 +        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(&disallowed_method::DISALLOWED_METHOD),
 +        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(&strings::STRING_LIT_AS_BYTES),
 +        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(
 +        "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");
 +    ls.register_renamed("clippy::zero_width_space", "clippy::invisible_characters");
 +    ls.register_renamed("clippy::single_char_push_str", "clippy::single_char_add_str");
 +}
 +
 +// 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 b4b4b3dc18d51a290feee50ee8a917b8849bb800,0000000000000000000000000000000000000000..bb52888883af5a90c1e366d7a688d8b2b77a186e
mode 100644,000000..100644
--- /dev/null
@@@ -1,232 -1,0 +1,232 @@@
-             if cx.sess().opts.edition == Edition::Edition2018;
 +use crate::utils::{in_macro, snippet, span_lint_and_sugg};
 +use hir::def::{DefKind, Res};
 +use if_chain::if_chain;
 +use rustc_ast::ast;
 +use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 +use rustc_errors::Applicability;
 +use rustc_hir as hir;
 +use rustc_lint::{LateContext, LateLintPass, LintContext};
 +use rustc_session::{declare_tool_lint, impl_lint_pass};
 +use rustc_span::{edition::Edition, Span};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for `#[macro_use] use...`.
 +    ///
 +    /// **Why is this bad?** Since the Rust 2018 edition you can import
 +    /// macro's directly, this is considered idiomatic.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust,ignore
 +    /// #[macro_use]
 +    /// use some_macro;
 +    /// ```
 +    pub MACRO_USE_IMPORTS,
 +    pedantic,
 +    "#[macro_use] is no longer needed"
 +}
 +
 +const BRACKETS: &[char] = &['<', '>'];
 +
 +#[derive(Clone, Debug, PartialEq, Eq)]
 +struct PathAndSpan {
 +    path: String,
 +    span: Span,
 +}
 +
 +/// `MacroRefData` includes the name of the macro
 +/// and the path from `SourceMap::span_to_filename`.
 +#[derive(Debug, Clone)]
 +pub struct MacroRefData {
 +    name: String,
 +    path: String,
 +}
 +
 +impl MacroRefData {
 +    pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self {
 +        let mut path = cx.sess().source_map().span_to_filename(callee).to_string();
 +
 +        // std lib paths are <::std::module::file type>
 +        // so remove brackets, space and type.
 +        if path.contains('<') {
 +            path = path.replace(BRACKETS, "");
 +        }
 +        if path.contains(' ') {
 +            path = path.split(' ').next().unwrap().to_string();
 +        }
 +        Self { name, path }
 +    }
 +}
 +
 +#[derive(Default)]
 +#[allow(clippy::module_name_repetitions)]
 +pub struct MacroUseImports {
 +    /// the actual import path used and the span of the attribute above it.
 +    imports: Vec<(String, Span)>,
 +    /// the span of the macro reference, kept to ensure only one reference is used per macro call.
 +    collected: FxHashSet<Span>,
 +    mac_refs: Vec<MacroRefData>,
 +}
 +
 +impl_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]);
 +
 +impl MacroUseImports {
 +    fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
 +        let call_site = span.source_callsite();
 +        let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
 +        if let Some(callee) = span.source_callee() {
 +            if !self.collected.contains(&call_site) {
 +                let name = if name.contains("::") {
 +                    name.split("::").last().unwrap().to_string()
 +                } else {
 +                    name.to_string()
 +                };
 +
 +                self.mac_refs.push(MacroRefData::new(name, callee.def_site, cx));
 +                self.collected.insert(call_site);
 +            }
 +        }
 +    }
 +
 +    fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) {
 +        let call_site = span.source_callsite();
 +        let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
 +        if let Some(callee) = span.source_callee() {
 +            if !self.collected.contains(&call_site) {
 +                self.mac_refs
 +                    .push(MacroRefData::new(name.to_string(), callee.def_site, cx));
 +                self.collected.insert(call_site);
 +            }
 +        }
 +    }
 +}
 +
 +impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
 +    fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
 +        if_chain! {
++            if cx.sess().opts.edition >= Edition::Edition2018;
 +            if let hir::ItemKind::Use(path, _kind) = &item.kind;
 +            if let Some(mac_attr) = item
 +                .attrs
 +                .iter()
 +                .find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
 +            if let Res::Def(DefKind::Mod, id) = path.res;
 +            then {
 +                for kid in cx.tcx.item_children(id).iter() {
 +                    if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
 +                        let span = mac_attr.span;
 +                        let def_path = cx.tcx.def_path_str(mac_id);
 +                        self.imports.push((def_path, span));
 +                    }
 +                }
 +            } else {
 +                if in_macro(item.span) {
 +                    self.push_unique_macro_pat_ty(cx, item.span);
 +                }
 +            }
 +        }
 +    }
 +    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
 +        if in_macro(attr.span) {
 +            self.push_unique_macro(cx, attr.span);
 +        }
 +    }
 +    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
 +        if in_macro(expr.span) {
 +            self.push_unique_macro(cx, expr.span);
 +        }
 +    }
 +    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {
 +        if in_macro(stmt.span) {
 +            self.push_unique_macro(cx, stmt.span);
 +        }
 +    }
 +    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) {
 +        if in_macro(pat.span) {
 +            self.push_unique_macro_pat_ty(cx, pat.span);
 +        }
 +    }
 +    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) {
 +        if in_macro(ty.span) {
 +            self.push_unique_macro_pat_ty(cx, ty.span);
 +        }
 +    }
 +    #[allow(clippy::too_many_lines)]
 +    fn check_crate_post(&mut self, cx: &LateContext<'_>, _krate: &hir::Crate<'_>) {
 +        let mut used = FxHashMap::default();
 +        let mut check_dup = vec![];
 +        for (import, span) in &self.imports {
 +            let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name));
 +
 +            if let Some(idx) = found_idx {
 +                let _ = self.mac_refs.remove(idx);
 +                let seg = import.split("::").collect::<Vec<_>>();
 +
 +                match seg.as_slice() {
 +                    // an empty path is impossible
 +                    // a path should always consist of 2 or more segments
 +                    [] | [_] => return,
 +                    [root, item] => {
 +                        if !check_dup.contains(&(*item).to_string()) {
 +                            used.entry(((*root).to_string(), span))
 +                                .or_insert_with(Vec::new)
 +                                .push((*item).to_string());
 +                            check_dup.push((*item).to_string());
 +                        }
 +                    },
 +                    [root, rest @ ..] => {
 +                        if rest.iter().all(|item| !check_dup.contains(&(*item).to_string())) {
 +                            let filtered = rest
 +                                .iter()
 +                                .filter_map(|item| {
 +                                    if check_dup.contains(&(*item).to_string()) {
 +                                        None
 +                                    } else {
 +                                        Some((*item).to_string())
 +                                    }
 +                                })
 +                                .collect::<Vec<_>>();
 +                            used.entry(((*root).to_string(), span))
 +                                .or_insert_with(Vec::new)
 +                                .push(filtered.join("::"));
 +                            check_dup.extend(filtered);
 +                        } else {
 +                            let rest = rest.to_vec();
 +                            used.entry(((*root).to_string(), span))
 +                                .or_insert_with(Vec::new)
 +                                .push(rest.join("::"));
 +                            check_dup.extend(rest.iter().map(ToString::to_string));
 +                        }
 +                    },
 +                }
 +            }
 +        }
 +
 +        let mut suggestions = vec![];
 +        for ((root, span), path) in used {
 +            if path.len() == 1 {
 +                suggestions.push((span, format!("{}::{}", root, path[0])))
 +            } else {
 +                suggestions.push((span, format!("{}::{{{}}}", root, path.join(", "))))
 +            }
 +        }
 +
 +        // If mac_refs is not empty we have encountered an import we could not handle
 +        // such as `std::prelude::v1::foo` or some other macro that expands to an import.
 +        if self.mac_refs.is_empty() {
 +            for (span, import) in suggestions {
 +                let help = format!("use {};", import);
 +                span_lint_and_sugg(
 +                    cx,
 +                    MACRO_USE_IMPORTS,
 +                    *span,
 +                    "`macro_use` attributes are no longer needed in the Rust 2018 edition",
 +                    "remove the attribute and import the macro directly, try",
 +                    help,
 +                    Applicability::MaybeIncorrect,
 +                )
 +            }
 +        }
 +    }
 +}
index 7b3b450ef93e943fad6882126463f32a42617ebd,0000000000000000000000000000000000000000..29439e52c48e1252fda7a8e275741ff127a413e6
mode 100644,000000..100644
--- /dev/null
@@@ -1,200 -1,0 +1,200 @@@
-                             if let Some(ret_pos) = position_before_rarrow(header_snip.clone());
 +use crate::utils::paths::FUTURE_FROM_GENERATOR;
 +use crate::utils::{match_function_call, position_before_rarrow, snippet_block, snippet_opt, span_lint_and_then};
 +use if_chain::if_chain;
 +use rustc_errors::Applicability;
 +use rustc_hir::intravisit::FnKind;
 +use rustc_hir::{
 +    AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
 +    IsAsync, ItemKind, LifetimeName, TraitRef, Ty, TyKind, TypeBindingKind,
 +};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::Span;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** It checks for manual implementations of `async` functions.
 +    ///
 +    /// **Why is this bad?** It's more idiomatic to use the dedicated syntax.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust
 +    /// use std::future::Future;
 +    ///
 +    /// fn foo() -> impl Future<Output = i32> { async { 42 } }
 +    /// ```
 +    /// Use instead:
 +    /// ```rust
 +    /// async fn foo() -> i32 { 42 }
 +    /// ```
 +    pub MANUAL_ASYNC_FN,
 +    style,
 +    "manual implementations of `async` functions can be simplified using the dedicated syntax"
 +}
 +
 +declare_lint_pass!(ManualAsyncFn => [MANUAL_ASYNC_FN]);
 +
 +impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
 +    fn check_fn(
 +        &mut self,
 +        cx: &LateContext<'tcx>,
 +        kind: FnKind<'tcx>,
 +        decl: &'tcx FnDecl<'_>,
 +        body: &'tcx Body<'_>,
 +        span: Span,
 +        _: HirId,
 +    ) {
 +        if_chain! {
 +            if let Some(header) = kind.header();
 +            if let IsAsync::NotAsync = header.asyncness;
 +            // Check that this function returns `impl Future`
 +            if let FnRetTy::Return(ret_ty) = decl.output;
 +            if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
 +            if let Some(output) = future_output_ty(trait_ref);
 +            if captures_all_lifetimes(decl.inputs, &output_lifetimes);
 +            // Check that the body of the function consists of one async block
 +            if let ExprKind::Block(block, _) = body.value.kind;
 +            if block.stmts.is_empty();
 +            if let Some(closure_body) = desugared_async_block(cx, block);
 +            then {
 +                let header_span = span.with_hi(ret_ty.span.hi());
 +
 +                span_lint_and_then(
 +                    cx,
 +                    MANUAL_ASYNC_FN,
 +                    header_span,
 +                    "this function can be simplified using the `async fn` syntax",
 +                    |diag| {
 +                        if_chain! {
 +                            if let Some(header_snip) = snippet_opt(cx, header_span);
++                            if let Some(ret_pos) = position_before_rarrow(&header_snip);
 +                            if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
 +                            then {
 +                                let help = format!("make the function `async` and {}", ret_sugg);
 +                                diag.span_suggestion(
 +                                    header_span,
 +                                    &help,
 +                                    format!("async {}{}", &header_snip[..ret_pos], ret_snip),
 +                                    Applicability::MachineApplicable
 +                                );
 +
 +                                let body_snip = snippet_block(cx, closure_body.value.span, "..", Some(block.span));
 +                                diag.span_suggestion(
 +                                    block.span,
 +                                    "move the body of the async block to the enclosing function",
 +                                    body_snip.to_string(),
 +                                    Applicability::MachineApplicable
 +                                );
 +                            }
 +                        }
 +                    },
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +fn future_trait_ref<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    ty: &'tcx Ty<'tcx>,
 +) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
 +    if_chain! {
 +        if let TyKind::OpaqueDef(item_id, bounds) = ty.kind;
 +        let item = cx.tcx.hir().item(item_id.id);
 +        if let ItemKind::OpaqueTy(opaque) = &item.kind;
 +        if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
 +            if let GenericBound::Trait(poly, _) = bound {
 +                Some(&poly.trait_ref)
 +            } else {
 +                None
 +            }
 +        });
 +        if trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait();
 +        then {
 +            let output_lifetimes = bounds
 +                .iter()
 +                .filter_map(|bound| {
 +                    if let GenericArg::Lifetime(lt) = bound {
 +                        Some(lt.name)
 +                    } else {
 +                        None
 +                    }
 +                })
 +                .collect();
 +
 +            return Some((trait_ref, output_lifetimes));
 +        }
 +    }
 +
 +    None
 +}
 +
 +fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> {
 +    if_chain! {
 +        if let Some(segment) = trait_ref.path.segments.last();
 +        if let Some(args) = segment.args;
 +        if args.bindings.len() == 1;
 +        let binding = &args.bindings[0];
 +        if binding.ident.as_str() == "Output";
 +        if let TypeBindingKind::Equality{ty: output} = binding.kind;
 +        then {
 +            return Some(output)
 +        }
 +    }
 +
 +    None
 +}
 +
 +fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) -> bool {
 +    let input_lifetimes: Vec<LifetimeName> = inputs
 +        .iter()
 +        .filter_map(|ty| {
 +            if let TyKind::Rptr(lt, _) = ty.kind {
 +                Some(lt.name)
 +            } else {
 +                None
 +            }
 +        })
 +        .collect();
 +
 +    // The lint should trigger in one of these cases:
 +    // - There are no input lifetimes
 +    // - There's only one output lifetime bound using `+ '_`
 +    // - All input lifetimes are explicitly bound to the output
 +    input_lifetimes.is_empty()
 +        || (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Underscore))
 +        || input_lifetimes
 +            .iter()
 +            .all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
 +}
 +
 +fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {
 +    if_chain! {
 +        if let Some(block_expr) = block.expr;
 +        if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR);
 +        if args.len() == 1;
 +        if let Expr{kind: ExprKind::Closure(_, _, body_id, ..), ..} = args[0];
 +        let closure_body = cx.tcx.hir().body(body_id);
 +        if let Some(GeneratorKind::Async(AsyncGeneratorKind::Block)) = closure_body.generator_kind;
 +        then {
 +            return Some(closure_body);
 +        }
 +    }
 +
 +    None
 +}
 +
 +fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str, String)> {
 +    match output.kind {
 +        TyKind::Tup(tys) if tys.is_empty() => {
 +            let sugg = "remove the return type";
 +            Some((sugg, "".into()))
 +        },
 +        _ => {
 +            let sugg = "return the output of the future directly";
 +            snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {}", snip)))
 +        },
 +    }
 +}
index f3c0515b9bcde0e9e4522a9a517dc03e93fa8d38,0000000000000000000000000000000000000000..76fe8e776eafda01f6d642edb19270a5182ddba2
mode 100644,000000..100644
--- /dev/null
@@@ -1,147 -1,0 +1,147 @@@
-     /// **Why is this bad?** This map_err throws away the original error rather than allowing the enum to contain and report the cause of the error
 +use crate::utils::span_lint_and_help;
 +
 +use rustc_hir::{CaptureBy, Expr, ExprKind, PatKind};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for instances of `map_err(|_| Some::Enum)`
 +    ///
-                                     "Consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)",
++    /// **Why is this bad?** This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// Before:
 +    /// ```rust
 +    /// use std::fmt;
 +    ///
 +    /// #[derive(Debug)]
 +    /// enum Error {
 +    ///     Indivisible,
 +    ///     Remainder(u8),
 +    /// }
 +    ///
 +    /// impl fmt::Display for Error {
 +    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 +    ///         match self {
 +    ///             Error::Indivisible => write!(f, "could not divide input by three"),
 +    ///             Error::Remainder(remainder) => write!(
 +    ///                 f,
 +    ///                 "input is not divisible by three, remainder = {}",
 +    ///                 remainder
 +    ///             ),
 +    ///         }
 +    ///     }
 +    /// }
 +    ///
 +    /// impl std::error::Error for Error {}
 +    ///
 +    /// fn divisible_by_3(input: &str) -> Result<(), Error> {
 +    ///     input
 +    ///         .parse::<i32>()
 +    ///         .map_err(|_| Error::Indivisible)
 +    ///         .map(|v| v % 3)
 +    ///         .and_then(|remainder| {
 +    ///             if remainder == 0 {
 +    ///                 Ok(())
 +    ///             } else {
 +    ///                 Err(Error::Remainder(remainder as u8))
 +    ///             }
 +    ///         })
 +    /// }
 +    ///  ```
 +    ///
 +    ///  After:
 +    ///  ```rust
 +    /// use std::{fmt, num::ParseIntError};
 +    ///
 +    /// #[derive(Debug)]
 +    /// enum Error {
 +    ///     Indivisible(ParseIntError),
 +    ///     Remainder(u8),
 +    /// }
 +    ///
 +    /// impl fmt::Display for Error {
 +    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 +    ///         match self {
 +    ///             Error::Indivisible(_) => write!(f, "could not divide input by three"),
 +    ///             Error::Remainder(remainder) => write!(
 +    ///                 f,
 +    ///                 "input is not divisible by three, remainder = {}",
 +    ///                 remainder
 +    ///             ),
 +    ///         }
 +    ///     }
 +    /// }
 +    ///
 +    /// impl std::error::Error for Error {
 +    ///     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
 +    ///         match self {
 +    ///             Error::Indivisible(source) => Some(source),
 +    ///             _ => None,
 +    ///         }
 +    ///     }
 +    /// }
 +    ///
 +    /// fn divisible_by_3(input: &str) -> Result<(), Error> {
 +    ///     input
 +    ///         .parse::<i32>()
 +    ///         .map_err(Error::Indivisible)
 +    ///         .map(|v| v % 3)
 +    ///         .and_then(|remainder| {
 +    ///             if remainder == 0 {
 +    ///                 Ok(())
 +    ///             } else {
 +    ///                 Err(Error::Remainder(remainder as u8))
 +    ///             }
 +    ///         })
 +    /// }
 +    /// ```
 +    pub MAP_ERR_IGNORE,
 +    restriction,
 +    "`map_err` should not ignore the original error"
 +}
 +
 +declare_lint_pass!(MapErrIgnore => [MAP_ERR_IGNORE]);
 +
 +impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
 +    // do not try to lint if this is from a macro or desugaring
 +    fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
 +        if e.span.from_expansion() {
 +            return;
 +        }
 +
 +        // check if this is a method call (e.g. x.foo())
 +        if let ExprKind::MethodCall(ref method, _t_span, ref args, _) = e.kind {
 +            // only work if the method name is `map_err` and there are only 2 arguments (e.g. x.map_err(|_|[1]
 +            // Enum::Variant[2]))
 +            if method.ident.as_str() == "map_err" && args.len() == 2 {
 +                // make sure the first argument is a closure, and grab the CaptureRef, body_id, and body_span fields
 +                if let ExprKind::Closure(capture, _, body_id, body_span, _) = args[1].kind {
 +                    // check if this is by Reference (meaning there's no move statement)
 +                    if capture == CaptureBy::Ref {
 +                        // Get the closure body to check the parameters and values
 +                        let closure_body = cx.tcx.hir().body(body_id);
 +                        // make sure there's only one parameter (`|_|`)
 +                        if closure_body.params.len() == 1 {
 +                            // make sure that parameter is the wild token (`_`)
 +                            if let PatKind::Wild = closure_body.params[0].pat.kind {
 +                                // span the area of the closure capture and warn that the
 +                                // original error will be thrown away
 +                                span_lint_and_help(
 +                                    cx,
 +                                    MAP_ERR_IGNORE,
 +                                    body_span,
 +                                    "`map_err(|_|...` wildcard pattern discards the original error",
 +                                    None,
++                                    "consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)",
 +                                );
 +                            }
 +                        }
 +                    }
 +                }
 +            }
 +        }
 +    }
 +}
index dcb643a28aebcceb0cc2420ccde03a87d851589b,0000000000000000000000000000000000000000..c494a713631311403392539b2a3a8a6760c22c5c
mode 100644,000000..100644
--- /dev/null
@@@ -1,329 -1,0 +1,359 @@@
-                 let mut ty_snippet = None;
-                 if_chain! {
-                     if let TyKind::Path(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).kind;
-                     if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last();
-                     then {
-                         let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg {
-                             GenericArg::Type(ty) => Some(ty),
-                             _ => None,
-                         }).collect();
-                         if types.len() == 1 {
-                             ty_snippet = snippet_opt(cx, types[0].span);
-                         }
-                     }
-                 };
 +//! Checks for usage of  `&Vec[_]` and `&String`.
 +
 +use crate::utils::ptr::get_spans;
 +use crate::utils::{
 +    is_allowed, is_type_diagnostic_item, match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_sugg,
 +    span_lint_and_then, walk_ptrs_hir_ty,
 +};
 +use if_chain::if_chain;
 +use rustc_errors::Applicability;
 +use rustc_hir::{
 +    BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind,
 +    Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
 +};
 +use rustc_lint::{LateContext, LateLintPass};
 +use rustc_middle::ty;
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +use rustc_span::{sym, MultiSpan};
 +use std::borrow::Cow;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** This lint checks for function arguments of type `&String`
 +    /// or `&Vec` unless the references are mutable. It will also suggest you
 +    /// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`
 +    /// calls.
 +    ///
 +    /// **Why is this bad?** Requiring the argument to be of the specific size
 +    /// makes the function less useful for no benefit; slices in the form of `&[T]`
 +    /// or `&str` usually suffice and can be obtained from other types, too.
 +    ///
 +    /// **Known problems:** The lint does not follow data. So if you have an
 +    /// argument `x` and write `let y = x; y.clone()` the lint will not suggest
 +    /// changing that `.clone()` to `.to_owned()`.
 +    ///
 +    /// Other functions called from this function taking a `&String` or `&Vec`
 +    /// argument may also fail to compile if you change the argument. Applying
 +    /// this lint on them will fix the problem, but they may be in other crates.
 +    ///
 +    /// One notable example of a function that may cause issues, and which cannot
 +    /// easily be changed due to being in the standard library is `Vec::contains`.
 +    /// when called on a `Vec<Vec<T>>`. If a `&Vec` is passed to that method then
 +    /// it will compile, but if a `&[T]` is passed then it will not compile.
 +    ///
 +    /// ```ignore
 +    /// fn cannot_take_a_slice(v: &Vec<u8>) -> bool {
 +    ///     let vec_of_vecs: Vec<Vec<u8>> = some_other_fn();
 +    ///
 +    ///     vec_of_vecs.contains(v)
 +    /// }
 +    /// ```
 +    ///
 +    /// Also there may be `fn(&Vec)`-typed references pointing to your function.
 +    /// If you have them, you will get a compiler error after applying this lint's
 +    /// suggestions. You then have the choice to undo your changes or change the
 +    /// type of the reference.
 +    ///
 +    /// Note that if the function is part of your public interface, there may be
 +    /// other crates referencing it, of which you may not be aware. Carefully
 +    /// deprecate the function before applying the lint suggestions in this case.
 +    ///
 +    /// **Example:**
 +    /// ```ignore
 +    /// // Bad
 +    /// fn foo(&Vec<u32>) { .. }
 +    ///
 +    /// // Good
 +    /// fn foo(&[u32]) { .. }
 +    /// ```
 +    pub PTR_ARG,
 +    style,
 +    "fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively"
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** This lint checks for equality comparisons with `ptr::null`
 +    ///
 +    /// **Why is this bad?** It's easier and more readable to use the inherent
 +    /// `.is_null()`
 +    /// method instead
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```ignore
 +    /// // Bad
 +    /// if x == ptr::null {
 +    ///     ..
 +    /// }
 +    ///
 +    /// // Good
 +    /// if x.is_null() {
 +    ///     ..
 +    /// }
 +    /// ```
 +    pub CMP_NULL,
 +    style,
 +    "comparing a pointer to a null pointer, suggesting to use `.is_null()` instead."
 +}
 +
 +declare_clippy_lint! {
 +    /// **What it does:** This lint checks for functions that take immutable
 +    /// references and return mutable ones.
 +    ///
 +    /// **Why is this bad?** This is trivially unsound, as one can create two
 +    /// mutable references from the same (immutable!) source.
 +    /// This [error](https://github.com/rust-lang/rust/issues/39465)
 +    /// actually lead to an interim Rust release 1.15.1.
 +    ///
 +    /// **Known problems:** To be on the conservative side, if there's at least one
 +    /// mutable reference with the output lifetime, this lint will not trigger.
 +    /// In practice, this case is unlikely anyway.
 +    ///
 +    /// **Example:**
 +    /// ```ignore
 +    /// fn foo(&Foo) -> &mut Bar { .. }
 +    /// ```
 +    pub MUT_FROM_REF,
 +    correctness,
 +    "fns that create mutable refs from immutable ref args"
 +}
 +
 +declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF]);
 +
 +impl<'tcx> LateLintPass<'tcx> for Ptr {
 +    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
 +        if let ItemKind::Fn(ref sig, _, body_id) = item.kind {
 +            check_fn(cx, &sig.decl, item.hir_id, Some(body_id));
 +        }
 +    }
 +
 +    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
 +        if let ImplItemKind::Fn(ref sig, body_id) = item.kind {
 +            let parent_item = cx.tcx.hir().get_parent_item(item.hir_id);
 +            if let Some(Node::Item(it)) = cx.tcx.hir().find(parent_item) {
 +                if let ItemKind::Impl { of_trait: Some(_), .. } = it.kind {
 +                    return; // ignore trait impls
 +                }
 +            }
 +            check_fn(cx, &sig.decl, item.hir_id, Some(body_id));
 +        }
 +    }
 +
 +    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
 +        if let TraitItemKind::Fn(ref sig, ref trait_method) = item.kind {
 +            let body_id = if let TraitFn::Provided(b) = *trait_method {
 +                Some(b)
 +            } else {
 +                None
 +            };
 +            check_fn(cx, &sig.decl, item.hir_id, body_id);
 +        }
 +    }
 +
 +    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 +        if let ExprKind::Binary(ref op, ref l, ref r) = expr.kind {
 +            if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(l) || is_null_path(r)) {
 +                span_lint(
 +                    cx,
 +                    CMP_NULL,
 +                    expr.span,
 +                    "comparing with null is better expressed by the `.is_null()` method",
 +                );
 +            }
 +        }
 +    }
 +}
 +
 +#[allow(clippy::too_many_lines)]
 +fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: Option<BodyId>) {
 +    let fn_def_id = cx.tcx.hir().local_def_id(fn_id);
 +    let sig = cx.tcx.fn_sig(fn_def_id);
 +    let fn_ty = sig.skip_binder();
 +    let body = opt_body_id.map(|id| cx.tcx.hir().body(id));
 +
 +    for (idx, (arg, ty)) in decl.inputs.iter().zip(fn_ty.inputs()).enumerate() {
 +        // Honor the allow attribute on parameters. See issue 5644.
 +        if let Some(body) = &body {
 +            if is_allowed(cx, PTR_ARG, body.params[idx].hir_id) {
 +                continue;
 +            }
 +        }
 +
 +        if let ty::Ref(_, ty, Mutability::Not) = ty.kind() {
 +            if is_type_diagnostic_item(cx, ty, sym::vec_type) {
-                             if let Some(ref snippet) = ty_snippet {
 +                if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) {
 +                    span_lint_and_then(
 +                        cx,
 +                        PTR_ARG,
 +                        arg.span,
 +                        "writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
 +                         with non-Vec-based slices.",
 +                        |diag| {
++                            if let Some(ref snippet) = get_only_generic_arg_snippet(cx, arg) {
 +                                diag.span_suggestion(
 +                                    arg.span,
 +                                    "change this to",
 +                                    format!("&[{}]", snippet),
 +                                    Applicability::Unspecified,
 +                                );
 +                            }
 +                            for (clonespan, suggestion) in spans {
 +                                diag.span_suggestion(
 +                                    clonespan,
 +                                    &snippet_opt(cx, clonespan).map_or("change the call to".into(), |x| {
 +                                        Cow::Owned(format!("change `{}` to", x))
 +                                    }),
 +                                    suggestion.into(),
 +                                    Applicability::Unspecified,
 +                                );
 +                            }
 +                        },
 +                    );
 +                }
 +            } else if is_type_diagnostic_item(cx, ty, sym::string_type) {
 +                if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_string()"), ("as_str", "")]) {
 +                    span_lint_and_then(
 +                        cx,
 +                        PTR_ARG,
 +                        arg.span,
 +                        "writing `&String` instead of `&str` involves a new object where a slice will do.",
 +                        |diag| {
 +                            diag.span_suggestion(arg.span, "change this to", "&str".into(), Applicability::Unspecified);
 +                            for (clonespan, suggestion) in spans {
 +                                diag.span_suggestion_short(
 +                                    clonespan,
 +                                    &snippet_opt(cx, clonespan).map_or("change the call to".into(), |x| {
 +                                        Cow::Owned(format!("change `{}` to", x))
 +                                    }),
 +                                    suggestion.into(),
 +                                    Applicability::Unspecified,
 +                                );
 +                            }
 +                        },
 +                    );
 +                }
++            } else if match_type(cx, ty, &paths::PATH_BUF) {
++                if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_path_buf()"), ("as_path", "")]) {
++                    span_lint_and_then(
++                        cx,
++                        PTR_ARG,
++                        arg.span,
++                        "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.",
++                        |diag| {
++                            diag.span_suggestion(
++                                arg.span,
++                                "change this to",
++                                "&Path".into(),
++                                Applicability::Unspecified,
++                            );
++                            for (clonespan, suggestion) in spans {
++                                diag.span_suggestion_short(
++                                    clonespan,
++                                    &snippet_opt(cx, clonespan).map_or("change the call to".into(), |x| {
++                                        Cow::Owned(format!("change `{}` to", x))
++                                    }),
++                                    suggestion.into(),
++                                    Applicability::Unspecified,
++                                );
++                            }
++                        },
++                    );
++                }
 +            } else if match_type(cx, ty, &paths::COW) {
 +                if_chain! {
 +                    if let TyKind::Rptr(_, MutTy { ref ty, ..} ) = arg.kind;
 +                    if let TyKind::Path(ref path) = ty.kind;
 +                    if let QPath::Resolved(None, ref pp) = *path;
 +                    if let [ref bx] = *pp.segments;
 +                    if let Some(ref params) = bx.args;
 +                    if !params.parenthesized;
 +                    if let Some(inner) = params.args.iter().find_map(|arg| match arg {
 +                        GenericArg::Type(ty) => Some(ty),
 +                        _ => None,
 +                    });
 +                    then {
 +                        let replacement = snippet_opt(cx, inner.span);
 +                        if let Some(r) = replacement {
 +                            span_lint_and_sugg(
 +                                cx,
 +                                PTR_ARG,
 +                                arg.span,
 +                                "using a reference to `Cow` is not recommended.",
 +                                "change this to",
 +                                "&".to_owned() + &r,
 +                                Applicability::Unspecified,
 +                            );
 +                        }
 +                    }
 +                }
 +            }
 +        }
 +    }
 +
 +    if let FnRetTy::Return(ref ty) = decl.output {
 +        if let Some((out, Mutability::Mut, _)) = get_rptr_lm(ty) {
 +            let mut immutables = vec![];
 +            for (_, ref mutbl, ref argspan) in decl
 +                .inputs
 +                .iter()
 +                .filter_map(|ty| get_rptr_lm(ty))
 +                .filter(|&(lt, _, _)| lt.name == out.name)
 +            {
 +                if *mutbl == Mutability::Mut {
 +                    return;
 +                }
 +                immutables.push(*argspan);
 +            }
 +            if immutables.is_empty() {
 +                return;
 +            }
 +            span_lint_and_then(
 +                cx,
 +                MUT_FROM_REF,
 +                ty.span,
 +                "mutable borrow from immutable input(s)",
 +                |diag| {
 +                    let ms = MultiSpan::from_spans(immutables);
 +                    diag.span_note(ms, "immutable borrow here");
 +                },
 +            );
 +        }
 +    }
 +}
 +
++fn get_only_generic_arg_snippet(cx: &LateContext<'_>, arg: &Ty<'_>) -> Option<String> {
++    if_chain! {
++        if let TyKind::Path(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).kind;
++        if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last();
++        let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg {
++            GenericArg::Type(ty) => Some(ty),
++            _ => None,
++        }).collect();
++        if types.len() == 1;
++        then {
++            snippet_opt(cx, types[0].span)
++        } else {
++            None
++        }
++    }
++}
++
 +fn get_rptr_lm<'tcx>(ty: &'tcx Ty<'tcx>) -> Option<(&'tcx Lifetime, Mutability, Span)> {
 +    if let TyKind::Rptr(ref lt, ref m) = ty.kind {
 +        Some((lt, m.mutbl, ty.span))
 +    } else {
 +        None
 +    }
 +}
 +
 +fn is_null_path(expr: &Expr<'_>) -> bool {
 +    if let ExprKind::Call(ref pathexp, ref args) = expr.kind {
 +        if args.is_empty() {
 +            if let ExprKind::Path(ref path) = pathexp.kind {
 +                return match_qpath(path, &paths::PTR_NULL) || match_qpath(path, &paths::PTR_NULL_MUT);
 +            }
 +        }
 +    }
 +    false
 +}
index 35b38eca14d1be6293e729d4ce3c370d0fef0a8a,0000000000000000000000000000000000000000..1fc4ff5c2e61fcad025432b360ce6c422e8a933c
mode 100644,000000..100644
--- /dev/null
@@@ -1,62 -1,0 +1,62 @@@
-             if cx.sess.opts.edition == Edition::Edition2018;
 +use crate::utils::{in_macro, span_lint_and_sugg};
 +use if_chain::if_chain;
 +use rustc_ast::{Item, ItemKind, UseTreeKind};
 +use rustc_errors::Applicability;
 +use rustc_lint::{EarlyContext, EarlyLintPass};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::edition::Edition;
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checking for imports with single component use path.
 +    ///
 +    /// **Why is this bad?** Import with single component use path such as `use cratename;`
 +    /// is not necessary, and thus should be removed.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    ///
 +    /// ```rust,ignore
 +    /// use regex;
 +    ///
 +    /// fn main() {
 +    ///     regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
 +    /// }
 +    /// ```
 +    /// Better as
 +    /// ```rust,ignore
 +    /// fn main() {
 +    ///     regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
 +    /// }
 +    /// ```
 +    pub SINGLE_COMPONENT_PATH_IMPORTS,
 +    style,
 +    "imports with single component path are redundant"
 +}
 +
 +declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
 +
 +impl EarlyLintPass for SingleComponentPathImports {
 +    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
 +        if_chain! {
 +            if !in_macro(item.span);
++            if cx.sess.opts.edition >= Edition::Edition2018;
 +            if !item.vis.kind.is_pub();
 +            if let ItemKind::Use(use_tree) = &item.kind;
 +            if let segments = &use_tree.prefix.segments;
 +            if segments.len() == 1;
 +            if let UseTreeKind::Simple(None, _, _) = use_tree.kind;
 +            then {
 +                span_lint_and_sugg(
 +                    cx,
 +                    SINGLE_COMPONENT_PATH_IMPORTS,
 +                    item.span,
 +                    "this import is redundant",
 +                    "remove it entirely",
 +                    String::new(),
 +                    Applicability::MachineApplicable
 +                );
 +            }
 +        }
 +    }
 +}
index f61fd2ecd735d915964c5b3ce80bfaa6da56e29e,0000000000000000000000000000000000000000..a31cd5fda849ed918211bf6d6822cf8555b3954c
mode 100644,000000..100644
--- /dev/null
@@@ -1,142 -1,0 +1,142 @@@
-         position_before_rarrow(fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
 +use if_chain::if_chain;
 +use rustc_ast::ast;
 +use rustc_ast::visit::FnKind;
 +use rustc_errors::Applicability;
 +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 +use rustc_session::{declare_lint_pass, declare_tool_lint};
 +use rustc_span::source_map::Span;
 +use rustc_span::BytePos;
 +
 +use crate::utils::{position_before_rarrow, span_lint_and_sugg};
 +
 +declare_clippy_lint! {
 +    /// **What it does:** Checks for unit (`()`) expressions that can be removed.
 +    ///
 +    /// **Why is this bad?** Such expressions add no value, but can make the code
 +    /// less readable. Depending on formatting they can make a `break` or `return`
 +    /// statement look like a function call.
 +    ///
 +    /// **Known problems:** None.
 +    ///
 +    /// **Example:**
 +    /// ```rust
 +    /// fn return_unit() -> () {
 +    ///     ()
 +    /// }
 +    /// ```
 +    pub UNUSED_UNIT,
 +    style,
 +    "needless unit expression"
 +}
 +
 +declare_lint_pass!(UnusedUnit => [UNUSED_UNIT]);
 +
 +impl EarlyLintPass for UnusedUnit {
 +    fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, span: Span, _: ast::NodeId) {
 +        if_chain! {
 +            if let ast::FnRetTy::Ty(ref ty) = kind.decl().output;
 +            if let ast::TyKind::Tup(ref vals) = ty.kind;
 +            if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span);
 +            then {
 +                lint_unneeded_unit_return(cx, ty, span);
 +            }
 +        }
 +    }
 +
 +    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) {
 +        if_chain! {
 +            if let Some(ref stmt) = block.stmts.last();
 +            if let ast::StmtKind::Expr(ref expr) = stmt.kind;
 +            if is_unit_expr(expr) && !stmt.span.from_expansion();
 +            then {
 +                let sp = expr.span;
 +                span_lint_and_sugg(
 +                    cx,
 +                    UNUSED_UNIT,
 +                    sp,
 +                    "unneeded unit expression",
 +                    "remove the final `()`",
 +                    String::new(),
 +                    Applicability::MachineApplicable,
 +                );
 +            }
 +        }
 +    }
 +
 +    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
 +        match e.kind {
 +            ast::ExprKind::Ret(Some(ref expr)) | ast::ExprKind::Break(_, Some(ref expr)) => {
 +                if is_unit_expr(expr) && !expr.span.from_expansion() {
 +                    span_lint_and_sugg(
 +                        cx,
 +                        UNUSED_UNIT,
 +                        expr.span,
 +                        "unneeded `()`",
 +                        "remove the `()`",
 +                        String::new(),
 +                        Applicability::MachineApplicable,
 +                    );
 +                }
 +            },
 +            _ => (),
 +        }
 +    }
 +
 +    fn check_poly_trait_ref(&mut self, cx: &EarlyContext<'_>, poly: &ast::PolyTraitRef, _: &ast::TraitBoundModifier) {
 +        let segments = &poly.trait_ref.path.segments;
 +
 +        if_chain! {
 +            if segments.len() == 1;
 +            if ["Fn", "FnMut", "FnOnce"].contains(&&*segments[0].ident.name.as_str());
 +            if let Some(args) = &segments[0].args;
 +            if let ast::GenericArgs::Parenthesized(generic_args) = &**args;
 +            if let ast::FnRetTy::Ty(ty) = &generic_args.output;
 +            if ty.kind.is_unit();
 +            then {
 +                lint_unneeded_unit_return(cx, ty, generic_args.span);
 +            }
 +        }
 +    }
 +}
 +
 +// get the def site
 +#[must_use]
 +fn get_def(span: Span) -> Option<Span> {
 +    if span.from_expansion() {
 +        Some(span.ctxt().outer_expn_data().def_site)
 +    } else {
 +        None
 +    }
 +}
 +
 +// is this expr a `()` unit?
 +fn is_unit_expr(expr: &ast::Expr) -> bool {
 +    if let ast::ExprKind::Tup(ref vals) = expr.kind {
 +        vals.is_empty()
 +    } else {
 +        false
 +    }
 +}
 +
 +fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
 +    let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) {
++        position_before_rarrow(&fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
 +            (
 +                #[allow(clippy::cast_possible_truncation)]
 +                ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
 +                Applicability::MachineApplicable,
 +            )
 +        })
 +    } else {
 +        (ty.span, Applicability::MaybeIncorrect)
 +    };
 +    span_lint_and_sugg(
 +        cx,
 +        UNUSED_UNIT,
 +        ret_span,
 +        "unneeded unit return type",
 +        "remove the `-> ()`",
 +        String::new(),
 +        appl,
 +    );
 +}
index 940573e4caa69799c64ee4d874586780f0ff7b7d,0000000000000000000000000000000000000000..5aed676fceb2815e56dc8dcda839eb5252a2c3fc
mode 100644,000000..100644
--- /dev/null
@@@ -1,552 -1,0 +1,562 @@@
-             (Const { ty: lt, kw_span: _ , default: ld}, Const { ty: rt, kw_span: _, default: rd }) =>
-                 eq_ty(lt, rt) && both(ld, rd, |ld, rd| eq_anon_const(ld, rd)),
 +//! Utilities for manipulating and extracting information from `rustc_ast::ast`.
 +//!
 +//! - The `eq_foobar` functions test for semantic equality but ignores `NodeId`s and `Span`s.
 +
 +#![allow(clippy::similar_names, clippy::wildcard_imports, clippy::enum_glob_use)]
 +
 +use crate::utils::{both, over};
 +use rustc_ast::ptr::P;
 +use rustc_ast::{self as ast, *};
 +use rustc_span::symbol::Ident;
 +use std::mem;
 +
 +pub mod ident_iter;
 +pub use ident_iter::IdentIter;
 +
 +pub fn is_useless_with_eq_exprs(kind: BinOpKind) -> bool {
 +    use BinOpKind::*;
 +    matches!(
 +        kind,
 +        Sub | Div | Eq | Lt | Le | Gt | Ge | Ne | And | Or | BitXor | BitAnd | BitOr
 +    )
 +}
 +
 +/// Checks if each element in the first slice is contained within the latter as per `eq_fn`.
 +pub fn unordered_over<X>(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
 +    left.len() == right.len() && left.iter().all(|l| right.iter().any(|r| eq_fn(l, r)))
 +}
 +
 +pub fn eq_id(l: Ident, r: Ident) -> bool {
 +    l.name == r.name
 +}
 +
 +pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
 +    use PatKind::*;
 +    match (&l.kind, &r.kind) {
 +        (Paren(l), _) => eq_pat(l, r),
 +        (_, Paren(r)) => eq_pat(l, r),
 +        (Wild, Wild) | (Rest, Rest) => true,
 +        (Lit(l), Lit(r)) => eq_expr(l, r),
 +        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => b1 == b2 && eq_id(*i1, *i2) && both(s1, s2, |l, r| eq_pat(l, r)),
 +        (Range(lf, lt, le), Range(rf, rt, re)) => {
 +            eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt) && eq_range_end(&le.node, &re.node)
 +        },
 +        (Box(l), Box(r))
 +        | (Ref(l, Mutability::Not), Ref(r, Mutability::Not))
 +        | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
 +        (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
 +        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
 +        (TupleStruct(lp, lfs), TupleStruct(rp, rfs)) => eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
 +        (Struct(lp, lfs, lr), Struct(rp, rfs, rr)) => {
 +            lr == rr && eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
 +        },
 +        (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_range_end(l: &RangeEnd, r: &RangeEnd) -> bool {
 +    match (l, r) {
 +        (RangeEnd::Excluded, RangeEnd::Excluded) => true,
 +        (RangeEnd::Included(l), RangeEnd::Included(r)) => {
 +            matches!(l, RangeSyntax::DotDotEq) == matches!(r, RangeSyntax::DotDotEq)
 +        },
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_field_pat(l: &FieldPat, r: &FieldPat) -> bool {
 +    l.is_placeholder == r.is_placeholder
 +        && eq_id(l.ident, r.ident)
 +        && eq_pat(&l.pat, &r.pat)
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +}
 +
 +pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {
 +    l.position == r.position && eq_ty(&l.ty, &r.ty)
 +}
 +
 +pub fn eq_path(l: &Path, r: &Path) -> bool {
 +    over(&l.segments, &r.segments, |l, r| eq_path_seg(l, r))
 +}
 +
 +pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {
 +    eq_id(l.ident, r.ident) && both(&l.args, &r.args, |l, r| eq_generic_args(l, r))
 +}
 +
 +pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
 +    match (l, r) {
 +        (GenericArgs::AngleBracketed(l), GenericArgs::AngleBracketed(r)) => {
 +            over(&l.args, &r.args, |l, r| eq_angle_arg(l, r))
 +        },
 +        (GenericArgs::Parenthesized(l), GenericArgs::Parenthesized(r)) => {
 +            over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output)
 +        },
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool {
 +    match (l, r) {
 +        (AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r),
 +        (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_constraint(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool {
 +    match (l, r) {
 +        (GenericArg::Lifetime(l), GenericArg::Lifetime(r)) => eq_id(l.ident, r.ident),
 +        (GenericArg::Type(l), GenericArg::Type(r)) => eq_ty(l, r),
 +        (GenericArg::Const(l), GenericArg::Const(r)) => eq_expr(&l.value, &r.value),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_expr_opt(l: &Option<P<Expr>>, r: &Option<P<Expr>>) -> bool {
 +    both(l, r, |l, r| eq_expr(l, r))
 +}
 +
 +pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {
 +    match (l, r) {
 +        (StructRest::Base(lb), StructRest::Base(rb)) => eq_expr(lb, rb),
 +        (StructRest::Rest(_), StructRest::Rest(_)) | (StructRest::None, StructRest::None) => true,
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
 +    use ExprKind::*;
 +    if !over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)) {
 +        return false;
 +    }
 +    match (&l.kind, &r.kind) {
 +        (Paren(l), _) => eq_expr(l, r),
 +        (_, Paren(r)) => eq_expr(l, r),
 +        (Err, Err) => true,
 +        (Box(l), Box(r)) | (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r),
 +        (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
 +        (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
 +        (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
 +        (MethodCall(lc, la, _), MethodCall(rc, ra, _)) => eq_path_seg(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
 +        (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),
 +        (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
 +        (Lit(l), Lit(r)) => l.kind == r.kind,
 +        (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt),
 +        (Let(lp, le), Let(rp, re)) => eq_pat(lp, rp) && eq_expr(le, re),
 +        (If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
 +        (While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
 +        (ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => {
 +            eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt)
 +        },
 +        (Loop(lt, ll), Loop(rt, rl)) => eq_label(ll, rl) && eq_block(lt, rt),
 +        (Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
 +        (TryBlock(l), TryBlock(r)) => eq_block(l, r),
 +        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
 +        (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
 +        (Continue(ll), Continue(rl)) => eq_label(ll, rl),
 +        (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2), Index(r1, r2)) => eq_expr(l1, r1) && eq_expr(l2, r2),
 +        (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
 +        (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
 +        (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, |l, r| eq_arm(l, r)),
 +        (Closure(lc, la, lm, lf, lb, _), Closure(rc, ra, rm, rf, rb, _)) => {
 +            lc == rc && la.is_async() == ra.is_async() && lm == rm && eq_fn_decl(lf, rf) && eq_expr(lb, rb)
 +        },
 +        (Async(lc, _, lb), Async(rc, _, rb)) => lc == rc && eq_block(lb, rb),
 +        (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
 +        (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
 +        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        (Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
 +            eq_path(lp, rp) && eq_struct_rest(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
 +        },
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_field(l: &Field, r: &Field) -> bool {
 +    l.is_placeholder == r.is_placeholder
 +        && eq_id(l.ident, r.ident)
 +        && eq_expr(&l.expr, &r.expr)
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +}
 +
 +pub fn eq_arm(l: &Arm, r: &Arm) -> bool {
 +    l.is_placeholder == r.is_placeholder
 +        && eq_pat(&l.pat, &r.pat)
 +        && eq_expr(&l.body, &r.body)
 +        && eq_expr_opt(&l.guard, &r.guard)
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +}
 +
 +pub fn eq_label(l: &Option<Label>, r: &Option<Label>) -> bool {
 +    both(l, r, |l, r| eq_id(l.ident, r.ident))
 +}
 +
 +pub fn eq_block(l: &Block, r: &Block) -> bool {
 +    l.rules == r.rules && over(&l.stmts, &r.stmts, |l, r| eq_stmt(l, r))
 +}
 +
 +pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
 +    use StmtKind::*;
 +    match (&l.kind, &r.kind) {
 +        (Local(l), Local(r)) => {
 +            eq_pat(&l.pat, &r.pat)
 +                && both(&l.ty, &r.ty, |l, r| eq_ty(l, r))
 +                && eq_expr_opt(&l.init, &r.init)
 +                && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        },
 +        (Item(l), Item(r)) => eq_item(l, r, eq_item_kind),
 +        (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r),
 +        (Empty, Empty) => true,
 +        (MacCall(l), MacCall(r)) => {
 +            l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        },
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_item<K>(l: &Item<K>, r: &Item<K>, mut eq_kind: impl FnMut(&K, &K) -> bool) -> bool {
 +    eq_id(l.ident, r.ident)
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        && eq_vis(&l.vis, &r.vis)
 +        && eq_kind(&l.kind, &r.kind)
 +}
 +
 +pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
 +    use ItemKind::*;
 +    match (l, r) {
 +        (ExternCrate(l), ExternCrate(r)) => l == r,
 +        (Use(l), Use(r)) => eq_use_tree(l, r),
 +        (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
 +        (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
 +        (Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
 +            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
 +        },
 +        (Mod(l), Mod(r)) => l.inline == r.inline && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_item_kind)),
 +        (ForeignMod(l), ForeignMod(r)) => {
 +            both(&l.abi, &r.abi, |l, r| eq_str_lit(l, r))
 +                && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
 +        },
 +        (TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
 +            eq_defaultness(*ld, *rd)
 +                && eq_generics(lg, rg)
 +                && over(lb, rb, |l, r| eq_generic_bound(l, r))
 +                && both(lt, rt, |l, r| eq_ty(l, r))
 +        },
 +        (Enum(le, lg), Enum(re, rg)) => {
 +            over(&le.variants, &re.variants, |l, r| eq_variant(l, r)) && eq_generics(lg, rg)
 +        },
 +        (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
 +            eq_variant_data(lv, rv) && eq_generics(lg, rg)
 +        },
 +        (Trait(la, lu, lg, lb, li), Trait(ra, ru, rg, rb, ri)) => {
 +            la == ra
 +                && matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
 +                && eq_generics(lg, rg)
 +                && over(lb, rb, |l, r| eq_generic_bound(l, r))
 +                && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
 +        },
 +        (TraitAlias(lg, lb), TraitAlias(rg, rb)) => eq_generics(lg, rg) && over(lb, rb, |l, r| eq_generic_bound(l, r)),
 +        (
 +            Impl {
 +                unsafety: lu,
 +                polarity: lp,
 +                defaultness: ld,
 +                constness: lc,
 +                generics: lg,
 +                of_trait: lot,
 +                self_ty: lst,
 +                items: li,
 +            },
 +            Impl {
 +                unsafety: ru,
 +                polarity: rp,
 +                defaultness: rd,
 +                constness: rc,
 +                generics: rg,
 +                of_trait: rot,
 +                self_ty: rst,
 +                items: ri,
 +            },
 +        ) => {
 +            matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
 +                && matches!(lp, ImplPolarity::Positive) == matches!(rp, ImplPolarity::Positive)
 +                && eq_defaultness(*ld, *rd)
 +                && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
 +                && eq_generics(lg, rg)
 +                && both(lot, rot, |l, r| eq_path(&l.path, &r.path))
 +                && eq_ty(lst, rst)
 +                && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
 +        },
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_mac_args(&l.body, &r.body),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
 +    use ForeignItemKind::*;
 +    match (l, r) {
 +        (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
 +        (Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
 +            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
 +        },
 +        (TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
 +            eq_defaultness(*ld, *rd)
 +                && eq_generics(lg, rg)
 +                && over(lb, rb, |l, r| eq_generic_bound(l, r))
 +                && both(lt, rt, |l, r| eq_ty(l, r))
 +        },
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
 +    use AssocItemKind::*;
 +    match (l, r) {
 +        (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
 +        (Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
 +            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
 +        },
 +        (TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
 +            eq_defaultness(*ld, *rd)
 +                && eq_generics(lg, rg)
 +                && over(lb, rb, |l, r| eq_generic_bound(l, r))
 +                && both(lt, rt, |l, r| eq_ty(l, r))
 +        },
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_variant(l: &Variant, r: &Variant) -> bool {
 +    l.is_placeholder == r.is_placeholder
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        && eq_vis(&l.vis, &r.vis)
 +        && eq_id(l.ident, r.ident)
 +        && eq_variant_data(&l.data, &r.data)
 +        && both(&l.disr_expr, &r.disr_expr, |l, r| eq_expr(&l.value, &r.value))
 +}
 +
 +pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
 +    use VariantData::*;
 +    match (l, r) {
 +        (Unit(_), Unit(_)) => true,
 +        (Struct(l, _), Struct(r, _)) | (Tuple(l, _), Tuple(r, _)) => over(l, r, |l, r| eq_struct_field(l, r)),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_struct_field(l: &StructField, r: &StructField) -> bool {
 +    l.is_placeholder == r.is_placeholder
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        && eq_vis(&l.vis, &r.vis)
 +        && both(&l.ident, &r.ident, |l, r| eq_id(*l, *r))
 +        && eq_ty(&l.ty, &r.ty)
 +}
 +
 +pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
 +    eq_fn_decl(&l.decl, &r.decl) && eq_fn_header(&l.header, &r.header)
 +}
 +
 +pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
 +    matches!(l.unsafety, Unsafe::No) == matches!(r.unsafety, Unsafe::No)
 +        && l.asyncness.is_async() == r.asyncness.is_async()
 +        && matches!(l.constness, Const::No) == matches!(r.constness, Const::No)
 +        && eq_ext(&l.ext, &r.ext)
 +}
 +
 +pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
 +    over(&l.params, &r.params, |l, r| eq_generic_param(l, r))
 +        && over(&l.where_clause.predicates, &r.where_clause.predicates, |l, r| {
 +            eq_where_predicate(l, r)
 +        })
 +}
 +
 +pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
 +    use WherePredicate::*;
 +    match (l, r) {
 +        (BoundPredicate(l), BoundPredicate(r)) => {
 +            over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
 +                eq_generic_param(l, r)
 +            }) && eq_ty(&l.bounded_ty, &r.bounded_ty)
 +                && over(&l.bounds, &r.bounds, |l, r| eq_generic_bound(l, r))
 +        },
 +        (RegionPredicate(l), RegionPredicate(r)) => {
 +            eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, |l, r| eq_generic_bound(l, r))
 +        },
 +        (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool {
 +    eq_path(&l.prefix, &r.prefix) && eq_use_tree_kind(&l.kind, &r.kind)
 +}
 +
 +pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
 +    use UseTreeKind::*;
 +    match (l, r) {
 +        (Glob, Glob) => true,
 +        (Simple(l, _, _), Simple(r, _, _)) => both(l, r, |l, r| eq_id(*l, *r)),
 +        (Nested(l), Nested(r)) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool {
 +    eq_expr(&l.value, &r.value)
 +}
 +
 +pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
 +    matches!(
 +        (l, r),
 +        (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_))
 +    )
 +}
 +
 +pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
 +    use VisibilityKind::*;
 +    match (&l.kind, &r.kind) {
 +        (Public, Public) | (Inherited, Inherited) | (Crate(_), Crate(_)) => true,
 +        (Restricted { path: l, .. }, Restricted { path: r, .. }) => eq_path(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool {
 +    eq_fn_ret_ty(&l.output, &r.output)
 +        && over(&l.inputs, &r.inputs, |l, r| {
 +            l.is_placeholder == r.is_placeholder
 +                && eq_pat(&l.pat, &r.pat)
 +                && eq_ty(&l.ty, &r.ty)
 +                && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +        })
 +}
 +
 +pub fn eq_fn_ret_ty(l: &FnRetTy, r: &FnRetTy) -> bool {
 +    match (l, r) {
 +        (FnRetTy::Default(_), FnRetTy::Default(_)) => true,
 +        (FnRetTy::Ty(l), FnRetTy::Ty(r)) => eq_ty(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
 +    use TyKind::*;
 +    match (&l.kind, &r.kind) {
 +        (Paren(l), _) => eq_ty(l, r),
 +        (_, Paren(r)) => eq_ty(l, r),
 +        (Never, Never) | (Infer, Infer) | (ImplicitSelf, ImplicitSelf) | (Err, Err) | (CVarArgs, CVarArgs) => true,
 +        (Slice(l), Slice(r)) => eq_ty(l, r),
 +        (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),
 +        (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),
 +        (Rptr(ll, l), Rptr(rl, r)) => {
 +            both(ll, rl, |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
 +        },
 +        (BareFn(l), BareFn(r)) => {
 +            l.unsafety == r.unsafety
 +                && eq_ext(&l.ext, &r.ext)
 +                && over(&l.generic_params, &r.generic_params, |l, r| eq_generic_param(l, r))
 +                && eq_fn_decl(&l.decl, &r.decl)
 +        },
 +        (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)),
 +        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
 +        (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, |l, r| eq_generic_bound(l, r)),
 +        (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, |l, r| eq_generic_bound(l, r)),
 +        (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value),
 +        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_ext(l: &Extern, r: &Extern) -> bool {
 +    use Extern::*;
 +    match (l, r) {
 +        (None, None) | (Implicit, Implicit) => true,
 +        (Explicit(l), Explicit(r)) => eq_str_lit(l, r),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool {
 +    l.style == r.style && l.symbol == r.symbol && l.suffix == r.suffix
 +}
 +
 +pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {
 +    eq_path(&l.trait_ref.path, &r.trait_ref.path)
 +        && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
 +            eq_generic_param(l, r)
 +        })
 +}
 +
 +pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
 +    use GenericParamKind::*;
 +    l.is_placeholder == r.is_placeholder
 +        && eq_id(l.ident, r.ident)
 +        && over(&l.bounds, &r.bounds, |l, r| eq_generic_bound(l, r))
 +        && match (&l.kind, &r.kind) {
 +            (Lifetime, Lifetime) => true,
 +            (Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)),
++            (
++                Const {
++                    ty: lt,
++                    kw_span: _,
++                    default: ld,
++                },
++                Const {
++                    ty: rt,
++                    kw_span: _,
++                    default: rd,
++                },
++            ) => eq_ty(lt, rt) && both(ld, rd, |ld, rd| eq_anon_const(ld, rd)),
 +            _ => false,
 +        }
 +        && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
 +}
 +
 +pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
 +    use GenericBound::*;
 +    match (l, r) {
 +        (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2),
 +        (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
 +        _ => false,
 +    }
 +}
 +
 +pub fn eq_assoc_constraint(l: &AssocTyConstraint, r: &AssocTyConstraint) -> bool {
 +    use AssocTyConstraintKind::*;
 +    eq_id(l.ident, r.ident)
 +        && match (&l.kind, &r.kind) {
 +            (Equality { ty: l }, Equality { ty: r }) => eq_ty(l, r),
 +            (Bound { bounds: l }, Bound { bounds: r }) => over(l, r, |l, r| eq_generic_bound(l, r)),
 +            _ => false,
 +        }
 +}
 +
 +pub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool {
 +    eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args)
 +}
 +
 +pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
 +    use AttrKind::*;
 +    l.style == r.style
 +        && match (&l.kind, &r.kind) {
 +            (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
 +            (Normal(l, _), Normal(r, _)) => eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args),
 +            _ => false,
 +        }
 +}
 +
 +pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool {
 +    use MacArgs::*;
 +    match (l, r) {
 +        (Empty, Empty) => true,
 +        (Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
 +        (Eq(_, lts), Eq(_, rts)) => lts.eq_unspanned(rts),
 +        _ => false,
 +    }
 +}
index 424856090f261f598dfe200fc7fd65652f6fa04e,0000000000000000000000000000000000000000..1c68e837c4ab97286410fc51e7f3347bb8356b3e
mode 100644,000000..100644
--- /dev/null
@@@ -1,1785 -1,0 +1,1784 @@@
- #[allow(clippy::needless_pass_by_value)]
- pub fn position_before_rarrow(s: String) -> Option<usize> {
 +#[macro_use]
 +pub mod sym;
 +
 +#[allow(clippy::module_name_repetitions)]
 +pub mod ast_utils;
 +pub mod attrs;
 +pub mod author;
 +pub mod camel_case;
 +pub mod comparisons;
 +pub mod conf;
 +pub mod constants;
 +mod diagnostics;
 +pub mod eager_or_lazy;
 +pub mod higher;
 +mod hir_utils;
 +pub mod inspector;
 +#[cfg(feature = "internal-lints")]
 +pub mod internal_lints;
 +pub mod numeric_literal;
 +pub mod paths;
 +pub mod ptr;
 +pub mod qualify_min_const_fn;
 +pub mod sugg;
 +pub mod usage;
 +pub mod visitors;
 +
 +pub use self::attrs::*;
 +pub use self::diagnostics::*;
 +pub use self::hir_utils::{both, eq_expr_value, over, SpanlessEq, SpanlessHash};
 +
 +use std::borrow::Cow;
 +use std::collections::hash_map::Entry;
 +use std::hash::BuildHasherDefault;
 +use std::mem;
 +
 +use if_chain::if_chain;
 +use rustc_ast::ast::{self, Attribute, LitKind};
 +use rustc_attr as attr;
 +use rustc_data_structures::fx::FxHashMap;
 +use rustc_errors::Applicability;
 +use rustc_hir as hir;
 +use rustc_hir::def::{DefKind, Res};
 +use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 +use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 +use rustc_hir::Node;
 +use rustc_hir::{
 +    def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
 +    MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, Unsafety,
 +};
 +use rustc_infer::infer::TyCtxtInferExt;
 +use rustc_lint::{LateContext, Level, Lint, LintContext};
 +use rustc_middle::hir::map::Map;
 +use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
 +use rustc_middle::ty::{self, layout::IntegerExt, Ty, TyCtxt, TypeFoldable};
 +use rustc_semver::RustcVersion;
 +use rustc_session::Session;
 +use rustc_span::hygiene::{ExpnKind, MacroKind};
 +use rustc_span::source_map::original_sp;
 +use rustc_span::sym as rustc_sym;
 +use rustc_span::symbol::{self, kw, Symbol};
 +use rustc_span::{BytePos, Pos, Span, DUMMY_SP};
 +use rustc_target::abi::Integer;
 +use rustc_trait_selection::traits::query::normalize::AtExt;
 +use smallvec::SmallVec;
 +
 +use crate::consts::{constant, Constant};
 +
 +pub fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
 +    if let Ok(version) = RustcVersion::parse(msrv) {
 +        return Some(version);
 +    } else if let Some(sess) = sess {
 +        if let Some(span) = span {
 +            sess.span_err(span, &format!("`{}` is not a valid Rust version", msrv));
 +        }
 +    }
 +    None
 +}
 +
 +pub fn meets_msrv(msrv: Option<&RustcVersion>, lint_msrv: &RustcVersion) -> bool {
 +    msrv.map_or(true, |msrv| msrv.meets(*lint_msrv))
 +}
 +
 +macro_rules! extract_msrv_attr {
 +    (LateContext) => {
 +        extract_msrv_attr!(@LateContext, ());
 +    };
 +    (EarlyContext) => {
 +        extract_msrv_attr!(@EarlyContext);
 +    };
 +    (@$context:ident$(, $call:tt)?) => {
 +        fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'tcx>, attrs: &'tcx [rustc_ast::ast::Attribute]) {
 +            use $crate::utils::get_unique_inner_attr;
 +            match get_unique_inner_attr(cx.sess$($call)?, attrs, "msrv") {
 +                Some(msrv_attr) => {
 +                    if let Some(msrv) = msrv_attr.value_str() {
 +                        self.msrv = $crate::utils::parse_msrv(
 +                            &msrv.to_string(),
 +                            Some(cx.sess$($call)?),
 +                            Some(msrv_attr.span),
 +                        );
 +                    } else {
 +                        cx.sess$($call)?.span_err(msrv_attr.span, "bad clippy attribute");
 +                    }
 +                },
 +                _ => (),
 +            }
 +        }
 +    };
 +}
 +
 +/// Returns `true` if the two spans come from differing expansions (i.e., one is
 +/// from a macro and one isn't).
 +#[must_use]
 +pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool {
 +    rhs.ctxt() != lhs.ctxt()
 +}
 +
 +/// Returns `true` if the given `NodeId` is inside a constant context
 +///
 +/// # Example
 +///
 +/// ```rust,ignore
 +/// if in_constant(cx, expr.hir_id) {
 +///     // Do something
 +/// }
 +/// ```
 +pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
 +    let parent_id = cx.tcx.hir().get_parent_item(id);
 +    match cx.tcx.hir().get(parent_id) {
 +        Node::Item(&Item {
 +            kind: ItemKind::Const(..) | ItemKind::Static(..),
 +            ..
 +        })
 +        | Node::TraitItem(&TraitItem {
 +            kind: TraitItemKind::Const(..),
 +            ..
 +        })
 +        | Node::ImplItem(&ImplItem {
 +            kind: ImplItemKind::Const(..),
 +            ..
 +        })
 +        | Node::AnonConst(_) => true,
 +        Node::Item(&Item {
 +            kind: ItemKind::Fn(ref sig, ..),
 +            ..
 +        })
 +        | Node::ImplItem(&ImplItem {
 +            kind: ImplItemKind::Fn(ref sig, _),
 +            ..
 +        }) => sig.header.constness == Constness::Const,
 +        _ => false,
 +    }
 +}
 +
 +/// Returns `true` if this `span` was expanded by any macro.
 +#[must_use]
 +pub fn in_macro(span: Span) -> bool {
 +    if span.from_expansion() {
 +        !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
 +    } else {
 +        false
 +    }
 +}
 +
 +// If the snippet is empty, it's an attribute that was inserted during macro
 +// expansion and we want to ignore those, because they could come from external
 +// sources that the user has no control over.
 +// For some reason these attributes don't have any expansion info on them, so
 +// we have to check it this way until there is a better way.
 +pub fn is_present_in_source<T: LintContext>(cx: &T, span: Span) -> bool {
 +    if let Some(snippet) = snippet_opt(cx, span) {
 +        if snippet.is_empty() {
 +            return false;
 +        }
 +    }
 +    true
 +}
 +
 +/// Checks if given pattern is a wildcard (`_`)
 +pub fn is_wild<'tcx>(pat: &impl std::ops::Deref<Target = Pat<'tcx>>) -> bool {
 +    matches!(pat.kind, PatKind::Wild)
 +}
 +
 +/// Checks if type is struct, enum or union type with the given def path.
 +///
 +/// If the type is a diagnostic item, use `is_type_diagnostic_item` instead.
 +/// If you change the signature, remember to update the internal lint `MatchTypeOnDiagItem`
 +pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool {
 +    match ty.kind() {
 +        ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
 +        _ => false,
 +    }
 +}
 +
 +/// Checks if the type is equal to a diagnostic item
 +///
 +/// If you change the signature, remember to update the internal lint `MatchTypeOnDiagItem`
 +pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
 +    match ty.kind() {
 +        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did),
 +        _ => false,
 +    }
 +}
 +
 +/// Checks if the type is equal to a lang item
 +pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
 +    match ty.kind() {
 +        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).unwrap() == adt.did,
 +        _ => false,
 +    }
 +}
 +
 +/// Checks if the method call given in `expr` belongs to the given trait.
 +pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool {
 +    let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
 +    let trt_id = cx.tcx.trait_of_item(def_id);
 +    trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path))
 +}
 +
 +/// Checks if an expression references a variable of the given name.
 +pub fn match_var(expr: &Expr<'_>, var: Symbol) -> bool {
 +    if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.kind {
 +        if let [p] = path.segments {
 +            return p.ident.name == var;
 +        }
 +    }
 +    false
 +}
 +
 +pub fn last_path_segment<'tcx>(path: &QPath<'tcx>) -> &'tcx PathSegment<'tcx> {
 +    match *path {
 +        QPath::Resolved(_, ref path) => path.segments.last().expect("A path must have at least one segment"),
 +        QPath::TypeRelative(_, ref seg) => seg,
 +        QPath::LangItem(..) => panic!("last_path_segment: lang item has no path segments"),
 +    }
 +}
 +
 +pub fn single_segment_path<'tcx>(path: &QPath<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
 +    match *path {
 +        QPath::Resolved(_, ref path) => path.segments.get(0),
 +        QPath::TypeRelative(_, ref seg) => Some(seg),
 +        QPath::LangItem(..) => None,
 +    }
 +}
 +
 +/// Matches a `QPath` against a slice of segment string literals.
 +///
 +/// There is also `match_path` if you are dealing with a `rustc_hir::Path` instead of a
 +/// `rustc_hir::QPath`.
 +///
 +/// # Examples
 +/// ```rust,ignore
 +/// match_qpath(path, &["std", "rt", "begin_unwind"])
 +/// ```
 +pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
 +    match *path {
 +        QPath::Resolved(_, ref path) => match_path(path, segments),
 +        QPath::TypeRelative(ref ty, ref segment) => match ty.kind {
 +            TyKind::Path(ref inner_path) => {
 +                if let [prefix @ .., end] = segments {
 +                    if match_qpath(inner_path, prefix) {
 +                        return segment.ident.name.as_str() == *end;
 +                    }
 +                }
 +                false
 +            },
 +            _ => false,
 +        },
 +        QPath::LangItem(..) => false,
 +    }
 +}
 +
 +/// Matches a `Path` against a slice of segment string literals.
 +///
 +/// There is also `match_qpath` if you are dealing with a `rustc_hir::QPath` instead of a
 +/// `rustc_hir::Path`.
 +///
 +/// # Examples
 +///
 +/// ```rust,ignore
 +/// if match_path(&trait_ref.path, &paths::HASH) {
 +///     // This is the `std::hash::Hash` trait.
 +/// }
 +///
 +/// if match_path(ty_path, &["rustc", "lint", "Lint"]) {
 +///     // This is a `rustc_middle::lint::Lint`.
 +/// }
 +/// ```
 +pub fn match_path(path: &Path<'_>, segments: &[&str]) -> bool {
 +    path.segments
 +        .iter()
 +        .rev()
 +        .zip(segments.iter().rev())
 +        .all(|(a, b)| a.ident.name.as_str() == *b)
 +}
 +
 +/// Matches a `Path` against a slice of segment string literals, e.g.
 +///
 +/// # Examples
 +/// ```rust,ignore
 +/// match_path_ast(path, &["std", "rt", "begin_unwind"])
 +/// ```
 +pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
 +    path.segments
 +        .iter()
 +        .rev()
 +        .zip(segments.iter().rev())
 +        .all(|(a, b)| a.ident.name.as_str() == *b)
 +}
 +
 +/// Gets the definition associated to a path.
 +pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option<def::Res> {
 +    let crates = cx.tcx.crates();
 +    let krate = crates
 +        .iter()
 +        .find(|&&krate| cx.tcx.crate_name(krate).as_str() == path[0]);
 +    if let Some(krate) = krate {
 +        let krate = DefId {
 +            krate: *krate,
 +            index: CRATE_DEF_INDEX,
 +        };
 +        let mut current_item = None;
 +        let mut items = cx.tcx.item_children(krate);
 +        let mut path_it = path.iter().skip(1).peekable();
 +
 +        loop {
 +            let segment = match path_it.next() {
 +                Some(segment) => segment,
 +                None => return None,
 +            };
 +
 +            // `get_def_path` seems to generate these empty segments for extern blocks.
 +            // We can just ignore them.
 +            if segment.is_empty() {
 +                continue;
 +            }
 +
 +            let result = SmallVec::<[_; 8]>::new();
 +            for item in mem::replace(&mut items, cx.tcx.arena.alloc_slice(&result)).iter() {
 +                if item.ident.name.as_str() == *segment {
 +                    if path_it.peek().is_none() {
 +                        return Some(item.res);
 +                    }
 +
 +                    current_item = Some(item);
 +                    items = cx.tcx.item_children(item.res.def_id());
 +                    break;
 +                }
 +            }
 +
 +            // The segment isn't a child_item.
 +            // Try to find it under an inherent impl.
 +            if_chain! {
 +                if path_it.peek().is_none();
 +                if let Some(current_item) = current_item;
 +                let item_def_id = current_item.res.def_id();
 +                if cx.tcx.def_kind(item_def_id) == DefKind::Struct;
 +                then {
 +                    // Bad `find_map` suggestion. See #4193.
 +                    #[allow(clippy::find_map)]
 +                    return cx.tcx.inherent_impls(item_def_id).iter()
 +                        .flat_map(|&impl_def_id| cx.tcx.item_children(impl_def_id))
 +                        .find(|item| item.ident.name.as_str() == *segment)
 +                        .map(|item| item.res);
 +                }
 +            }
 +        }
 +    } else {
 +        None
 +    }
 +}
 +
 +pub fn qpath_res(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
 +    match qpath {
 +        hir::QPath::Resolved(_, path) => path.res,
 +        hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => {
 +            if cx.tcx.has_typeck_results(id.owner.to_def_id()) {
 +                cx.tcx.typeck(id.owner).qpath_res(qpath, id)
 +            } else {
 +                Res::Err
 +            }
 +        },
 +    }
 +}
 +
 +/// Convenience function to get the `DefId` of a trait by path.
 +/// It could be a trait or trait alias.
 +pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option<DefId> {
 +    let res = match path_to_res(cx, path) {
 +        Some(res) => res,
 +        None => return None,
 +    };
 +
 +    match res {
 +        Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
 +        Res::Err => unreachable!("this trait resolution is impossible: {:?}", &path),
 +        _ => None,
 +    }
 +}
 +
 +/// Checks whether a type implements a trait.
 +/// See also `get_trait_def_id`.
 +pub fn implements_trait<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    ty: Ty<'tcx>,
 +    trait_id: DefId,
 +    ty_params: &[GenericArg<'tcx>],
 +) -> bool {
 +    // Do not check on infer_types to avoid panic in evaluate_obligation.
 +    if ty.has_infer_types() {
 +        return false;
 +    }
 +    let ty = cx.tcx.erase_regions(ty);
 +    if ty.has_escaping_bound_vars() {
 +        return false;
 +    }
 +    let ty_params = cx.tcx.mk_substs(ty_params.iter());
 +    cx.tcx.type_implements_trait((trait_id, ty, ty_params, cx.param_env))
 +}
 +
 +/// Gets the `hir::TraitRef` of the trait the given method is implemented for.
 +///
 +/// Use this if you want to find the `TraitRef` of the `Add` trait in this example:
 +///
 +/// ```rust
 +/// struct Point(isize, isize);
 +///
 +/// impl std::ops::Add for Point {
 +///     type Output = Self;
 +///
 +///     fn add(self, other: Self) -> Self {
 +///         Point(0, 0)
 +///     }
 +/// }
 +/// ```
 +pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx TraitRef<'tcx>> {
 +    // Get the implemented trait for the current function
 +    let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
 +    if_chain! {
 +        if parent_impl != hir::CRATE_HIR_ID;
 +        if let hir::Node::Item(item) = cx.tcx.hir().get(parent_impl);
 +        if let hir::ItemKind::Impl{ of_trait: trait_ref, .. } = &item.kind;
 +        then { return trait_ref.as_ref(); }
 +    }
 +    None
 +}
 +
 +/// Checks whether this type implements `Drop`.
 +pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 +    match ty.ty_adt_def() {
 +        Some(def) => def.has_dtor(cx.tcx),
 +        None => false,
 +    }
 +}
 +
 +/// Returns the method names and argument list of nested method call expressions that make up
 +/// `expr`. method/span lists are sorted with the most recent call first.
 +pub fn method_calls<'tcx>(
 +    expr: &'tcx Expr<'tcx>,
 +    max_depth: usize,
 +) -> (Vec<Symbol>, Vec<&'tcx [Expr<'tcx>]>, Vec<Span>) {
 +    let mut method_names = Vec::with_capacity(max_depth);
 +    let mut arg_lists = Vec::with_capacity(max_depth);
 +    let mut spans = Vec::with_capacity(max_depth);
 +
 +    let mut current = expr;
 +    for _ in 0..max_depth {
 +        if let ExprKind::MethodCall(path, span, args, _) = &current.kind {
 +            if args.iter().any(|e| e.span.from_expansion()) {
 +                break;
 +            }
 +            method_names.push(path.ident.name);
 +            arg_lists.push(&**args);
 +            spans.push(*span);
 +            current = &args[0];
 +        } else {
 +            break;
 +        }
 +    }
 +
 +    (method_names, arg_lists, spans)
 +}
 +
 +/// Matches an `Expr` against a chain of methods, and return the matched `Expr`s.
 +///
 +/// For example, if `expr` represents the `.baz()` in `foo.bar().baz()`,
 +/// `method_chain_args(expr, &["bar", "baz"])` will return a `Vec`
 +/// containing the `Expr`s for
 +/// `.bar()` and `.baz()`
 +pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<&'a [Expr<'a>]>> {
 +    let mut current = expr;
 +    let mut matched = Vec::with_capacity(methods.len());
 +    for method_name in methods.iter().rev() {
 +        // method chains are stored last -> first
 +        if let ExprKind::MethodCall(ref path, _, ref args, _) = current.kind {
 +            if path.ident.name.as_str() == *method_name {
 +                if args.iter().any(|e| e.span.from_expansion()) {
 +                    return None;
 +                }
 +                matched.push(&**args); // build up `matched` backwards
 +                current = &args[0] // go to parent expression
 +            } else {
 +                return None;
 +            }
 +        } else {
 +            return None;
 +        }
 +    }
 +    // Reverse `matched` so that it is in the same order as `methods`.
 +    matched.reverse();
 +    Some(matched)
 +}
 +
 +/// Returns `true` if the provided `def_id` is an entrypoint to a program.
 +pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool {
 +    cx.tcx
 +        .entry_fn(LOCAL_CRATE)
 +        .map_or(false, |(entry_fn_def_id, _)| def_id == entry_fn_def_id.to_def_id())
 +}
 +
 +/// Returns `true` if the expression is in the program's `#[panic_handler]`.
 +pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 +    let parent = cx.tcx.hir().get_parent_item(e.hir_id);
 +    let def_id = cx.tcx.hir().local_def_id(parent).to_def_id();
 +    Some(def_id) == cx.tcx.lang_items().panic_impl()
 +}
 +
 +/// Gets the name of the item the expression is in, if available.
 +pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
 +    let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id);
 +    match cx.tcx.hir().find(parent_id) {
 +        Some(
 +            Node::Item(Item { ident, .. })
 +            | Node::TraitItem(TraitItem { ident, .. })
 +            | Node::ImplItem(ImplItem { ident, .. }),
 +        ) => Some(ident.name),
 +        _ => None,
 +    }
 +}
 +
 +/// Gets the name of a `Pat`, if any.
 +pub fn get_pat_name(pat: &Pat<'_>) -> Option<Symbol> {
 +    match pat.kind {
 +        PatKind::Binding(.., ref spname, _) => Some(spname.name),
 +        PatKind::Path(ref qpath) => single_segment_path(qpath).map(|ps| ps.ident.name),
 +        PatKind::Box(ref p) | PatKind::Ref(ref p, _) => get_pat_name(&*p),
 +        _ => None,
 +    }
 +}
 +
 +struct ContainsName {
 +    name: Symbol,
 +    result: bool,
 +}
 +
 +impl<'tcx> Visitor<'tcx> for ContainsName {
 +    type Map = Map<'tcx>;
 +
 +    fn visit_name(&mut self, _: Span, name: Symbol) {
 +        if self.name == name {
 +            self.result = true;
 +        }
 +    }
 +    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
 +        NestedVisitorMap::None
 +    }
 +}
 +
 +/// Checks if an `Expr` contains a certain name.
 +pub fn contains_name(name: Symbol, expr: &Expr<'_>) -> bool {
 +    let mut cn = ContainsName { name, result: false };
 +    cn.visit_expr(expr);
 +    cn.result
 +}
 +
 +/// Returns `true` if `expr` contains a return expression
 +pub fn contains_return(expr: &hir::Expr<'_>) -> bool {
 +    struct RetCallFinder {
 +        found: bool,
 +    }
 +
 +    impl<'tcx> hir::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 {
 +                hir::intravisit::walk_expr(self, expr);
 +            }
 +        }
 +
 +        fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
 +            hir::intravisit::NestedVisitorMap::None
 +        }
 +    }
 +
 +    let mut visitor = RetCallFinder { found: false };
 +    visitor.visit_expr(expr);
 +    visitor.found
 +}
 +
 +struct FindMacroCalls<'a, 'b> {
 +    names: &'a [&'b str],
 +    result: Vec<Span>,
 +}
 +
 +impl<'a, 'b, 'tcx> Visitor<'tcx> for FindMacroCalls<'a, 'b> {
 +    type Map = Map<'tcx>;
 +
 +    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
 +        if self.names.iter().any(|fun| is_expn_of(expr.span, fun).is_some()) {
 +            self.result.push(expr.span);
 +        }
 +        // and check sub-expressions
 +        intravisit::walk_expr(self, expr);
 +    }
 +
 +    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
 +        NestedVisitorMap::None
 +    }
 +}
 +
 +/// Finds calls of the specified macros in a function body.
 +pub fn find_macro_calls(names: &[&str], body: &Body<'_>) -> Vec<Span> {
 +    let mut fmc = FindMacroCalls {
 +        names,
 +        result: Vec::new(),
 +    };
 +    fmc.visit_expr(&body.value);
 +    fmc.result
 +}
 +
 +/// Converts a span to a code snippet if available, otherwise use default.
 +///
 +/// This is useful if you want to provide suggestions for your lint or more generally, if you want
 +/// to convert a given `Span` to a `str`.
 +///
 +/// # Example
 +/// ```rust,ignore
 +/// snippet(cx, expr.span, "..")
 +/// ```
 +pub fn snippet<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
 +    snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
 +}
 +
 +/// Same as `snippet`, but it adapts the applicability level by following rules:
 +///
 +/// - Applicability level `Unspecified` will never be changed.
 +/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.
 +/// - If the default value is used and the applicability level is `MachineApplicable`, change it to
 +/// `HasPlaceholders`
 +pub fn snippet_with_applicability<'a, T: LintContext>(
 +    cx: &T,
 +    span: Span,
 +    default: &'a str,
 +    applicability: &mut Applicability,
 +) -> Cow<'a, str> {
 +    if *applicability != Applicability::Unspecified && span.from_expansion() {
 +        *applicability = Applicability::MaybeIncorrect;
 +    }
 +    snippet_opt(cx, span).map_or_else(
 +        || {
 +            if *applicability == Applicability::MachineApplicable {
 +                *applicability = Applicability::HasPlaceholders;
 +            }
 +            Cow::Borrowed(default)
 +        },
 +        From::from,
 +    )
 +}
 +
 +/// Same as `snippet`, but should only be used when it's clear that the input span is
 +/// not a macro argument.
 +pub fn snippet_with_macro_callsite<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
 +    snippet(cx, span.source_callsite(), default)
 +}
 +
 +/// Converts a span to a code snippet. Returns `None` if not available.
 +pub fn snippet_opt<T: LintContext>(cx: &T, span: Span) -> Option<String> {
 +    cx.sess().source_map().span_to_snippet(span).ok()
 +}
 +
 +/// Converts a span (from a block) to a code snippet if available, otherwise use default.
 +///
 +/// This trims the code of indentation, except for the first line. Use it for blocks or block-like
 +/// things which need to be printed as such.
 +///
 +/// The `indent_relative_to` arg can be used, to provide a span, where the indentation of the
 +/// resulting snippet of the given span.
 +///
 +/// # Example
 +///
 +/// ```rust,ignore
 +/// snippet_block(cx, block.span, "..", None)
 +/// // where, `block` is the block of the if expr
 +///     if x {
 +///         y;
 +///     }
 +/// // will return the snippet
 +/// {
 +///     y;
 +/// }
 +/// ```
 +///
 +/// ```rust,ignore
 +/// snippet_block(cx, block.span, "..", Some(if_expr.span))
 +/// // where, `block` is the block of the if expr
 +///     if x {
 +///         y;
 +///     }
 +/// // will return the snippet
 +/// {
 +///         y;
 +///     } // aligned with `if`
 +/// ```
 +/// Note that the first line of the snippet always has 0 indentation.
 +pub fn snippet_block<'a, T: LintContext>(
 +    cx: &T,
 +    span: Span,
 +    default: &'a str,
 +    indent_relative_to: Option<Span>,
 +) -> Cow<'a, str> {
 +    let snip = snippet(cx, span, default);
 +    let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
 +    reindent_multiline(snip, true, indent)
 +}
 +
 +/// Same as `snippet_block`, but adapts the applicability level by the rules of
 +/// `snippet_with_applicability`.
 +pub fn snippet_block_with_applicability<'a, T: LintContext>(
 +    cx: &T,
 +    span: Span,
 +    default: &'a str,
 +    indent_relative_to: Option<Span>,
 +    applicability: &mut Applicability,
 +) -> Cow<'a, str> {
 +    let snip = snippet_with_applicability(cx, span, default, applicability);
 +    let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
 +    reindent_multiline(snip, true, indent)
 +}
 +
 +/// Returns a new Span that extends the original Span to the first non-whitespace char of the first
 +/// line.
 +///
 +/// ```rust,ignore
 +///     let x = ();
 +/// //          ^^
 +/// // will be converted to
 +///     let x = ();
 +/// //  ^^^^^^^^^^
 +/// ```
 +pub fn first_line_of_span<T: LintContext>(cx: &T, span: Span) -> Span {
 +    first_char_in_first_line(cx, span).map_or(span, |first_char_pos| span.with_lo(first_char_pos))
 +}
 +
 +fn first_char_in_first_line<T: LintContext>(cx: &T, span: Span) -> Option<BytePos> {
 +    let line_span = line_span(cx, span);
 +    snippet_opt(cx, line_span).and_then(|snip| {
 +        snip.find(|c: char| !c.is_whitespace())
 +            .map(|pos| line_span.lo() + BytePos::from_usize(pos))
 +    })
 +}
 +
 +/// Returns the indentation of the line of a span
 +///
 +/// ```rust,ignore
 +/// let x = ();
 +/// //      ^^ -- will return 0
 +///     let x = ();
 +/// //          ^^ -- will return 4
 +/// ```
 +pub fn indent_of<T: LintContext>(cx: &T, span: Span) -> Option<usize> {
 +    snippet_opt(cx, line_span(cx, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace()))
 +}
 +
 +/// Returns the positon just before rarrow
 +///
 +/// ```rust,ignore
 +/// fn into(self) -> () {}
 +///              ^
 +/// // in case of unformatted code
 +/// fn into2(self)-> () {}
 +///               ^
 +/// fn into3(self)   -> () {}
 +///               ^
 +/// ```
++pub fn position_before_rarrow(s: &str) -> Option<usize> {
 +    s.rfind("->").map(|rpos| {
 +        let mut rpos = rpos;
 +        let chars: Vec<char> = s.chars().collect();
 +        while rpos > 1 {
 +            if let Some(c) = chars.get(rpos - 1) {
 +                if c.is_whitespace() {
 +                    rpos -= 1;
 +                    continue;
 +                }
 +            }
 +            break;
 +        }
 +        rpos
 +    })
 +}
 +
 +/// Extends the span to the beginning of the spans line, incl. whitespaces.
 +///
 +/// ```rust,ignore
 +///        let x = ();
 +/// //             ^^
 +/// // will be converted to
 +///        let x = ();
 +/// // ^^^^^^^^^^^^^^
 +/// ```
 +fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
 +    let span = original_sp(span, DUMMY_SP);
 +    let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
 +    let line_no = source_map_and_line.line;
 +    let line_start = source_map_and_line.sf.lines[line_no];
 +    Span::new(line_start, span.hi(), span.ctxt())
 +}
 +
 +/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
 +/// Also takes an `Option<String>` which can be put inside the braces.
 +pub fn expr_block<'a, T: LintContext>(
 +    cx: &T,
 +    expr: &Expr<'_>,
 +    option: Option<String>,
 +    default: &'a str,
 +    indent_relative_to: Option<Span>,
 +) -> Cow<'a, str> {
 +    let code = snippet_block(cx, expr.span, default, indent_relative_to);
 +    let string = option.unwrap_or_default();
 +    if expr.span.from_expansion() {
 +        Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default)))
 +    } else if let ExprKind::Block(_, _) = expr.kind {
 +        Cow::Owned(format!("{}{}", code, string))
 +    } else if string.is_empty() {
 +        Cow::Owned(format!("{{ {} }}", code))
 +    } else {
 +        Cow::Owned(format!("{{\n{};\n{}\n}}", code, string))
 +    }
 +}
 +
 +/// Reindent a multiline string with possibility of ignoring the first line.
 +#[allow(clippy::needless_pass_by_value)]
 +pub fn reindent_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>) -> Cow<'_, str> {
 +    let s_space = reindent_multiline_inner(&s, ignore_first, indent, ' ');
 +    let s_tab = reindent_multiline_inner(&s_space, ignore_first, indent, '\t');
 +    reindent_multiline_inner(&s_tab, ignore_first, indent, ' ').into()
 +}
 +
 +fn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option<usize>, ch: char) -> String {
 +    let x = s
 +        .lines()
 +        .skip(ignore_first as usize)
 +        .filter_map(|l| {
 +            if l.is_empty() {
 +                None
 +            } else {
 +                // ignore empty lines
 +                Some(l.char_indices().find(|&(_, x)| x != ch).unwrap_or((l.len(), ch)).0)
 +            }
 +        })
 +        .min()
 +        .unwrap_or(0);
 +    let indent = indent.unwrap_or(0);
 +    s.lines()
 +        .enumerate()
 +        .map(|(i, l)| {
 +            if (ignore_first && i == 0) || l.is_empty() {
 +                l.to_owned()
 +            } else if x > indent {
 +                l.split_at(x - indent).1.to_owned()
 +            } else {
 +                " ".repeat(indent - x) + l
 +            }
 +        })
 +        .collect::<Vec<String>>()
 +        .join("\n")
 +}
 +
 +/// Gets the parent expression, if any –- this is useful to constrain a lint.
 +pub fn get_parent_expr<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
 +    let map = &cx.tcx.hir();
 +    let hir_id = e.hir_id;
 +    let parent_id = map.get_parent_node(hir_id);
 +    if hir_id == parent_id {
 +        return None;
 +    }
 +    map.find(parent_id).and_then(|node| {
 +        if let Node::Expr(parent) = node {
 +            Some(parent)
 +        } else {
 +            None
 +        }
 +    })
 +}
 +
 +pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> {
 +    let map = &cx.tcx.hir();
 +    let enclosing_node = map
 +        .get_enclosing_scope(hir_id)
 +        .and_then(|enclosing_id| map.find(enclosing_id));
 +    enclosing_node.and_then(|node| match node {
 +        Node::Block(block) => Some(block),
 +        Node::Item(&Item {
 +            kind: ItemKind::Fn(_, _, eid),
 +            ..
 +        })
 +        | Node::ImplItem(&ImplItem {
 +            kind: ImplItemKind::Fn(_, eid),
 +            ..
 +        }) => match cx.tcx.hir().body(eid).value.kind {
 +            ExprKind::Block(ref block, _) => Some(block),
 +            _ => None,
 +        },
 +        _ => None,
 +    })
 +}
 +
 +/// Returns the base type for HIR references and pointers.
 +pub fn walk_ptrs_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
 +    match ty.kind {
 +        TyKind::Ptr(ref mut_ty) | TyKind::Rptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
 +        _ => ty,
 +    }
 +}
 +
 +/// Returns the base type for references and raw pointers, and count reference
 +/// depth.
 +pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) {
 +    fn inner(ty: Ty<'_>, depth: usize) -> (Ty<'_>, usize) {
 +        match ty.kind() {
 +            ty::Ref(_, ty, _) => inner(ty, depth + 1),
 +            _ => (ty, depth),
 +        }
 +    }
 +    inner(ty, 0)
 +}
 +
 +/// Checks whether the given expression is a constant integer of the given value.
 +/// unlike `is_integer_literal`, this version does const folding
 +pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool {
 +    if is_integer_literal(e, value) {
 +        return true;
 +    }
 +    let map = cx.tcx.hir();
 +    let parent_item = map.get_parent_item(e.hir_id);
 +    if let Some((Constant::Int(v), _)) = map
 +        .maybe_body_owned_by(parent_item)
 +        .and_then(|body_id| constant(cx, cx.tcx.typeck_body(body_id), e))
 +    {
 +        value == v
 +    } else {
 +        false
 +    }
 +}
 +
 +/// Checks whether the given expression is a constant literal of the given value.
 +pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool {
 +    // FIXME: use constant folding
 +    if let ExprKind::Lit(ref spanned) = expr.kind {
 +        if let LitKind::Int(v, _) = spanned.node {
 +            return v == value;
 +        }
 +    }
 +    false
 +}
 +
 +/// Returns `true` if the given `Expr` has been coerced before.
 +///
 +/// Examples of coercions can be found in the Nomicon at
 +/// <https://doc.rust-lang.org/nomicon/coercions.html>.
 +///
 +/// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_typeck::check::coercion` for more
 +/// information on adjustments and coercions.
 +pub fn is_adjusted(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 +    cx.typeck_results().adjustments().get(e.hir_id).is_some()
 +}
 +
 +/// Returns the pre-expansion span if is this comes from an expansion of the
 +/// macro `name`.
 +/// See also `is_direct_expn_of`.
 +#[must_use]
 +pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
 +    loop {
 +        if span.from_expansion() {
 +            let data = span.ctxt().outer_expn_data();
 +            let new_span = data.call_site;
 +
 +            if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
 +                if mac_name.as_str() == name {
 +                    return Some(new_span);
 +                }
 +            }
 +
 +            span = new_span;
 +        } else {
 +            return None;
 +        }
 +    }
 +}
 +
 +/// Returns the pre-expansion span if the span directly comes from an expansion
 +/// of the macro `name`.
 +/// The difference with `is_expn_of` is that in
 +/// ```rust,ignore
 +/// foo!(bar!(42));
 +/// ```
 +/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only
 +/// `bar!` by
 +/// `is_direct_expn_of`.
 +#[must_use]
 +pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
 +    if span.from_expansion() {
 +        let data = span.ctxt().outer_expn_data();
 +        let new_span = data.call_site;
 +
 +        if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
 +            if mac_name.as_str() == name {
 +                return Some(new_span);
 +            }
 +        }
 +    }
 +
 +    None
 +}
 +
 +/// Convenience function to get the return type of a function.
 +pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_item: hir::HirId) -> Ty<'tcx> {
 +    let fn_def_id = cx.tcx.hir().local_def_id(fn_item);
 +    let ret_ty = cx.tcx.fn_sig(fn_def_id).output();
 +    cx.tcx.erase_late_bound_regions(ret_ty)
 +}
 +
 +/// Walks into `ty` and returns `true` if any inner type is the same as `other_ty`
 +pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
 +    ty.walk().any(|inner| match inner.unpack() {
 +        GenericArgKind::Type(inner_ty) => ty::TyS::same_type(other_ty, inner_ty),
 +        GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
 +    })
 +}
 +
 +/// Returns `true` if the given type is an `unsafe` function.
 +pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 +    match ty.kind() {
 +        ty::FnDef(..) | ty::FnPtr(_) => ty.fn_sig(cx.tcx).unsafety() == Unsafety::Unsafe,
 +        _ => false,
 +    }
 +}
 +
 +pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 +    ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env)
 +}
 +
 +/// Checks if an expression is constructing a tuple-like enum variant or struct
 +pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    if let ExprKind::Call(ref fun, _) = expr.kind {
 +        if let ExprKind::Path(ref qp) = fun.kind {
 +            let res = cx.qpath_res(qp, fun.hir_id);
 +            return match res {
 +                def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
 +                def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
 +                _ => false,
 +            };
 +        }
 +    }
 +    false
 +}
 +
 +/// Returns `true` if a pattern is refutable.
 +// TODO: should be implemented using rustc/mir_build/thir machinery
 +pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
 +    fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {
 +        matches!(
 +            cx.qpath_res(qpath, id),
 +            def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
 +        )
 +    }
 +
 +    fn are_refutable<'a, I: Iterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>, mut i: I) -> bool {
 +        i.any(|pat| is_refutable(cx, pat))
 +    }
 +
 +    match pat.kind {
 +        PatKind::Wild => false,
 +        PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
 +        PatKind::Box(ref pat) | PatKind::Ref(ref pat, _) => is_refutable(cx, pat),
 +        PatKind::Lit(..) | PatKind::Range(..) => true,
 +        PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
 +        PatKind::Or(ref pats) => {
 +            // TODO: should be the honest check, that pats is exhaustive set
 +            are_refutable(cx, pats.iter().map(|pat| &**pat))
 +        },
 +        PatKind::Tuple(ref pats, _) => are_refutable(cx, pats.iter().map(|pat| &**pat)),
 +        PatKind::Struct(ref qpath, ref fields, _) => {
 +            is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat))
 +        },
 +        PatKind::TupleStruct(ref qpath, ref pats, _) => {
 +            is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats.iter().map(|pat| &**pat))
 +        },
 +        PatKind::Slice(ref head, ref middle, ref tail) => {
 +            match &cx.typeck_results().node_type(pat.hir_id).kind() {
 +                ty::Slice(..) => {
 +                    // [..] is the only irrefutable slice pattern.
 +                    !head.is_empty() || middle.is_none() || !tail.is_empty()
 +                },
 +                ty::Array(..) => are_refutable(cx, head.iter().chain(middle).chain(tail.iter()).map(|pat| &**pat)),
 +                _ => {
 +                    // unreachable!()
 +                    true
 +                },
 +            }
 +        },
 +    }
 +}
 +
 +/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d
 +/// implementations have.
 +pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
 +    attrs.iter().any(|attr| attr.has_name(rustc_sym::automatically_derived))
 +}
 +
 +/// Remove blocks around an expression.
 +///
 +/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return
 +/// themselves.
 +pub fn remove_blocks<'tcx>(mut expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
 +    while let ExprKind::Block(ref block, ..) = expr.kind {
 +        match (block.stmts.is_empty(), block.expr.as_ref()) {
 +            (true, Some(e)) => expr = e,
 +            _ => break,
 +        }
 +    }
 +    expr
 +}
 +
 +pub fn is_self(slf: &Param<'_>) -> bool {
 +    if let PatKind::Binding(.., name, _) = slf.pat.kind {
 +        name.name == kw::SelfLower
 +    } else {
 +        false
 +    }
 +}
 +
 +pub fn is_self_ty(slf: &hir::Ty<'_>) -> bool {
 +    if_chain! {
 +        if let TyKind::Path(ref qp) = slf.kind;
 +        if let QPath::Resolved(None, ref path) = *qp;
 +        if let Res::SelfTy(..) = path.res;
 +        then {
 +            return true
 +        }
 +    }
 +    false
 +}
 +
 +pub fn iter_input_pats<'tcx>(decl: &FnDecl<'_>, body: &'tcx Body<'_>) -> impl Iterator<Item = &'tcx Param<'tcx>> {
 +    (0..decl.inputs.len()).map(move |i| &body.params[i])
 +}
 +
 +/// Checks if a given expression is a match expression expanded from the `?`
 +/// operator or the `try` macro.
 +pub fn is_try<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
 +    fn is_ok(arm: &Arm<'_>) -> bool {
 +        if_chain! {
 +            if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pat.kind;
 +            if match_qpath(path, &paths::RESULT_OK[1..]);
 +            if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind;
 +            if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.kind;
 +            if let Res::Local(lid) = path.res;
 +            if lid == hir_id;
 +            then {
 +                return true;
 +            }
 +        }
 +        false
 +    }
 +
 +    fn is_err(arm: &Arm<'_>) -> bool {
 +        if let PatKind::TupleStruct(ref path, _, _) = arm.pat.kind {
 +            match_qpath(path, &paths::RESULT_ERR[1..])
 +        } else {
 +            false
 +        }
 +    }
 +
 +    if let ExprKind::Match(_, ref arms, ref source) = expr.kind {
 +        // desugared from a `?` operator
 +        if let MatchSource::TryDesugar = *source {
 +            return Some(expr);
 +        }
 +
 +        if_chain! {
 +            if arms.len() == 2;
 +            if arms[0].guard.is_none();
 +            if arms[1].guard.is_none();
 +            if (is_ok(&arms[0]) && is_err(&arms[1])) ||
 +                (is_ok(&arms[1]) && is_err(&arms[0]));
 +            then {
 +                return Some(expr);
 +            }
 +        }
 +    }
 +
 +    None
 +}
 +
 +/// Returns `true` if the lint is allowed in the current context
 +///
 +/// Useful for skipping long running code when it's unnecessary
 +pub fn is_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool {
 +    cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
 +}
 +
 +pub fn get_arg_name(pat: &Pat<'_>) -> Option<Symbol> {
 +    match pat.kind {
 +        PatKind::Binding(.., ident, None) => Some(ident.name),
 +        PatKind::Ref(ref subpat, _) => get_arg_name(subpat),
 +        _ => None,
 +    }
 +}
 +
 +pub fn int_bits(tcx: TyCtxt<'_>, ity: ast::IntTy) -> u64 {
 +    Integer::from_attr(&tcx, attr::IntType::SignedInt(ity)).size().bits()
 +}
 +
 +#[allow(clippy::cast_possible_wrap)]
 +/// Turn a constant int byte representation into an i128
 +pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: ast::IntTy) -> i128 {
 +    let amt = 128 - int_bits(tcx, ity);
 +    ((u as i128) << amt) >> amt
 +}
 +
 +#[allow(clippy::cast_sign_loss)]
 +/// clip unused bytes
 +pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: ast::IntTy) -> u128 {
 +    let amt = 128 - int_bits(tcx, ity);
 +    ((u as u128) << amt) >> amt
 +}
 +
 +/// clip unused bytes
 +pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: ast::UintTy) -> u128 {
 +    let bits = Integer::from_attr(&tcx, attr::IntType::UnsignedInt(ity)).size().bits();
 +    let amt = 128 - bits;
 +    (u << amt) >> amt
 +}
 +
 +/// Removes block comments from the given `Vec` of lines.
 +///
 +/// # Examples
 +///
 +/// ```rust,ignore
 +/// without_block_comments(vec!["/*", "foo", "*/"]);
 +/// // => vec![]
 +///
 +/// without_block_comments(vec!["bar", "/*", "foo", "*/"]);
 +/// // => vec!["bar"]
 +/// ```
 +pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> {
 +    let mut without = vec![];
 +
 +    let mut nest_level = 0;
 +
 +    for line in lines {
 +        if line.contains("/*") {
 +            nest_level += 1;
 +            continue;
 +        } else if line.contains("*/") {
 +            nest_level -= 1;
 +            continue;
 +        }
 +
 +        if nest_level == 0 {
 +            without.push(line);
 +        }
 +    }
 +
 +    without
 +}
 +
 +pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool {
 +    let map = &tcx.hir();
 +    let mut prev_enclosing_node = None;
 +    let mut enclosing_node = node;
 +    while Some(enclosing_node) != prev_enclosing_node {
 +        if is_automatically_derived(map.attrs(enclosing_node)) {
 +            return true;
 +        }
 +        prev_enclosing_node = Some(enclosing_node);
 +        enclosing_node = map.get_parent_item(enclosing_node);
 +    }
 +    false
 +}
 +
 +/// Returns true if ty has `iter` or `iter_mut` methods
 +pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> {
 +    // FIXME: instead of this hard-coded list, we should check if `<adt>::iter`
 +    // exists and has the desired signature. Unfortunately FnCtxt is not exported
 +    // so we can't use its `lookup_method` method.
 +    let into_iter_collections: [&[&str]; 13] = [
 +        &paths::VEC,
 +        &paths::OPTION,
 +        &paths::RESULT,
 +        &paths::BTREESET,
 +        &paths::BTREEMAP,
 +        &paths::VEC_DEQUE,
 +        &paths::LINKED_LIST,
 +        &paths::BINARY_HEAP,
 +        &paths::HASHSET,
 +        &paths::HASHMAP,
 +        &paths::PATH_BUF,
 +        &paths::PATH,
 +        &paths::RECEIVER,
 +    ];
 +
 +    let ty_to_check = match probably_ref_ty.kind() {
 +        ty::Ref(_, ty_to_check, _) => ty_to_check,
 +        _ => probably_ref_ty,
 +    };
 +
 +    let def_id = match ty_to_check.kind() {
 +        ty::Array(..) => return Some("array"),
 +        ty::Slice(..) => return Some("slice"),
 +        ty::Adt(adt, _) => adt.did,
 +        _ => return None,
 +    };
 +
 +    for path in &into_iter_collections {
 +        if match_def_path(cx, def_id, path) {
 +            return Some(*path.last().unwrap());
 +        }
 +    }
 +    None
 +}
 +
 +/// Matches a function call with the given path and returns the arguments.
 +///
 +/// Usage:
 +///
 +/// ```rust,ignore
 +/// if let Some(args) = match_function_call(cx, cmp_max_call, &paths::CMP_MAX);
 +/// ```
 +pub fn match_function_call<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    expr: &'tcx Expr<'_>,
 +    path: &[&str],
 +) -> Option<&'tcx [Expr<'tcx>]> {
 +    if_chain! {
 +        if let ExprKind::Call(ref fun, ref args) = expr.kind;
 +        if let ExprKind::Path(ref qpath) = fun.kind;
 +        if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
 +        if match_def_path(cx, fun_def_id, path);
 +        then {
 +            return Some(&args)
 +        }
 +    };
 +    None
 +}
 +
 +/// Checks if `Ty` is normalizable. This function is useful
 +/// to avoid crashes on `layout_of`.
 +pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
 +    cx.tcx.infer_ctxt().enter(|infcx| {
 +        let cause = rustc_middle::traits::ObligationCause::dummy();
 +        infcx.at(&cause, param_env).normalize(ty).is_ok()
 +    })
 +}
 +
 +pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool {
 +    // We have to convert `syms` to `&[Symbol]` here because rustc's `match_def_path`
 +    // accepts only that. We should probably move to Symbols in Clippy as well.
 +    let syms = syms.iter().map(|p| Symbol::intern(p)).collect::<Vec<Symbol>>();
 +    cx.match_def_path(did, &syms)
 +}
 +
 +pub fn match_panic_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx [Expr<'tcx>]> {
 +    match_function_call(cx, expr, &paths::BEGIN_PANIC)
 +        .or_else(|| match_function_call(cx, expr, &paths::BEGIN_PANIC_FMT))
 +        .or_else(|| match_function_call(cx, expr, &paths::PANIC_ANY))
 +        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC))
 +        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_FMT))
 +        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_STR))
 +}
 +
 +pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
 +    match_def_path(cx, did, &paths::BEGIN_PANIC)
 +        || match_def_path(cx, did, &paths::BEGIN_PANIC_FMT)
 +        || match_def_path(cx, did, &paths::PANIC_ANY)
 +        || match_def_path(cx, did, &paths::PANICKING_PANIC)
 +        || match_def_path(cx, did, &paths::PANICKING_PANIC_FMT)
 +        || match_def_path(cx, did, &paths::PANICKING_PANIC_STR)
 +}
 +
 +/// Returns the list of condition expressions and the list of blocks in a
 +/// sequence of `if/else`.
 +/// E.g., this returns `([a, b], [c, d, e])` for the expression
 +/// `if a { c } else if b { d } else { e }`.
 +pub fn if_sequence<'tcx>(
 +    mut expr: &'tcx Expr<'tcx>,
 +) -> (SmallVec<[&'tcx Expr<'tcx>; 1]>, SmallVec<[&'tcx Block<'tcx>; 1]>) {
 +    let mut conds = SmallVec::new();
 +    let mut blocks: SmallVec<[&Block<'_>; 1]> = SmallVec::new();
 +
 +    while let Some((ref cond, ref then_expr, ref else_expr)) = higher::if_block(&expr) {
 +        conds.push(&**cond);
 +        if let ExprKind::Block(ref block, _) = then_expr.kind {
 +            blocks.push(block);
 +        } else {
 +            panic!("ExprKind::If node is not an ExprKind::Block");
 +        }
 +
 +        if let Some(ref else_expr) = *else_expr {
 +            expr = else_expr;
 +        } else {
 +            break;
 +        }
 +    }
 +
 +    // final `else {..}`
 +    if !blocks.is_empty() {
 +        if let ExprKind::Block(ref block, _) = expr.kind {
 +            blocks.push(&**block);
 +        }
 +    }
 +
 +    (conds, blocks)
 +}
 +
 +pub fn parent_node_is_if_expr(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
 +    let map = cx.tcx.hir();
 +    let parent_id = map.get_parent_node(expr.hir_id);
 +    let parent_node = map.get(parent_id);
 +
 +    match parent_node {
 +        Node::Expr(e) => higher::if_block(&e).is_some(),
 +        Node::Arm(e) => higher::if_block(&e.body).is_some(),
 +        _ => false,
 +    }
 +}
 +
 +// Finds the attribute with the given name, if any
 +pub fn attr_by_name<'a>(attrs: &'a [Attribute], name: &'_ str) -> Option<&'a Attribute> {
 +    attrs
 +        .iter()
 +        .find(|attr| attr.ident().map_or(false, |ident| ident.as_str() == name))
 +}
 +
 +// Finds the `#[must_use]` attribute, if any
 +pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> {
 +    attr_by_name(attrs, "must_use")
 +}
 +
 +// Returns whether the type has #[must_use] attribute
 +pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 +    match ty.kind() {
 +        ty::Adt(ref adt, _) => must_use_attr(&cx.tcx.get_attrs(adt.did)).is_some(),
 +        ty::Foreign(ref did) => must_use_attr(&cx.tcx.get_attrs(*did)).is_some(),
 +        ty::Slice(ref ty)
 +        | ty::Array(ref ty, _)
 +        | ty::RawPtr(ty::TypeAndMut { ref ty, .. })
 +        | ty::Ref(_, ref ty, _) => {
 +            // for the Array case we don't need to care for the len == 0 case
 +            // because we don't want to lint functions returning empty arrays
 +            is_must_use_ty(cx, *ty)
 +        },
 +        ty::Tuple(ref substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)),
 +        ty::Opaque(ref def_id, _) => {
 +            for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) {
 +                if let ty::PredicateAtom::Trait(trait_predicate, _) = predicate.skip_binders() {
 +                    if must_use_attr(&cx.tcx.get_attrs(trait_predicate.trait_ref.def_id)).is_some() {
 +                        return true;
 +                    }
 +                }
 +            }
 +            false
 +        },
 +        ty::Dynamic(binder, _) => {
 +            for predicate in binder.iter() {
 +                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
 +                    if must_use_attr(&cx.tcx.get_attrs(trait_ref.def_id)).is_some() {
 +                        return true;
 +                    }
 +                }
 +            }
 +            false
 +        },
 +        _ => false,
 +    }
 +}
 +
 +// check if expr is calling method or function with #[must_use] attribute
 +pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 +    let did = match expr.kind {
 +        ExprKind::Call(ref path, _) => if_chain! {
 +            if let ExprKind::Path(ref qpath) = path.kind;
 +            if let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id);
 +            then {
 +                Some(did)
 +            } else {
 +                None
 +            }
 +        },
 +        ExprKind::MethodCall(_, _, _, _) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
 +        _ => None,
 +    };
 +
 +    did.map_or(false, |did| must_use_attr(&cx.tcx.get_attrs(did)).is_some())
 +}
 +
 +pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
 +    krate.item.attrs.iter().any(|attr| {
 +        if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
 +            attr.path == symbol::sym::no_std
 +        } else {
 +            false
 +        }
 +    })
 +}
 +
 +/// Check if parent of a hir node is a trait implementation block.
 +/// For example, `f` in
 +/// ```rust,ignore
 +/// impl Trait for S {
 +///     fn f() {}
 +/// }
 +/// ```
 +pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
 +    if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
 +        matches!(item.kind, ItemKind::Impl { of_trait: Some(_), .. })
 +    } else {
 +        false
 +    }
 +}
 +
 +/// Check if it's even possible to satisfy the `where` clause for the item.
 +///
 +/// `trivial_bounds` feature allows functions with unsatisfiable bounds, for example:
 +///
 +/// ```ignore
 +/// fn foo() where i32: Iterator {
 +///     for _ in 2i32 {}
 +/// }
 +/// ```
 +pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool {
 +    use rustc_trait_selection::traits;
 +    let predicates =
 +        cx.tcx
 +            .predicates_of(did)
 +            .predicates
 +            .iter()
 +            .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
 +    traits::impossible_predicates(
 +        cx.tcx,
 +        traits::elaborate_predicates(cx.tcx, predicates)
 +            .map(|o| o.predicate)
 +            .collect::<Vec<_>>(),
 +    )
 +}
 +
 +/// Returns the `DefId` of the callee if the given expression is a function or method call.
 +pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
 +    match &expr.kind {
 +        ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
 +        ExprKind::Call(
 +            Expr {
 +                kind: ExprKind::Path(qpath),
 +                ..
 +            },
 +            ..,
 +        ) => cx.typeck_results().qpath_res(qpath, expr.hir_id).opt_def_id(),
 +        _ => None,
 +    }
 +}
 +
 +pub fn run_lints(cx: &LateContext<'_>, lints: &[&'static Lint], id: HirId) -> bool {
 +    lints.iter().any(|lint| {
 +        matches!(
 +            cx.tcx.lint_level_at_node(lint, id),
 +            (Level::Forbid | Level::Deny | Level::Warn, _)
 +        )
 +    })
 +}
 +
 +/// Returns true iff the given type is a primitive (a bool or char, any integer or floating-point
 +/// number type, a str, or an array, slice, or tuple of those types).
 +pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
 +    match ty.kind() {
 +        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true,
 +        ty::Ref(_, inner, _) if *inner.kind() == ty::Str => true,
 +        ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type),
 +        ty::Tuple(inner_types) => inner_types.types().all(is_recursively_primitive_type),
 +        _ => false,
 +    }
 +}
 +
 +/// Returns Option<String> where String is a textual representation of the type encapsulated in the
 +/// slice iff the given expression is a slice of primitives (as defined in the
 +/// `is_recursively_primitive_type` function) and None otherwise.
 +pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
 +    let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
 +    let expr_kind = expr_type.kind();
 +    let is_primitive = match expr_kind {
 +        ty::Slice(element_type) => is_recursively_primitive_type(element_type),
 +        ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), &ty::Slice(_)) => {
 +            if let ty::Slice(element_type) = inner_ty.kind() {
 +                is_recursively_primitive_type(element_type)
 +            } else {
 +                unreachable!()
 +            }
 +        },
 +        _ => false,
 +    };
 +
 +    if is_primitive {
 +        // if we have wrappers like Array, Slice or Tuple, print these
 +        // and get the type enclosed in the slice ref
 +        match expr_type.peel_refs().walk().nth(1).unwrap().expect_ty().kind() {
 +            ty::Slice(..) => return Some("slice".into()),
 +            ty::Array(..) => return Some("array".into()),
 +            ty::Tuple(..) => return Some("tuple".into()),
 +            _ => {
 +                // is_recursively_primitive_type() should have taken care
 +                // of the rest and we can rely on the type that is found
 +                let refs_peeled = expr_type.peel_refs();
 +                return Some(refs_peeled.walk().last().unwrap().to_string());
 +            },
 +        }
 +    }
 +    None
 +}
 +
 +/// returns list of all pairs (a, b) from `exprs` such that `eq(a, b)`
 +/// `hash` must be comformed with `eq`
 +pub fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)>
 +where
 +    Hash: Fn(&T) -> u64,
 +    Eq: Fn(&T, &T) -> bool,
 +{
 +    if exprs.len() == 2 && eq(&exprs[0], &exprs[1]) {
 +        return vec![(&exprs[0], &exprs[1])];
 +    }
 +
 +    let mut match_expr_list: Vec<(&T, &T)> = Vec::new();
 +
 +    let mut map: FxHashMap<_, Vec<&_>> =
 +        FxHashMap::with_capacity_and_hasher(exprs.len(), BuildHasherDefault::default());
 +
 +    for expr in exprs {
 +        match map.entry(hash(expr)) {
 +            Entry::Occupied(mut o) => {
 +                for o in o.get() {
 +                    if eq(o, expr) {
 +                        match_expr_list.push((o, expr));
 +                    }
 +                }
 +                o.get_mut().push(expr);
 +            },
 +            Entry::Vacant(v) => {
 +                v.insert(vec![expr]);
 +            },
 +        }
 +    }
 +
 +    match_expr_list
 +}
 +
 +#[macro_export]
 +macro_rules! unwrap_cargo_metadata {
 +    ($cx: ident, $lint: ident, $deps: expr) => {{
 +        let mut command = cargo_metadata::MetadataCommand::new();
 +        if !$deps {
 +            command.no_deps();
 +        }
 +
 +        match command.exec() {
 +            Ok(metadata) => metadata,
 +            Err(err) => {
 +                span_lint($cx, $lint, DUMMY_SP, &format!("could not read cargo metadata: {}", err));
 +                return;
 +            },
 +        }
 +    }};
 +}
 +
 +#[cfg(test)]
 +mod test {
 +    use super::{reindent_multiline, without_block_comments};
 +
 +    #[test]
 +    fn test_reindent_multiline_single_line() {
 +        assert_eq!("", reindent_multiline("".into(), false, None));
 +        assert_eq!("...", reindent_multiline("...".into(), false, None));
 +        assert_eq!("...", reindent_multiline("    ...".into(), false, None));
 +        assert_eq!("...", reindent_multiline("\t...".into(), false, None));
 +        assert_eq!("...", reindent_multiline("\t\t...".into(), false, None));
 +    }
 +
 +    #[test]
 +    #[rustfmt::skip]
 +    fn test_reindent_multiline_block() {
 +        assert_eq!("\
 +    if x {
 +        y
 +    } else {
 +        z
 +    }", reindent_multiline("    if x {
 +            y
 +        } else {
 +            z
 +        }".into(), false, None));
 +        assert_eq!("\
 +    if x {
 +    \ty
 +    } else {
 +    \tz
 +    }", reindent_multiline("    if x {
 +        \ty
 +        } else {
 +        \tz
 +        }".into(), false, None));
 +    }
 +
 +    #[test]
 +    #[rustfmt::skip]
 +    fn test_reindent_multiline_empty_line() {
 +        assert_eq!("\
 +    if x {
 +        y
 +
 +    } else {
 +        z
 +    }", reindent_multiline("    if x {
 +            y
 +
 +        } else {
 +            z
 +        }".into(), false, None));
 +    }
 +
 +    #[test]
 +    #[rustfmt::skip]
 +    fn test_reindent_multiline_lines_deeper() {
 +        assert_eq!("\
 +        if x {
 +            y
 +        } else {
 +            z
 +        }", reindent_multiline("\
 +    if x {
 +        y
 +    } else {
 +        z
 +    }".into(), true, Some(8)));
 +    }
 +
 +    #[test]
 +    fn test_without_block_comments_lines_without_block_comments() {
 +        let result = without_block_comments(vec!["/*", "", "*/"]);
 +        println!("result: {:?}", result);
 +        assert!(result.is_empty());
 +
 +        let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]);
 +        assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]);
 +
 +        let result = without_block_comments(vec!["/* rust", "", "*/"]);
 +        assert!(result.is_empty());
 +
 +        let result = without_block_comments(vec!["/* one-line comment */"]);
 +        assert!(result.is_empty());
 +
 +        let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]);
 +        assert!(result.is_empty());
 +
 +        let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]);
 +        assert!(result.is_empty());
 +
 +        let result = without_block_comments(vec!["foo", "bar", "baz"]);
 +        assert_eq!(result, vec!["foo", "bar", "baz"]);
 +    }
 +}
index bd2c619f00028167c4b730a3966cc3a31130aed9,0000000000000000000000000000000000000000..b330f3d890e9cc6e4a3823629e30a0cb2f04d942
mode 100644,000000..100644
--- /dev/null
@@@ -1,87 -1,0 +1,86 @@@
-             return;
 +use crate::utils::{get_pat_name, match_var, snippet};
 +use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 +use rustc_hir::{Body, BodyId, Expr, ExprKind, Param};
 +use rustc_lint::LateContext;
 +use rustc_middle::hir::map::Map;
 +use rustc_span::{Span, Symbol};
 +use std::borrow::Cow;
 +
 +pub fn get_spans(
 +    cx: &LateContext<'_>,
 +    opt_body_id: Option<BodyId>,
 +    idx: usize,
 +    replacements: &[(&'static str, &'static str)],
 +) -> Option<Vec<(Span, Cow<'static, str>)>> {
 +    if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
 +        get_binding_name(&body.params[idx]).map_or_else(
 +            || Some(vec![]),
 +            |name| extract_clone_suggestions(cx, name, replacements, body),
 +        )
 +    } else {
 +        Some(vec![])
 +    }
 +}
 +
 +fn extract_clone_suggestions<'tcx>(
 +    cx: &LateContext<'tcx>,
 +    name: Symbol,
 +    replace: &[(&'static str, &'static str)],
 +    body: &'tcx Body<'_>,
 +) -> Option<Vec<(Span, Cow<'static, str>)>> {
 +    let mut visitor = PtrCloneVisitor {
 +        cx,
 +        name,
 +        replace,
 +        spans: vec![],
 +        abort: false,
 +    };
 +    visitor.visit_body(body);
 +    if visitor.abort {
 +        None
 +    } else {
 +        Some(visitor.spans)
 +    }
 +}
 +
 +struct PtrCloneVisitor<'a, 'tcx> {
 +    cx: &'a LateContext<'tcx>,
 +    name: Symbol,
 +    replace: &'a [(&'static str, &'static str)],
 +    spans: Vec<(Span, Cow<'static, str>)>,
 +    abort: bool,
 +}
 +
 +impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
 +    type Map = Map<'tcx>;
 +
 +    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
 +        if self.abort {
 +            return;
 +        }
 +        if let ExprKind::MethodCall(ref seg, _, ref args, _) = expr.kind {
 +            if args.len() == 1 && match_var(&args[0], self.name) {
 +                if seg.ident.name.as_str() == "capacity" {
 +                    self.abort = true;
 +                    return;
 +                }
 +                for &(fn_name, suffix) in self.replace {
 +                    if seg.ident.name.as_str() == fn_name {
 +                        self.spans
 +                            .push((expr.span, snippet(self.cx, args[0].span, "_") + suffix));
 +                        return;
 +                    }
 +                }
 +            }
 +        }
 +        walk_expr(self, expr);
 +    }
 +
 +    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
 +        NestedVisitorMap::None
 +    }
 +}
 +
 +fn get_binding_name(arg: &Param<'_>) -> Option<Symbol> {
 +    get_pat_name(&arg.pat)
 +}
index d2e84132f4ed9baee6717728dced000c97015530,0000000000000000000000000000000000000000..c579beeae89beca81922be2a546603b338fd8e6f
mode 100644,000000..100644
--- /dev/null
@@@ -1,3 -1,0 +1,3 @@@
- channel = "nightly-2020-12-20"
 +[toolchain]
++channel = "nightly-2021-01-02"
 +components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]
index f985a15eda2bb5cbc48fecbbdd1e8c1b0205346e,0000000000000000000000000000000000000000..1832482346820af414a29bddccd0992cbf7442a2
mode 100644,000000..100644
--- /dev/null
@@@ -1,86 -1,0 +1,96 @@@
 +#![allow(dead_code)]
 +
 +//! Used to test that certain lints don't trigger in imported external macros
 +
 +#[macro_export]
 +macro_rules! foofoo {
 +    () => {
 +        loop {}
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! must_use_unit {
 +    () => {
 +        #[must_use]
 +        fn foo() {}
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! try_err {
 +    () => {
 +        pub fn try_err_fn() -> Result<i32, i32> {
 +            let err: i32 = 1;
 +            // To avoid warnings during rustfix
 +            if true {
 +                Err(err)?
 +            } else {
 +                Ok(2)
 +            }
 +        }
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! string_add {
 +    () => {
 +        let y = "".to_owned();
 +        let z = y + "...";
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! take_external {
 +    ($s:expr) => {
 +        std::mem::replace($s, Default::default())
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! option_env_unwrap_external {
 +    ($env: expr) => {
 +        option_env!($env).unwrap()
 +    };
 +    ($env: expr, $message: expr) => {
 +        option_env!($env).expect($message)
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! ref_arg_binding {
 +    () => {
 +        let ref _y = 42;
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! ref_arg_function {
 +    () => {
 +        fn fun_example(ref _x: usize) {}
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! as_conv_with_arg {
 +    (0u32 as u64) => {
 +        ()
 +    };
 +}
 +
 +#[macro_export]
 +macro_rules! as_conv {
 +    () => {
 +        0u32 as u64
 +    };
 +}
++
++#[macro_export]
++macro_rules! large_enum_variant {
++    () => {
++        enum LargeEnumInMacro {
++            A(i32),
++            B([i32; 8000]),
++        }
++    };
++}
index 79a30c22f953658269ee94b88de670e4d9f6257a,0000000000000000000000000000000000000000..3e0921022b4174cf4faa22bae70d821a0055dfc6
mode 100644,000000..100644
--- /dev/null
@@@ -1,110 -1,0 +1,122 @@@
 +#![warn(clippy::field_reassign_with_default)]
 +
 +#[derive(Default)]
 +struct A {
 +    i: i32,
 +    j: i64,
 +}
 +
 +struct B {
 +    i: i32,
 +    j: i64,
 +}
 +
 +/// Implements .next() that returns a different number each time.
 +struct SideEffect(i32);
 +
 +impl SideEffect {
 +    fn new() -> SideEffect {
 +        SideEffect(0)
 +    }
 +    fn next(&mut self) -> i32 {
 +        self.0 += 1;
 +        self.0
 +    }
 +}
 +
 +fn main() {
 +    // wrong, produces first error in stderr
 +    let mut a: A = Default::default();
 +    a.i = 42;
 +
 +    // right
 +    let mut a: A = Default::default();
 +
 +    // right
 +    let a = A {
 +        i: 42,
 +        ..Default::default()
 +    };
 +
 +    // right
 +    let mut a: A = Default::default();
 +    if a.i == 0 {
 +        a.j = 12;
 +    }
 +
 +    // right
 +    let mut a: A = Default::default();
 +    let b = 5;
 +
 +    // right
 +    let mut b = 32;
 +    let mut a: A = Default::default();
 +    b = 2;
 +
 +    // right
 +    let b: B = B { i: 42, j: 24 };
 +
 +    // right
 +    let mut b: B = B { i: 42, j: 24 };
 +    b.i = 52;
 +
 +    // right
 +    let mut b = B { i: 15, j: 16 };
 +    let mut a: A = Default::default();
 +    b.i = 2;
 +
 +    // wrong, produces second error in stderr
 +    let mut a: A = Default::default();
 +    a.j = 43;
 +    a.i = 42;
 +
 +    // wrong, produces third error in stderr
 +    let mut a: A = Default::default();
 +    a.i = 42;
 +    a.j = 43;
 +    a.j = 44;
 +
 +    // wrong, produces fourth error in stderr
 +    let mut a = A::default();
 +    a.i = 42;
 +
 +    // wrong, but does not produce an error in stderr, because we can't produce a correct kind of
 +    // suggestion with current implementation
 +    let mut c: (i32, i32) = Default::default();
 +    c.0 = 42;
 +    c.1 = 21;
 +
 +    // wrong, produces the fifth error in stderr
 +    let mut a: A = Default::default();
 +    a.i = Default::default();
 +
 +    // wrong, produces the sixth error in stderr
 +    let mut a: A = Default::default();
 +    a.i = Default::default();
 +    a.j = 45;
 +
 +    // right, because an assignment refers to another field
 +    let mut x = A::default();
 +    x.i = 42;
 +    x.j = 21 + x.i as i64;
 +
 +    // right, we bail out if there's a reassignment to the same variable, since there is a risk of
 +    // side-effects affecting the outcome
 +    let mut x = A::default();
 +    let mut side_effect = SideEffect::new();
 +    x.i = side_effect.next();
 +    x.j = 2;
 +    x.i = side_effect.next();
++
++    // don't lint - some private fields
++    let mut x = m::F::default();
++    x.a = 1;
++}
++
++mod m {
++    #[derive(Default)]
++    pub struct F {
++        pub a: u64,
++        b: u64,
++    }
 +}
index c788ebae5526ce4e397038b07a0dca309067e7a1,0000000000000000000000000000000000000000..9a2bc778c3ff7ba5e03faccf7d69eda2e3f61d3a
mode 100644,000000..100644
--- /dev/null
@@@ -1,75 -1,0 +1,75 @@@
- note: consider initializing the variable with `A::default()` and removing relevant reassignments
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:30:5
 +   |
 +LL |     a.i = 42;
 +   |     ^^^^^^^^^
 +   |
 +   = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
 +note: consider initializing the variable with `A { i: 42, ..Default::default() }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:29:5
 +   |
 +LL |     let mut a: A = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:70:5
 +   |
 +LL |     a.j = 43;
 +   |     ^^^^^^^^^
 +   |
 +note: consider initializing the variable with `A { j: 43, i: 42 }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:69:5
 +   |
 +LL |     let mut a: A = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:75:5
 +   |
 +LL |     a.i = 42;
 +   |     ^^^^^^^^^
 +   |
 +note: consider initializing the variable with `A { i: 42, j: 44 }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:74:5
 +   |
 +LL |     let mut a: A = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:81:5
 +   |
 +LL |     a.i = 42;
 +   |     ^^^^^^^^^
 +   |
 +note: consider initializing the variable with `A { i: 42, ..Default::default() }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:80:5
 +   |
 +LL |     let mut a = A::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:91:5
 +   |
 +LL |     a.i = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
- note: consider initializing the variable with `A { j: 45, ..Default::default() }` and removing relevant reassignments
++note: consider initializing the variable with `A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:90:5
 +   |
 +LL |     let mut a: A = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: field assignment outside of initializer for an instance created with Default::default()
 +  --> $DIR/field_reassign_with_default.rs:95:5
 +   |
 +LL |     a.i = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 +   |
++note: consider initializing the variable with `A { i: Default::default(), j: 45 }` and removing relevant reassignments
 +  --> $DIR/field_reassign_with_default.rs:94:5
 +   |
 +LL |     let mut a: A = Default::default();
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: aborting due to 6 previous errors
 +
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..292d0924fb17a4ca1b32bf0a39fa6a81fdc68e82
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++#![warn(clippy::from_over_into)]
++
++// this should throw an error
++struct StringWrapper(String);
++
++impl Into<StringWrapper> for String {
++    fn into(self) -> StringWrapper {
++        StringWrapper(self)
++    }
++}
++
++// this is fine
++struct A(String);
++
++impl From<String> for A {
++    fn from(s: String) -> A {
++        A(s)
++    }
++}
++
++fn main() {}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..18f56f854329e364a2c3e526c254a9e1b5eda0da
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
++  --> $DIR/from_over_into.rs:6:1
++   |
++LL | / impl Into<StringWrapper> for String {
++LL | |     fn into(self) -> StringWrapper {
++LL | |         StringWrapper(self)
++LL | |     }
++LL | | }
++   | |_^
++   |
++   = note: `-D clippy::from-over-into` implied by `-D warnings`
++   = help: consider to implement `From` instead
++
++error: aborting due to previous error
++
index 852ef5fec0e7b060332bca56b8fb96e29d555e72,0000000000000000000000000000000000000000..d22fee3f27b05818c3ed86e1127c010726bb7afa
mode 100644,000000..100644
--- /dev/null
@@@ -1,54 -1,0 +1,61 @@@
- fn main() {}
++// aux-build:macro_rules.rs
++
 +#![allow(dead_code)]
 +#![allow(unused_variables)]
 +#![warn(clippy::large_enum_variant)]
 +
++#[macro_use]
++extern crate macro_rules;
++
 +enum LargeEnum {
 +    A(i32),
 +    B([i32; 8000]),
 +}
 +
 +enum GenericEnumOk<T> {
 +    A(i32),
 +    B([T; 8000]),
 +}
 +
 +enum GenericEnum2<T> {
 +    A(i32),
 +    B([i32; 8000]),
 +    C(T, [i32; 8000]),
 +}
 +
 +trait SomeTrait {
 +    type Item;
 +}
 +
 +enum LargeEnumGeneric<A: SomeTrait> {
 +    Var(A::Item),
 +}
 +
 +enum LargeEnum2 {
 +    VariantOk(i32, u32),
 +    ContainingLargeEnum(LargeEnum),
 +}
 +enum LargeEnum3 {
 +    ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
 +    VoidVariant,
 +    StructLikeLittle { x: i32, y: i32 },
 +}
 +
 +enum LargeEnum4 {
 +    VariantOk(i32, u32),
 +    StructLikeLarge { x: [i32; 8000], y: i32 },
 +}
 +
 +enum LargeEnum5 {
 +    VariantOk(i32, u32),
 +    StructLikeLarge2 { x: [i32; 8000] },
 +}
 +
 +enum LargeEnumOk {
 +    LargeA([i32; 8000]),
 +    LargeB([i32; 8001]),
 +}
 +
++fn main() {
++    large_enum_variant!();
++}
index 8ce641a81f29746289c9b750b11cad95ba133cf2,0000000000000000000000000000000000000000..d39a4d462aabde949de878d8821d11950cecfc73
mode 100644,000000..100644
--- /dev/null
@@@ -1,68 -1,0 +1,68 @@@
-   --> $DIR/large_enum_variant.rs:7:5
 +error: large size difference between variants
-   --> $DIR/large_enum_variant.rs:6:5
++  --> $DIR/large_enum_variant.rs:12:5
 +   |
 +LL |     B([i32; 8000]),
 +   |     ^^^^^^^^^^^^^^ this variant is 32000 bytes
 +   |
 +   = note: `-D clippy::large-enum-variant` implied by `-D warnings`
 +note: and the second-largest variant is 4 bytes:
-   --> $DIR/large_enum_variant.rs:31:5
++  --> $DIR/large_enum_variant.rs:11:5
 +   |
 +LL |     A(i32),
 +   |     ^^^^^^
 +help: consider boxing the large fields to reduce the total size of the enum
 +   |
 +LL |     B(Box<[i32; 8000]>),
 +   |       ^^^^^^^^^^^^^^^^
 +
 +error: large size difference between variants
-   --> $DIR/large_enum_variant.rs:30:5
++  --> $DIR/large_enum_variant.rs:36:5
 +   |
 +LL |     ContainingLargeEnum(LargeEnum),
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
 +   |
 +note: and the second-largest variant is 8 bytes:
-   --> $DIR/large_enum_variant.rs:41:5
++  --> $DIR/large_enum_variant.rs:35:5
 +   |
 +LL |     VariantOk(i32, u32),
 +   |     ^^^^^^^^^^^^^^^^^^^
 +help: consider boxing the large fields to reduce the total size of the enum
 +   |
 +LL |     ContainingLargeEnum(Box<LargeEnum>),
 +   |                         ^^^^^^^^^^^^^^
 +
 +error: large size difference between variants
-   --> $DIR/large_enum_variant.rs:40:5
++  --> $DIR/large_enum_variant.rs:46:5
 +   |
 +LL |     StructLikeLarge { x: [i32; 8000], y: i32 },
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
 +   |
 +note: and the second-largest variant is 8 bytes:
-   --> $DIR/large_enum_variant.rs:41:5
++  --> $DIR/large_enum_variant.rs:45:5
 +   |
 +LL |     VariantOk(i32, u32),
 +   |     ^^^^^^^^^^^^^^^^^^^
 +help: consider boxing the large fields to reduce the total size of the enum
-   --> $DIR/large_enum_variant.rs:46:5
++  --> $DIR/large_enum_variant.rs:46:5
 +   |
 +LL |     StructLikeLarge { x: [i32; 8000], y: i32 },
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +
 +error: large size difference between variants
-   --> $DIR/large_enum_variant.rs:45:5
++  --> $DIR/large_enum_variant.rs:51:5
 +   |
 +LL |     StructLikeLarge2 { x: [i32; 8000] },
 +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes
 +   |
 +note: and the second-largest variant is 8 bytes:
++  --> $DIR/large_enum_variant.rs:50:5
 +   |
 +LL |     VariantOk(i32, u32),
 +   |     ^^^^^^^^^^^^^^^^^^^
 +help: consider boxing the large fields to reduce the total size of the enum
 +   |
 +LL |     StructLikeLarge2 { x: Box<[i32; 8000]> },
 +   |                           ^^^^^^^^^^^^^^^^
 +
 +error: aborting due to 4 previous errors
 +
index 8ee2941790d3542d243502c8dd81135480830d06,0000000000000000000000000000000000000000..37e87e64de28f1be6c43b29e5ac6f56f2e12afa3
mode 100644,000000..100644
--- /dev/null
@@@ -1,11 -1,0 +1,11 @@@
-    = help: Consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)
 +error: `map_err(|_|...` wildcard pattern discards the original error
 +  --> $DIR/map_err.rs:23:32
 +   |
 +LL |     println!("{:?}", x.map_err(|_| Errors::Ignored));
 +   |                                ^^^
 +   |
 +   = note: `-D clippy::map-err-ignore` implied by `-D warnings`
++   = help: consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)
 +
 +error: aborting due to previous error
 +
index 3848bca3207596fd6d16901b5a425e109a88f093,0000000000000000000000000000000000000000..0f47f1cbc4026cb77c88eb4e70612e83ba70a60c
mode 100644,000000..100644
--- /dev/null
@@@ -1,169 -1,0 +1,177 @@@
 +#![allow(clippy::redundant_clone)]
 +#![feature(custom_inner_attributes)]
 +#![clippy::msrv = "1.0.0"]
 +
 +use std::ops::{Deref, RangeFrom};
 +
 +fn option_as_ref_deref() {
 +    let mut opt = Some(String::from("123"));
 +
 +    let _ = opt.as_ref().map(String::as_str);
 +    let _ = opt.as_ref().map(|x| x.as_str());
 +    let _ = opt.as_mut().map(String::as_mut_str);
 +    let _ = opt.as_mut().map(|x| x.as_mut_str());
 +}
 +
 +fn match_like_matches() {
 +    let _y = match Some(5) {
 +        Some(0) => true,
 +        _ => false,
 +    };
 +}
 +
 +fn match_same_arms() {
 +    match (1, 2, 3) {
 +        (1, .., 3) => 42,
 +        (.., 3) => 42, //~ ERROR match arms have same body
 +        _ => 0,
 +    };
 +}
 +
 +fn match_same_arms2() {
 +    let _ = match Some(42) {
 +        Some(_) => 24,
 +        None => 24, //~ ERROR match arms have same body
 +    };
 +}
 +
 +pub fn manual_strip_msrv() {
 +    let s = "hello, world!";
 +    if s.starts_with("hello, ") {
 +        assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +    }
 +}
 +
 +pub fn redundant_fieldnames() {
 +    let start = 0;
 +    let _ = RangeFrom { start: start };
 +}
 +
 +pub fn redundant_static_lifetime() {
 +    const VAR_ONE: &'static str = "Test constant #1";
 +}
 +
 +pub fn checked_conversion() {
 +    let value: i64 = 42;
 +    let _ = value <= (u32::max_value() as i64) && value >= 0;
 +    let _ = value <= (u32::MAX as i64) && value >= 0;
 +}
 +
++pub struct FromOverInto(String);
++
++impl Into<FromOverInto> for String {
++    fn into(self) -> FromOverInto {
++        FromOverInto(self)
++    }
++}
++
 +pub fn filter_map_next() {
 +    let a = ["1", "lol", "3", "NaN", "5"];
 +
 +    #[rustfmt::skip]
 +    let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]
 +        .into_iter()
 +        .filter_map(|x| {
 +            if x == 2 {
 +                Some(x * 2)
 +            } else {
 +                None
 +            }
 +        })
 +        .next();
 +}
 +
 +#[allow(clippy::no_effect)]
 +#[allow(clippy::short_circuit_statement)]
 +#[allow(clippy::unnecessary_operation)]
 +pub fn manual_range_contains() {
 +    let x = 5;
 +    x >= 8 && x < 12;
 +}
 +
 +pub fn use_self() {
 +    struct Foo {}
 +
 +    impl Foo {
 +        fn new() -> Foo {
 +            Foo {}
 +        }
 +        fn test() -> Foo {
 +            Foo::new()
 +        }
 +    }
 +}
 +
 +fn replace_with_default() {
 +    let mut s = String::from("foo");
 +    let _ = std::mem::replace(&mut s, String::default());
 +}
 +
 +fn map_unwrap_or() {
 +    let opt = Some(1);
 +
 +    // Check for `option.map(_).unwrap_or(_)` use.
 +    // Single line case.
 +    let _ = opt
 +        .map(|x| x + 1)
 +        // Should lint even though this call is on a separate line.
 +        .unwrap_or(0);
 +}
 +
 +// Could be const
 +fn missing_const_for_fn() -> i32 {
 +    1
 +}
 +
 +fn main() {
 +    filter_map_next();
 +    checked_conversion();
 +    redundant_fieldnames();
 +    redundant_static_lifetime();
 +    option_as_ref_deref();
 +    match_like_matches();
 +    match_same_arms();
 +    match_same_arms2();
 +    manual_strip_msrv();
 +    manual_range_contains();
 +    use_self();
 +    replace_with_default();
 +    map_unwrap_or();
 +    missing_const_for_fn();
 +}
 +
 +mod meets_msrv {
 +    #![feature(custom_inner_attributes)]
 +    #![clippy::msrv = "1.45.0"]
 +
 +    fn main() {
 +        let s = "hello, world!";
 +        if s.starts_with("hello, ") {
 +            assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +        }
 +    }
 +}
 +
 +mod just_under_msrv {
 +    #![feature(custom_inner_attributes)]
 +    #![clippy::msrv = "1.46.0"]
 +
 +    fn main() {
 +        let s = "hello, world!";
 +        if s.starts_with("hello, ") {
 +            assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +        }
 +    }
 +}
 +
 +mod just_above_msrv {
 +    #![feature(custom_inner_attributes)]
 +    #![clippy::msrv = "1.44.0"]
 +
 +    fn main() {
 +        let s = "hello, world!";
 +        if s.starts_with("hello, ") {
 +            assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +        }
 +    }
 +}
index 348052631049b2f8dc9790074c1b0ef5958f34f4,0000000000000000000000000000000000000000..e3e3b335cbe165721ed9ea5260dbe9f71dcd2bb4
mode 100644,000000..100644
--- /dev/null
@@@ -1,37 -1,0 +1,37 @@@
-   --> $DIR/min_rust_version_attr.rs:142:24
 +error: stripping a prefix manually
-   --> $DIR/min_rust_version_attr.rs:141:9
++  --> $DIR/min_rust_version_attr.rs:150:24
 +   |
 +LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +   |                        ^^^^^^^^^^^^^^^^^^^^
 +   |
 +   = note: `-D clippy::manual-strip` implied by `-D warnings`
 +note: the prefix was tested here
-   --> $DIR/min_rust_version_attr.rs:154:24
++  --> $DIR/min_rust_version_attr.rs:149:9
 +   |
 +LL |         if s.starts_with("hello, ") {
 +   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: try using the `strip_prefix` method
 +   |
 +LL |         if let Some(<stripped>) = s.strip_prefix("hello, ") {
 +LL |             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
 +   |
 +
 +error: stripping a prefix manually
-   --> $DIR/min_rust_version_attr.rs:153:9
++  --> $DIR/min_rust_version_attr.rs:162:24
 +   |
 +LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
 +   |                        ^^^^^^^^^^^^^^^^^^^^
 +   |
 +note: the prefix was tested here
++  --> $DIR/min_rust_version_attr.rs:161:9
 +   |
 +LL |         if s.starts_with("hello, ") {
 +   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 +help: try using the `strip_prefix` method
 +   |
 +LL |         if let Some(<stripped>) = s.strip_prefix("hello, ") {
 +LL |             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
 +   |
 +
 +error: aborting due to 2 previous errors
 +
index 541225e635102b73626c4c7e960c7796f2161f8f,0000000000000000000000000000000000000000..06370dfce65188899dda939fb0dbee8e561c7170
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,157 @@@
 +#![allow(unused, clippy::many_single_char_names, clippy::redundant_clone)]
 +#![warn(clippy::ptr_arg)]
 +
 +use std::borrow::Cow;
++use std::path::PathBuf;
 +
 +fn do_vec(x: &Vec<i64>) {
 +    //Nothing here
 +}
 +
 +fn do_vec_mut(x: &mut Vec<i64>) {
 +    // no error here
 +    //Nothing here
 +}
 +
 +fn do_str(x: &String) {
 +    //Nothing here either
 +}
 +
 +fn do_str_mut(x: &mut String) {
 +    // no error here
 +    //Nothing here either
 +}
 +
++fn do_path(x: &PathBuf) {
++    //Nothing here either
++}
++
++fn do_path_mut(x: &mut PathBuf) {
++    // no error here
++    //Nothing here either
++}
++
 +fn main() {}
 +
 +trait Foo {
 +    type Item;
 +    fn do_vec(x: &Vec<i64>);
 +    fn do_item(x: &Self::Item);
 +}
 +
 +struct Bar;
 +
 +// no error, in trait impl (#425)
 +impl Foo for Bar {
 +    type Item = Vec<u8>;
 +    fn do_vec(x: &Vec<i64>) {}
 +    fn do_item(x: &Vec<u8>) {}
 +}
 +
 +fn cloned(x: &Vec<u8>) -> Vec<u8> {
 +    let e = x.clone();
 +    let f = e.clone(); // OK
 +    let g = x;
 +    let h = g.clone(); // Alas, we cannot reliably detect this without following data.
 +    let i = (e).clone();
 +    x.clone()
 +}
 +
 +fn str_cloned(x: &String) -> String {
 +    let a = x.clone();
 +    let b = x.clone();
 +    let c = b.clone();
 +    let d = a.clone().clone().clone();
 +    x.clone()
 +}
 +
++fn path_cloned(x: &PathBuf) -> PathBuf {
++    let a = x.clone();
++    let b = x.clone();
++    let c = b.clone();
++    let d = a.clone().clone().clone();
++    x.clone()
++}
++
 +fn false_positive_capacity(x: &Vec<u8>, y: &String) {
 +    let a = x.capacity();
 +    let b = y.clone();
 +    let c = y.as_str();
 +}
 +
 +fn false_positive_capacity_too(x: &String) -> String {
 +    if x.capacity() > 1024 {
 +        panic!("Too large!");
 +    }
 +    x.clone()
 +}
 +
 +#[allow(dead_code)]
 +fn test_cow_with_ref(c: &Cow<[i32]>) {}
 +
 +fn test_cow(c: Cow<[i32]>) {
 +    let _c = c;
 +}
 +
 +trait Foo2 {
 +    fn do_string(&self);
 +}
 +
 +// no error for &self references where self is of type String (#2293)
 +impl Foo2 for String {
 +    fn do_string(&self) {}
 +}
 +
 +// Check that the allow attribute on parameters is honored
 +mod issue_5644 {
 +    use std::borrow::Cow;
++    use std::path::PathBuf;
 +
 +    fn allowed(
 +        #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
 +        #[allow(clippy::ptr_arg)] _s: &String,
++        #[allow(clippy::ptr_arg)] _p: &PathBuf,
 +        #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
 +    ) {
 +    }
 +
 +    struct S {}
 +    impl S {
 +        fn allowed(
 +            #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
 +            #[allow(clippy::ptr_arg)] _s: &String,
++            #[allow(clippy::ptr_arg)] _p: &PathBuf,
 +            #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
 +        ) {
 +        }
 +    }
 +
 +    trait T {
 +        fn allowed(
 +            #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
 +            #[allow(clippy::ptr_arg)] _s: &String,
++            #[allow(clippy::ptr_arg)] _p: &PathBuf,
 +            #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
 +        ) {
 +        }
 +    }
 +}
++
++mod issue6509 {
++    use std::path::PathBuf;
++
++    fn foo_vec(vec: &Vec<u8>) {
++        let _ = vec.clone().pop();
++        let _ = vec.clone().clone();
++    }
++
++    fn foo_path(path: &PathBuf) {
++        let _ = path.clone().pop();
++        let _ = path.clone().clone();
++    }
++
++    fn foo_str(str: &PathBuf) {
++        let _ = str.clone().pop();
++        let _ = str.clone().clone();
++    }
++}
index 314f23497f9716647785e95e7fcae266156a57c6,0000000000000000000000000000000000000000..708318bbe295c410f4dd20370842f9c2ce95e648
mode 100644,000000..100644
--- /dev/null
@@@ -1,89 -1,0 +1,175 @@@
-   --> $DIR/ptr_arg.rs:6:14
 +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
-   --> $DIR/ptr_arg.rs:15:14
++  --> $DIR/ptr_arg.rs:7:14
 +   |
 +LL | fn do_vec(x: &Vec<i64>) {
 +   |              ^^^^^^^^^ help: change this to: `&[i64]`
 +   |
 +   = note: `-D clippy::ptr-arg` implied by `-D warnings`
 +
 +error: writing `&String` instead of `&str` involves a new object where a slice will do.
-   --> $DIR/ptr_arg.rs:28:18
++  --> $DIR/ptr_arg.rs:16:14
 +   |
 +LL | fn do_str(x: &String) {
 +   |              ^^^^^^^ help: change this to: `&str`
 +
++error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
++  --> $DIR/ptr_arg.rs:25:15
++   |
++LL | fn do_path(x: &PathBuf) {
++   |               ^^^^^^^^ help: change this to: `&Path`
++
 +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
-   --> $DIR/ptr_arg.rs:41:14
++  --> $DIR/ptr_arg.rs:38:18
 +   |
 +LL |     fn do_vec(x: &Vec<i64>);
 +   |                  ^^^^^^^^^ help: change this to: `&[i64]`
 +
 +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
-   --> $DIR/ptr_arg.rs:50:18
++  --> $DIR/ptr_arg.rs:51:14
 +   |
 +LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
 +   |              ^^^^^^^^
 +   |
 +help: change this to
 +   |
 +LL | fn cloned(x: &[u8]) -> Vec<u8> {
 +   |              ^^^^^
 +help: change `x.clone()` to
 +   |
 +LL |     let e = x.to_owned();
 +   |             ^^^^^^^^^^^^
 +help: change `x.clone()` to
 +   |
 +LL |     x.to_owned()
 +   |
 +
 +error: writing `&String` instead of `&str` involves a new object where a slice will do.
-   --> $DIR/ptr_arg.rs:58:44
++  --> $DIR/ptr_arg.rs:60:18
 +   |
 +LL | fn str_cloned(x: &String) -> String {
 +   |                  ^^^^^^^
 +   |
 +help: change this to
 +   |
 +LL | fn str_cloned(x: &str) -> String {
 +   |                  ^^^^
 +help: change `x.clone()` to
 +   |
 +LL |     let a = x.to_string();
 +   |             ^^^^^^^^^^^^^
 +help: change `x.clone()` to
 +   |
 +LL |     let b = x.to_string();
 +   |             ^^^^^^^^^^^^^
 +help: change `x.clone()` to
 +   |
 +LL |     x.to_string()
 +   |
 +
++error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
++  --> $DIR/ptr_arg.rs:68:19
++   |
++LL | fn path_cloned(x: &PathBuf) -> PathBuf {
++   |                   ^^^^^^^^
++   |
++help: change this to
++   |
++LL | fn path_cloned(x: &Path) -> PathBuf {
++   |                   ^^^^^
++help: change `x.clone()` to
++   |
++LL |     let a = x.to_path_buf();
++   |             ^^^^^^^^^^^^^^^
++help: change `x.clone()` to
++   |
++LL |     let b = x.to_path_buf();
++   |             ^^^^^^^^^^^^^^^
++help: change `x.clone()` to
++   |
++LL |     x.to_path_buf()
++   |
++
 +error: writing `&String` instead of `&str` involves a new object where a slice will do.
-   --> $DIR/ptr_arg.rs:72:25
++  --> $DIR/ptr_arg.rs:76:44
 +   |
 +LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
 +   |                                            ^^^^^^^
 +   |
 +help: change this to
 +   |
 +LL | fn false_positive_capacity(x: &Vec<u8>, y: &str) {
 +   |                                            ^^^^
 +help: change `y.clone()` to
 +   |
 +LL |     let b = y.to_string();
 +   |             ^^^^^^^^^^^^^
 +help: change `y.as_str()` to
 +   |
 +LL |     let c = y;
 +   |             ^
 +
 +error: using a reference to `Cow` is not recommended.
- error: aborting due to 7 previous errors
++  --> $DIR/ptr_arg.rs:90:25
 +   |
 +LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
 +   |                         ^^^^^^^^^^^ help: change this to: `&[i32]`
 +
++error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
++  --> $DIR/ptr_arg.rs:143:21
++   |
++LL |     fn foo_vec(vec: &Vec<u8>) {
++   |                     ^^^^^^^^
++   |
++help: change this to
++   |
++LL |     fn foo_vec(vec: &[u8]) {
++   |                     ^^^^^
++help: change `vec.clone()` to
++   |
++LL |         let _ = vec.to_owned().pop();
++   |                 ^^^^^^^^^^^^^^
++help: change `vec.clone()` to
++   |
++LL |         let _ = vec.to_owned().clone();
++   |                 ^^^^^^^^^^^^^^
++
++error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
++  --> $DIR/ptr_arg.rs:148:23
++   |
++LL |     fn foo_path(path: &PathBuf) {
++   |                       ^^^^^^^^
++   |
++help: change this to
++   |
++LL |     fn foo_path(path: &Path) {
++   |                       ^^^^^
++help: change `path.clone()` to
++   |
++LL |         let _ = path.to_path_buf().pop();
++   |                 ^^^^^^^^^^^^^^^^^^
++help: change `path.clone()` to
++   |
++LL |         let _ = path.to_path_buf().clone();
++   |                 ^^^^^^^^^^^^^^^^^^
++
++error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.
++  --> $DIR/ptr_arg.rs:153:21
++   |
++LL |     fn foo_str(str: &PathBuf) {
++   |                     ^^^^^^^^
++   |
++help: change this to
++   |
++LL |     fn foo_str(str: &Path) {
++   |                     ^^^^^
++help: change `str.clone()` to
++   |
++LL |         let _ = str.to_path_buf().pop();
++   |                 ^^^^^^^^^^^^^^^^^
++help: change `str.clone()` to
++   |
++LL |         let _ = str.to_path_buf().clone();
++   |                 ^^^^^^^^^^^^^^^^^
++
++error: aborting due to 12 previous errors
 +
index 7afc5361356333235224a79b64710f13cd76e5cd,0000000000000000000000000000000000000000..a192ebde3ebf4e73047dde8152c6dee234cf6bfc
mode 100644,000000..100644
--- /dev/null
@@@ -1,81 -1,0 +1,82 @@@
 +// run-rustfix
 +
 +// The output for humans should just highlight the whole span without showing
 +// the suggested replacement, but we also want to test that suggested
 +// replacement only removes one set of parentheses, rather than naïvely
 +// stripping away any starting or ending parenthesis characters—hence this
 +// test of the JSON error format.
 +
 +#![feature(custom_inner_attributes)]
 +#![rustfmt::skip]
 +
 +#![deny(clippy::unused_unit)]
 +#![allow(dead_code)]
++#![allow(clippy::from_over_into)]
 +
 +struct Unitter;
 +impl Unitter {
 +    #[allow(clippy::no_effect)]
 +    pub fn get_unit<F: Fn(), G>(&self, f: F, _g: G)
 +    where G: Fn() {
 +        let _y: &dyn Fn() = &f;
 +        (); // this should not lint, as it's not in return type position
 +    }
 +}
 +
 +impl Into<()> for Unitter {
 +    #[rustfmt::skip]
 +    fn into(self) {
 +        
 +    }
 +}
 +
 +trait Trait {
 +    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)
 +    where
 +        G: FnMut(),
 +        H: Fn();
 +}
 +
 +impl Trait for Unitter {
 +    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)
 +    where
 +        G: FnMut(),
 +        H: Fn() {}
 +}
 +
 +fn return_unit() {  }
 +
 +#[allow(clippy::needless_return)]
 +#[allow(clippy::never_loop)]
 +#[allow(clippy::unit_cmp)]
 +fn main() {
 +    let u = Unitter;
 +    assert_eq!(u.get_unit(|| {}, return_unit), u.into());
 +    return_unit();
 +    loop {
 +        break;
 +    }
 +    return;
 +}
 +
 +// https://github.com/rust-lang/rust-clippy/issues/4076
 +fn foo() {
 +    macro_rules! foo {
 +        (recv($r:expr) -> $res:pat => $body:expr) => {
 +            $body
 +        }
 +    }
 +
 +    foo! {
 +        recv(rx) -> _x => ()
 +    }
 +}
 +
 +#[rustfmt::skip]
 +fn test(){}
 +
 +#[rustfmt::skip]
 +fn test2(){}
 +
 +#[rustfmt::skip]
 +fn test3(){}
index 96cef1ed5a5f213dddad7bb987fa034b39ec3f6b,0000000000000000000000000000000000000000..96041a7dd850e3807504697a84b87026447a5955
mode 100644,000000..100644
--- /dev/null
@@@ -1,81 -1,0 +1,82 @@@
 +// run-rustfix
 +
 +// The output for humans should just highlight the whole span without showing
 +// the suggested replacement, but we also want to test that suggested
 +// replacement only removes one set of parentheses, rather than naïvely
 +// stripping away any starting or ending parenthesis characters—hence this
 +// test of the JSON error format.
 +
 +#![feature(custom_inner_attributes)]
 +#![rustfmt::skip]
 +
 +#![deny(clippy::unused_unit)]
 +#![allow(dead_code)]
++#![allow(clippy::from_over_into)]
 +
 +struct Unitter;
 +impl Unitter {
 +    #[allow(clippy::no_effect)]
 +    pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
 +    where G: Fn() -> () {
 +        let _y: &dyn Fn() -> () = &f;
 +        (); // this should not lint, as it's not in return type position
 +    }
 +}
 +
 +impl Into<()> for Unitter {
 +    #[rustfmt::skip]
 +    fn into(self) -> () {
 +        ()
 +    }
 +}
 +
 +trait Trait {
 +    fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
 +    where
 +        G: FnMut() -> (),
 +        H: Fn() -> ();
 +}
 +
 +impl Trait for Unitter {
 +    fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
 +    where
 +        G: FnMut() -> (),
 +        H: Fn() -> () {}
 +}
 +
 +fn return_unit() -> () { () }
 +
 +#[allow(clippy::needless_return)]
 +#[allow(clippy::never_loop)]
 +#[allow(clippy::unit_cmp)]
 +fn main() {
 +    let u = Unitter;
 +    assert_eq!(u.get_unit(|| {}, return_unit), u.into());
 +    return_unit();
 +    loop {
 +        break();
 +    }
 +    return();
 +}
 +
 +// https://github.com/rust-lang/rust-clippy/issues/4076
 +fn foo() {
 +    macro_rules! foo {
 +        (recv($r:expr) -> $res:pat => $body:expr) => {
 +            $body
 +        }
 +    }
 +
 +    foo! {
 +        recv(rx) -> _x => ()
 +    }
 +}
 +
 +#[rustfmt::skip]
 +fn test()->(){}
 +
 +#[rustfmt::skip]
 +fn test2() ->(){}
 +
 +#[rustfmt::skip]
 +fn test3()-> (){}
index c45634c2b6df71a5131c4c7f8689e5a0edbf7607,0000000000000000000000000000000000000000..02038b5fb6b5a7ed56ce688bdf1e01834d0a68c6
mode 100644,000000..100644
--- /dev/null
@@@ -1,122 -1,0 +1,122 @@@
-   --> $DIR/unused_unit.rs:18:28
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:19:18
++  --> $DIR/unused_unit.rs:19:28
 +   |
 +LL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
 +   |                            ^^^^^^ help: remove the `-> ()`
 +   |
 +note: the lint level is defined here
 +  --> $DIR/unused_unit.rs:12:9
 +   |
 +LL | #![deny(clippy::unused_unit)]
 +   |         ^^^^^^^^^^^^^^^^^^^
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:18:58
++  --> $DIR/unused_unit.rs:20:18
 +   |
 +LL |     where G: Fn() -> () {
 +   |                  ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:20:26
++  --> $DIR/unused_unit.rs:19:58
 +   |
 +LL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
 +   |                                                          ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:27:18
++  --> $DIR/unused_unit.rs:21:26
 +   |
 +LL |         let _y: &dyn Fn() -> () = &f;
 +   |                          ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:28:9
++  --> $DIR/unused_unit.rs:28:18
 +   |
 +LL |     fn into(self) -> () {
 +   |                  ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit expression
-   --> $DIR/unused_unit.rs:33:29
++  --> $DIR/unused_unit.rs:29:9
 +   |
 +LL |         ()
 +   |         ^^ help: remove the final `()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:35:19
++  --> $DIR/unused_unit.rs:34:29
 +   |
 +LL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
 +   |                             ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:36:16
++  --> $DIR/unused_unit.rs:36:19
 +   |
 +LL |         G: FnMut() -> (),
 +   |                   ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:40:29
++  --> $DIR/unused_unit.rs:37:16
 +   |
 +LL |         H: Fn() -> ();
 +   |                ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:42:19
++  --> $DIR/unused_unit.rs:41:29
 +   |
 +LL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
 +   |                             ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:43:16
++  --> $DIR/unused_unit.rs:43:19
 +   |
 +LL |         G: FnMut() -> (),
 +   |                   ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:46:17
++  --> $DIR/unused_unit.rs:44:16
 +   |
 +LL |         H: Fn() -> () {}
 +   |                ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:46:26
++  --> $DIR/unused_unit.rs:47:17
 +   |
 +LL | fn return_unit() -> () { () }
 +   |                 ^^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit expression
-   --> $DIR/unused_unit.rs:56:14
++  --> $DIR/unused_unit.rs:47:26
 +   |
 +LL | fn return_unit() -> () { () }
 +   |                          ^^ help: remove the final `()`
 +
 +error: unneeded `()`
-   --> $DIR/unused_unit.rs:58:11
++  --> $DIR/unused_unit.rs:57:14
 +   |
 +LL |         break();
 +   |              ^^ help: remove the `()`
 +
 +error: unneeded `()`
-   --> $DIR/unused_unit.rs:75:10
++  --> $DIR/unused_unit.rs:59:11
 +   |
 +LL |     return();
 +   |           ^^ help: remove the `()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:78:11
++  --> $DIR/unused_unit.rs:76:10
 +   |
 +LL | fn test()->(){}
 +   |          ^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
-   --> $DIR/unused_unit.rs:81:11
++  --> $DIR/unused_unit.rs:79:11
 +   |
 +LL | fn test2() ->(){}
 +   |           ^^^^^ help: remove the `-> ()`
 +
 +error: unneeded unit return type
++  --> $DIR/unused_unit.rs:82:11
 +   |
 +LL | fn test3()-> (){}
 +   |           ^^^^^ help: remove the `-> ()`
 +
 +error: aborting due to 19 previous errors
 +
index f5d03c645df0435b7876033306ef910f0237afcc,0000000000000000000000000000000000000000..589b19f68f7a05bb485b1a700e3a0c2ddc0c50dd
mode 100644,000000..100644
--- /dev/null
@@@ -1,19 -1,0 +1,72 @@@
++#![allow(clippy::single_match_else)]
++use rustc_tools_util::VersionInfo;
++
 +#[test]
 +fn check_that_clippy_lints_has_the_same_version_as_clippy() {
 +    let clippy_meta = cargo_metadata::MetadataCommand::new()
 +        .no_deps()
 +        .exec()
 +        .expect("could not obtain cargo metadata");
 +    std::env::set_current_dir(std::env::current_dir().unwrap().join("clippy_lints")).unwrap();
 +    let clippy_lints_meta = cargo_metadata::MetadataCommand::new()
 +        .no_deps()
 +        .exec()
 +        .expect("could not obtain cargo metadata");
 +    assert_eq!(clippy_lints_meta.packages[0].version, clippy_meta.packages[0].version);
 +    for package in &clippy_meta.packages[0].dependencies {
 +        if package.name == "clippy_lints" {
 +            assert!(package.req.matches(&clippy_lints_meta.packages[0].version));
 +            return;
 +        }
 +    }
 +}
++
++#[test]
++fn check_that_clippy_has_the_same_major_version_as_rustc() {
++    let clippy_version = rustc_tools_util::get_version_info!();
++    let clippy_major = clippy_version.major;
++    let clippy_minor = clippy_version.minor;
++    let clippy_patch = clippy_version.patch;
++
++    // get the rustc version
++    // this way the rust-toolchain file version is honored
++    let rustc_version = String::from_utf8(
++        std::process::Command::new("rustc")
++            .arg("--version")
++            .output()
++            .expect("failed to run `rustc --version`")
++            .stdout,
++    )
++    .unwrap();
++    // extract "1 XX 0" from "rustc 1.XX.0-nightly (<commit> <date>)"
++    let vsplit: Vec<&str> = rustc_version
++        .split(' ')
++        .nth(1)
++        .unwrap()
++        .split('-')
++        .next()
++        .unwrap()
++        .split('.')
++        .collect();
++    match vsplit.as_slice() {
++        [rustc_major, rustc_minor, _rustc_patch] => {
++            // clippy 0.1.XX should correspond to rustc 1.XX.0
++            assert_eq!(clippy_major, 0); // this will probably stay the same for a long time
++            assert_eq!(
++                clippy_minor.to_string(),
++                *rustc_major,
++                "clippy minor version does not equal rustc major version"
++            );
++            assert_eq!(
++                clippy_patch.to_string(),
++                *rustc_minor,
++                "clippy patch version does not equal rustc minor version"
++            );
++            // do not check rustc_patch because when a stable-patch-release is made (like 1.50.2),
++            // we don't want our tests failing suddenly
++        },
++        _ => {
++            panic!("Failed to parse rustc version: {:?}", vsplit);
++        },
++    };
++}
index 428708136cb650df91b01ba72d1553ce68cf6572,0000000000000000000000000000000000000000..1852fb6640ecc9093ce712ecf1e8d4f8b159011a
mode 100644,000000..100644
--- /dev/null
@@@ -1,317 -1,0 +1,325 @@@
-                             <input type="text" class="form-control" placeholder="Keywords or search string" id="filter-input" ng-model="search" />
 +<!DOCTYPE html>
 +<html lang="en">
 +<head>
 +    <meta charset="UTF-8"/>
 +    <meta name="viewport" content="width=device-width, initial-scale=1"/>
 +
 +    <title>ALL the Clippy Lints</title>
 +
 +    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/>
 +    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.5.0/styles/github.min.css"/>
 +    <style>
 +        blockquote { font-size: 1em; }
 +        [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
 +
 +        .form-inline .checkbox { margin-right: 0.6em }
 +
 +        .panel-heading { cursor: pointer; }
 +        .panel-heading:hover { background-color: #eee; }
 +
 +        .panel-title { display: flex; }
 +        .panel-title .label { display: inline-block; }
 +
 +        .panel-title-name { flex: 1; }
 +        .panel-title-name span { vertical-align: bottom; }
 +
 +        .panel .panel-title-name .anchor { display: none; }
 +        .panel:hover .panel-title-name .anchor { display: inline; color: #fff; }
 +    </style>
 +</head>
 +<body>
 +    <div class="container" ng-app="clippy" ng-controller="lintList">
 +        <div class="page-header">
 +            <h1>ALL the Clippy Lints</h1>
 +        </div>
 +
 +        <noscript>
 +            <div class="alert alert-danger" role="alert">
 +                Sorry, this site only works with JavaScript! :(
 +            </div>
 +        </noscript>
 +
 +        <div ng-cloak>
 +
 +            <div class="alert alert-info" role="alert" ng-if="loading">
 +                Loading&#x2026;
 +            </div>
 +            <div class="alert alert-danger" role="alert" ng-if="error">
 +                Error loading lints!
 +            </div>
 +
 +            <div class="panel panel-default" ng-show="data">
 +                <div class="panel-body row">
 +                    <div class="col-md-6 form-inline">
 +                        <div class="form-group form-group-lg">
 +                            <p class="h4">Lint levels</p>
 +                            <div class="checkbox" ng-repeat="(level, enabled) in levels">
 +                                <label>
 +                                    <input type="checkbox" ng-model="levels[level]" />
 +                                    {{level}}
 +                                </label>
 +                            </div>
 +                        </div>
 +                    </div>
 +                    <div class="col-md-6 form-inline">
 +                        <div class="form-group form-group-lg">
 +                            <p class="h4">Lint groups</p>
 +                            <div class="checkbox" ng-repeat="(group, enabled) in groups">
 +                                <label class="text-capitalize">
 +                                    <input type="checkbox" ng-model="groups[group]" />
 +                                    {{group}}
 +                                </label>
 +                            </div>
 +                        </div>
 +                    </div>
 +                </div>
 +                <div class="panel-body row">
 +                    <div class="col-md-12 form-horizontal">
 +                        <div class="input-group">
 +                            <label class="input-group-addon" id="filter-label" for="filter-input">Filter:</label>
-                 let search_str = $scope.search;
++                            <input type="text" class="form-control" placeholder="Keywords or search string" id="filter-input" ng-model="search" ng-model-options="{debounce: 50}"/>
 +                            <span class="input-group-btn">
 +                                <button class="btn btn-default" type="button" ng-click="search = ''">
 +                                    Clear
 +                                </button>
 +                            </span>
 +                        </div>
 +                    </div>
 +                </div>
 +            </div>
 +
 +            <article class="panel panel-default" id="{{lint.id}}"
 +                ng-repeat="lint in data | filter:byLevels | filter:byGroups | filter:bySearch | orderBy:'id' track by lint.id">
 +                <header class="panel-heading" ng-click="open[lint.id] = !open[lint.id]">
 +                    <h2 class="panel-title">
 +                        <div class="panel-title-name">
 +                            <span>{{lint.id}}</span>
 +                            <a href="#{{lint.id}}" class="anchor label label-default" ng-click="open[lint.id] = true; $event.stopPropagation()">&para;</a>
 +                        </div>
 +
 +                        <div class="panel-title-addons">
 +                            <span class="label label-default text-capitalize">{{lint.group}}</span>
 +
 +                            <span ng-if="lint.level == 'Allow'" class="label label-success">Allow</span>
 +                            <span ng-if="lint.level == 'Warn'" class="label label-warning">Warn</span>
 +                            <span ng-if="lint.level == 'Deny'" class="label label-danger">Deny</span>
 +                            <span ng-if="lint.level == 'Deprecated'" class="label label-default">Deprecated</span>
 +
 +                            <button class="btn btn-default btn-xs">
 +                                <span ng-show="open[lint.id]">&minus;</span>
 +                                <span ng-hide="open[lint.id]">&plus;</span>
 +                            </button>
 +                        </div>
 +                    </h2>
 +                </header>
 +
 +                <ul class="list-group lint-docs" ng-if="lint.docs" ng-class="{collapse: true, in: open[lint.id]}">
 +                    <li class="list-group-item" ng-repeat="(title, text) in lint.docs">
 +                        <h4 class="list-group-item-heading">
 +                            {{title}}
 +                        </h4>
 +                        <div class="list-group-item-text" ng-bind-html="text | markdown"></div>
++                        <a ng-if="title == 'Known problems'" href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+{{lint.id}}">Search on GitHub</a>
 +                    </li>
 +                </ul>
 +            </article>
 +        </div>
 +    </div>
 +
 +    <a href="https://github.com/rust-lang/rust-clippy">
 +        <img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on Github"/>
 +    </a>
 +
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/7.0.0/markdown-it.min.js"></script>
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.5.0/highlight.min.js"></script>
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.5.0/languages/rust.min.js"></script>
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script>
 +    <script>
 +    (function () {
 +        var md = window.markdownit({
 +            html: true,
 +            linkify: true,
 +            typographer: true,
 +            highlight: function (str, lang) {
 +                if (lang && hljs.getLanguage(lang)) {
 +                    try {
 +                        return '<pre class="hljs"><code>' +
 +                            hljs.highlight(lang, str, true).value +
 +                            '</code></pre>';
 +                    } catch (__) {}
 +                }
 +
 +                return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
 +            }
 +        });
 +
 +        function scrollToLint(lintId) {
 +            var target = document.getElementById(lintId);
 +            if (!target) {
 +                return;
 +            }
 +            target.scrollIntoView();
 +        }
 +
 +        function scrollToLintByURL($scope) {
 +            var removeListener = $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
 +                scrollToLint(window.location.hash.slice(1));
 +                removeListener();
 +            });
 +        }
 +
 +        function selectGroup($scope, selectedGroup) {
 +            var groups = $scope.groups;
 +            for (var group in groups) {
 +                if (groups.hasOwnProperty(group)) {
 +                    if (group === selectedGroup) {
 +                        groups[group] = true;
 +                    } else {
 +                        groups[group] = false;
 +                    }
 +                }
 +            }
 +        }
 +
++        function searchLint(lint, term) {
++            for (const field in lint.docs) {
++                // Continue if it's not a property
++                if (!lint.docs.hasOwnProperty(field)) {
++                    continue;
++                }
++
++                // Return if not found
++                if (lint.docs[field].toLowerCase().indexOf(term) !== -1) {
++                    return true;
++                }
++            }
++
++            return false;
++        }
++
 +        angular.module("clippy", [])
 +        .filter('markdown', function ($sce) {
 +            return function (text) {
 +                return $sce.trustAsHtml(
 +                    md.render(text || '')
 +                    // Oh deer, what a hack :O
 +                    .replace('<table', '<table class="table"')
 +                );
 +            };
 +        })
 +        .directive('onFinishRender', function ($timeout) {
 +            return {
 +                restrict: 'A',
 +                link: function (scope, element, attr) {
 +                    if (scope.$last === true) {
 +                        $timeout(function () {
 +                            scope.$emit(attr.onFinishRender);
 +                        });
 +                    }
 +                }
 +            };
 +        })
 +        .controller("lintList", function ($scope, $http, $timeout) {
 +            // Level filter
 +            var LEVEL_FILTERS_DEFAULT = {Allow: true, Warn: true, Deny: true, Deprecated: true};
 +            $scope.levels = LEVEL_FILTERS_DEFAULT;
 +            $scope.byLevels = function (lint) {
 +                return $scope.levels[lint.level];
 +            };
 +
 +            $scope.groups = {};
 +            $scope.byGroups = function (lint) {
 +                return $scope.groups[lint.group];
 +            };
 +
 +            $scope.bySearch = function (lint, index, array) {
-                 if (search_str == null || search_str.length == 0) {
++                let searchStr = $scope.search;
 +                // It can be `null` I haven't missed this value 
-                 search_str = search_str.toLowerCase();
++                if (searchStr == null || searchStr.length < 3) {
 +                    return true;
 +                }
-                 let id_search = search_str.trim().replace(/(\-| )/g, "_");
-                 if (lint.id.includes(id_search)) {
++                searchStr = searchStr.toLowerCase();
 +
 +                // Search by id
-                 let search_lint = (lint, therm) => {
-                     for (const field in lint.docs) {
-                         // Continue if it's not a property
-                         if (!lint.docs.hasOwnProperty(field)) {
-                             continue;
-                         }
-                         // Return if not found
-                         if (lint.docs[field].toLowerCase().includes(therm)) {
-                             return true;
-                         }
++                if (lint.id.indexOf(searchStr.replace("-", "_")) !== -1) {
 +                    return true;
 +                }
 +
 +                // Search the description
 +                // The use of `for`-loops instead of `foreach` enables us to return early 
-                     return false;
-                 };
-                 let therms = search_str.split(" ");
-                 for (index = 0; index < therms.length; index++) {
-                     if (!search_lint(lint, therms[index])) {
-                         return false;
++                let terms = searchStr.split(" ");
++                for (index = 0; index < terms.length; index++) {
++                    if (lint.id.indexOf(terms[index]) !== -1) {
++                        continue;
 +                    }
++
++                    if (searchLint(lint, terms[index])) {
++                        continue;
 +                    }
++
++                    return false;
 +                }
 +
 +                return true;
 +            }
 +
 +            // Get data
 +            $scope.open = {};
 +            $scope.loading = true;
 +
 +            if (window.location.hash.length > 1) {
 +                $scope.search = window.location.hash.slice(1);
 +                $scope.open[window.location.hash.slice(1)] = true;
 +                scrollToLintByURL($scope);
 +            }
 +
 +            $http.get('./lints.json')
 +            .success(function (data) {
 +                $scope.data = data;
 +                $scope.loading = false;
 +
 +                // Initialize lint groups (the same structure is also used to enable filtering)
 +                $scope.groups = data.reduce(function (result, val) {
 +                    result[val.group] = true;
 +                    return result;
 +                }, {});
 +
 +                var selectedGroup = getQueryVariable("sel");
 +                if (selectedGroup) {
 +                    selectGroup($scope, selectedGroup.toLowerCase());
 +                }
 +
 +                scrollToLintByURL($scope);
 +            })
 +            .error(function (data) {
 +                $scope.error = data;
 +                $scope.loading = false;
 +            });
 +
 +            window.addEventListener('hashchange', function () {
 +                // trigger re-render
 +                $timeout(function () {
 +                    $scope.levels = LEVEL_FILTERS_DEFAULT;
 +                    $scope.search = window.location.hash.slice(1);
 +                    $scope.open[window.location.hash.slice(1)] = true;
 +
 +                    scrollToLintByURL($scope);
 +                });
 +                return true;
 +            }, false);
 +        });
 +    })();
 +
 +    function getQueryVariable(variable) {
 +        var query = window.location.search.substring(1);
 +        var vars = query.split('&');
 +        for (var i = 0; i < vars.length; i++) {
 +            var pair = vars[i].split('=');
 +            if (decodeURIComponent(pair[0]) == variable) {
 +                return decodeURIComponent(pair[1]);
 +            }
 +        }
 +    }
 +    </script>
 +</body>
 +</html>