Merge commit 'd9c24d1b1ee61f276e550b967409c9f155eac4e3' into clippyup

This commit is contained in:
Philipp Krones 2023-07-17 10:19:29 +02:00
parent fdb2e363d3
commit d6d530fd0b
516 changed files with 5266 additions and 2562 deletions

View File

@ -50,7 +50,7 @@ jobs:
echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
- name: Build
run: cargo build --features deny-warnings,internal
run: cargo build --tests --features deny-warnings,internal
- name: Test
run: cargo test --features deny-warnings,internal

View File

@ -106,7 +106,7 @@ jobs:
echo "$SYSROOT/bin" >> $GITHUB_PATH
- name: Build
run: cargo build --features deny-warnings,internal
run: cargo build --tests --features deny-warnings,internal
- name: Test
if: runner.os == 'Linux'

View File

@ -6,13 +6,74 @@ document.
## Unreleased / Beta / In Rust Nightly
[83e42a23...master](https://github.com/rust-lang/rust-clippy/compare/83e42a23...master)
[435a8ad8...master](https://github.com/rust-lang/rust-clippy/compare/435a8ad8...master)
## Rust 1.71
Current stable, released 2023-07-13
<!-- FIXME: Remove the request for feedback, with the next changelog -->
We're trying out a new shorter changelog format, that only contains significant changes.
You can check out the list of merged pull requests for a list of all changes.
If you have any feedback related to the new format, please share it in
[#10847](https://github.com/rust-lang/rust-clippy/issues/10847)
[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-04-11T20%3A05%3A26Z..2023-05-20T13%3A48%3A17Z+base%3Amaster)
### New Lints
* [`non_minimal_cfg`]
[#10763](https://github.com/rust-lang/rust-clippy/pull/10763)
* [`manual_next_back`]
[#10769](https://github.com/rust-lang/rust-clippy/pull/10769)
* [`ref_patterns`]
[#10736](https://github.com/rust-lang/rust-clippy/pull/10736)
* [`default_constructed_unit_structs`]
[#10716](https://github.com/rust-lang/rust-clippy/pull/10716)
* [`manual_while_let_some`]
[#10647](https://github.com/rust-lang/rust-clippy/pull/10647)
* [`needless_bool_assign`]
[#10432](https://github.com/rust-lang/rust-clippy/pull/10432)
* [`items_after_test_module`]
[#10578](https://github.com/rust-lang/rust-clippy/pull/10578)
### Moves and Deprecations
* Rename `integer_arithmetic` to `arithmetic_side_effects`
[#10674](https://github.com/rust-lang/rust-clippy/pull/10674)
* Moved [`redundant_clone`] to `nursery` (Now allow-by-default)
[#10873](https://github.com/rust-lang/rust-clippy/pull/10873)
### Enhancements
* [`invalid_regex`]: Now supports the new syntax introduced after regex v1.8.0
[#10682](https://github.com/rust-lang/rust-clippy/pull/10682)
* [`semicolon_outside_block`]: Added [`semicolon-outside-block-ignore-multiline`] as a new config value.
[#10656](https://github.com/rust-lang/rust-clippy/pull/10656)
* [`semicolon_inside_block`]: Added [`semicolon-inside-block-ignore-singleline`] as a new config value.
[#10656](https://github.com/rust-lang/rust-clippy/pull/10656)
* [`unnecessary_box_returns`]: Added [`unnecessary-box-size`] as a new config value to set the maximum
size of `T` in `Box<T>` to be linted.
[#10651](https://github.com/rust-lang/rust-clippy/pull/10651)
### Documentation Improvements
* `cargo clippy --explain LINT` now shows possible configuration options for the explained lint
[#10751](https://github.com/rust-lang/rust-clippy/pull/10751)
* New config values mentioned in this changelog will now be linked.
[#10889](https://github.com/rust-lang/rust-clippy/pull/10889)
* Several sections of [Clippy's book] have been reworked
[#10652](https://github.com/rust-lang/rust-clippy/pull/10652)
[#10622](https://github.com/rust-lang/rust-clippy/pull/10622)
[Clippy's book]: https://doc.rust-lang.org/clippy/
## Rust 1.70
Current stable, released 2023-06-01
Released 2023-06-01
[**View 85 PRs merged since 1.69**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-04-20..2023-06-01+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-02-26T01%3A05%3A43Z..2023-04-11T13%3A27%3A30Z+base%3Amaster)
### New Lints
@ -137,7 +198,7 @@ Current stable, released 2023-06-01
Released 2023-04-20
[**View 86 PRs merged since 1.68**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-03-09..2023-04-20+base%3Amaster+sort%3Amerged-desc+)
[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-01-13T06%3A12%3A46Z..2023-02-25T23%3A48%3A10Z+base%3Amaster)
### New Lints
@ -252,7 +313,7 @@ Released 2023-04-20
Released 2023-03-09
[**View 85 PRs merged since 1.67**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-01-26..2023-03-09+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-12-01T20%3A40%3A04Z..2023-01-12T18%3A58%3A59Z+base%3Amaster)
### New Lints
@ -399,7 +460,7 @@ Released 2023-03-09
Released 2023-01-26
[**View 68 PRs merged since 1.66**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-12-15..2023-01-26+base%3Amaster+sort%3Amerged-desc+)
[View all 104 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-10-23T13%3A35%3A19Z..2022-12-01T13%3A34%3A39Z+base%3Amaster)
### New Lints
@ -590,8 +651,7 @@ Released 2023-01-26
Released 2022-12-15
[**View 93 PRs merged since 1.65**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-11-03..2022-12-15+base%3Amaster+sort%3Amerged-desc+)
[View all 116 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-09-09T17%3A32%3A39Z..2022-10-23T11%3A27%3A24Z+base%3Amaster)
### New Lints
@ -762,8 +822,7 @@ Released 2022-12-15
Released 2022-11-03
[**View 129 PRs merged since 1.64**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-09-22..2022-11-03+base%3Amaster+sort%3Amerged-desc+)
[View all 86 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-07-29T01%3A09%3A31Z..2022-09-09T00%3A01%3A54Z+base%3Amaster)
### Important Changes
@ -907,8 +966,7 @@ Released 2022-11-03
Released 2022-09-22
[**View 92 PRs merged since 1.63**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-08-11..2022-09-22+base%3Amaster+sort%3Amerged-desc+)
[View all 110 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-06-17T21%3A25%3A31Z..2022-07-28T17%3A11%3A18Z+base%3Amaster)
### New Lints
@ -1058,8 +1116,7 @@ Released 2022-09-22
Released 2022-08-11
[**View 100 PRs merged since 1.62**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-06-30..2022-08-11+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-05-05T17%3A24%3A22Z..2022-06-16T14%3A24%3A48Z+base%3Amaster)
### New Lints
@ -1205,8 +1262,7 @@ Released 2022-08-11
Released 2022-06-30
[**View 104 PRs merged since 1.61**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-05-19..2022-06-30+base%3Amaster+sort%3Amerged-desc+)
[View all 90 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-03-25T17%3A22%3A30Z..2022-05-05T13%3A29%3A44Z+base%3Amaster)
### New Lints
@ -1363,8 +1419,7 @@ Released 2022-06-30
Released 2022-05-19
[**View 93 PRs merged since 1.60**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-04-07..2022-05-19+base%3Amaster+sort%3Amerged-desc+)
[View all 60 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-02-11T16%3A54%3A41Z..2022-03-24T13%3A42%3A25Z+base%3Amaster)
### New Lints
@ -1465,8 +1520,7 @@ Released 2022-05-19
Released 2022-04-07
[**View 75 PRs merged since 1.59**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-02-24..2022-04-07+base%3Amaster+sort%3Amerged-desc+)
[View all 73 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-12-31T17%3A53%3A37Z..2022-02-10T17%3A31%3A37Z+base%3Amaster)
### New Lints
@ -1598,8 +1652,7 @@ Released 2022-04-07
Released 2022-02-24
[**View 63 PRs merged since 1.58**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2022-01-13..2022-02-24+base%3Amaster+sort%3Amerged-desc+)
[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-11-04T12%3A40%3A18Z..2021-12-30T13%3A36%3A20Z+base%3Amaster)
### New Lints
@ -1763,8 +1816,7 @@ Released 2022-02-24
Released 2022-01-13
[**View 73 PRs merged since 1.57**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-12-02..2022-01-13+base%3Amaster+sort%3Amerged-desc+)
[View all 68 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-10-07T09%3A49%3A18Z..2021-11-04T12%3A20%3A12Z+base%3Amaster)
### Rust 1.58.1
@ -1885,8 +1937,7 @@ Released 2022-01-13
Released 2021-12-02
[**View 92 PRs merged since 1.56**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-10-21..2021-12-02+base%3Amaster+sort%3Amerged-desc+)
[View all 148 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-08-12T20%3A36%3A04Z..2021-11-03T17%3A57%3A59Z+base%3Amaster)
### New Lints
@ -2037,7 +2088,7 @@ Released 2021-12-02
Released 2021-10-21
[**View 92 PRs merged since 1.55**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-09-09..2021-10-21+base%3Amaster+sort%3Amerged-desc+)
[View all 38 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-07-19T14%3A33%3A33Z..2021-08-12T09%3A28%3A38Z+base%3Amaster)
### New Lints
@ -2103,7 +2154,7 @@ Released 2021-10-21
Released 2021-09-09
[**View 61 PRs merged since 1.54**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-07-29..2021-09-09+base%3Amaster+sort%3Amerged-desc+)
[View all 83 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-06-03T07%3A23%3A59Z..2021-07-29T11%3A47%3A32Z+base%3Amaster)
### Important Changes
@ -2221,8 +2272,7 @@ Released 2021-09-09
Released 2021-07-29
[**View 68 PRs merged since 1.53**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-06-17..2021-07-29+base%3Amaster+sort%3Amerged-desc+)
[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-04-27T23%3A51%3A18Z..2021-06-03T06%3A54%3A07Z+base%3Amaster)
### New Lints
@ -2350,7 +2400,7 @@ Released 2021-07-29
Released 2021-06-17
[**View 80 PRs merged since 1.52**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-05-06..2021-06-17+base%3Amaster+sort%3Amerged-desc+)
[View all 126 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-03-12T22%3A49%3A20Z..2021-04-27T14%3A38%3A20Z+base%3Amaster)
### New Lints
@ -2534,8 +2584,7 @@ Released 2021-06-17
Released 2021-05-06
[**View 113 PRs merged since 1.51**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-03-25..2021-05-06+base%3Amaster+sort%3Amerged-desc+)
[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-02-03T15%3A59%3A06Z..2021-03-11T20%3A06%3A43Z+base%3Amaster)
### New Lints
@ -2670,8 +2719,7 @@ Released 2021-05-06
Released 2021-03-25
[**View 117 PRs merged since 1.50**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2021-02-11..2021-03-25+base%3Amaster+sort%3Amerged-desc+)
[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-12-21T15%3A43%3A04Z..2021-02-03T04%3A21%3A10Z+base%3Amaster)
### New Lints
@ -2786,8 +2834,7 @@ Released 2021-03-25
Released 2021-02-11
[**View 90 PRs merged since 1.49**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-12-31..2021-02-11+base%3Amaster+sort%3Amerged-desc+)
[View all 119 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-11-06T18%3A32%3A40Z..2021-01-03T14%3A51%3A18Z+base%3Amaster)
### New Lints
@ -2916,8 +2963,7 @@ Released 2021-02-11
Released 2020-12-31
[**View 85 PRs merged since 1.48**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-11-19..2020-12-31+base%3Amaster+sort%3Amerged-desc+)
[View all 107 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-09-24T14%3A05%3A12Z..2020-11-05T13%3A35%3A44Z+base%3Amaster)
### New Lints
@ -3023,7 +3069,7 @@ Released 2020-12-31
Released 2020-11-19
[**View 112 PRs merged since 1.47**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-10-08..2020-11-19+base%3Amaster+sort%3Amerged-desc+)
[View all 99 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-08-11T13%3A14%3A38Z..2020-09-23T18%3A55%3A22Z+base%3Amaster)
### New lints
@ -3141,8 +3187,7 @@ Released 2020-11-19
Released 2020-10-08
[**View 80 PRs merged since 1.46**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-08-27..2020-10-08+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-06-23T16%3A27%3A11Z..2020-08-11T12%3A52%3A41Z+base%3Amaster)
### New lints
@ -3244,8 +3289,7 @@ Released 2020-10-08
Released 2020-08-27
[**View 93 PRs merged since 1.45**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-07-16..2020-08-27+base%3Amaster+sort%3Amerged-desc+)
[View all 48 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-05-31T12%3A50%3A53Z..2020-06-23T15%3A00%3A32Z+base%3Amaster)
### New lints
@ -3307,8 +3351,7 @@ Released 2020-08-27
Released 2020-07-16
[**View 65 PRs merged since 1.44**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-06-04..2020-07-16+base%3Amaster+sort%3Amerged-desc+)
[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-04-18T20%3A18%3A04Z..2020-05-27T19%3A25%3A04Z+base%3Amaster)
### New lints
@ -3385,8 +3428,7 @@ and [`similar_names`]. [#5651](https://github.com/rust-lang/rust-clippy/pull/565
Released 2020-06-04
[**View 88 PRs merged since 1.43**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-04-23..2020-06-04+base%3Amaster+sort%3Amerged-desc+)
[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-03-05T17%3A30%3A53Z..2020-04-18T09%3A20%3A51Z+base%3Amaster)
### New lints
@ -3469,8 +3511,7 @@ Released 2020-06-04
Released 2020-04-23
[**View 121 PRs merged since 1.42**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-03-12..2020-04-23+base%3Amaster+sort%3Amerged-desc+)
[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-01-26T16%3A01%3A11Z..2020-03-04T16%3A45%3A37Z+base%3Amaster)
### New lints
@ -3528,7 +3569,7 @@ Released 2020-04-23
Released 2020-03-12
[**View 106 PRs merged since 1.41**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2020-01-30..2020-03-12+base%3Amaster+sort%3Amerged-desc+)
[View all 101 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-12-15T01%3A40%3A34Z..2020-01-26T11%3A22%3A13Z+base%3Amaster)
### New lints
@ -3595,7 +3636,7 @@ Released 2020-03-12
Released 2020-01-30
[**View 107 PRs merged since 1.40**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-12-19..2020-01-30+base%3Amaster+sort%3Amerged-desc+)
[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-10-28T20%3A50%3A24Z..2019-12-12T00%3A53%3A03Z+base%3Amaster)
* New Lints:
* [`exit`] [#4697](https://github.com/rust-lang/rust-clippy/pull/4697)
@ -3640,8 +3681,7 @@ Released 2020-01-30
Released 2019-12-19
[**View 69 😺 PRs merged since 1.39**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-11-07..2019-12-19+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-09-23T06%3A18%3A04Z..2019-10-28T17%3A34%3A55Z+base%3Amaster)
* New Lints:
* [`unneeded_wildcard_pattern`] [#4537](https://github.com/rust-lang/rust-clippy/pull/4537)
@ -3683,7 +3723,7 @@ Released 2019-12-19
Released 2019-11-07
[**View 84 PRs merged since 1.38**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-09-26..2019-11-07+base%3Amaster+sort%3Amerged-desc+)
[View all 100 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-08-11T19%3A21%3A38Z..2019-09-22T12%3A07%3A39Z+base%3Amaster)
* New Lints:
* [`uninit_assumed_init`] [#4479](https://github.com/rust-lang/rust-clippy/pull/4479)
@ -3727,7 +3767,7 @@ Released 2019-11-07
Released 2019-09-26
[**View 102 PRs merged since 1.37**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-08-15..2019-09-26+base%3Amaster+sort%3Amerged-desc+)
[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-06-30T13%3A40%3A26Z..2019-08-11T09%3A47%3A27Z+base%3Amaster)
* New Lints:
* [`main_recursion`] [#4203](https://github.com/rust-lang/rust-clippy/pull/4203)
@ -3757,7 +3797,7 @@ Released 2019-09-26
Released 2019-08-15
[**View 83 PRs merged since 1.36**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-07-04..2019-08-15+base%3Amaster+sort%3Amerged-desc+)
[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-05-19T08%3A11%3A23Z..2019-06-25T23%3A22%3A22Z+base%3Amaster)
* New Lints:
* [`checked_conversions`] [#4088](https://github.com/rust-lang/rust-clippy/pull/4088)
@ -3781,8 +3821,7 @@ Released 2019-08-15
Released 2019-07-04
[**View 75 PRs merged since 1.35**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-05-20..2019-07-04+base%3Amaster+sort%3Amerged-desc+)
[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-04-10T09%3A41%3A56Z..2019-05-18T00%3A29%3A40Z+base%3Amaster)
* 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)
@ -3813,8 +3852,7 @@ Released 2019-07-04
Released 2019-05-20
[**View 90 PRs merged since 1.34**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-04-10..2019-05-20+base%3Amaster+sort%3Amerged-desc+)
[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)
@ -3842,8 +3880,7 @@ Released 2019-05-20
Released 2019-04-10
[**View 66 PRs merged since 1.33**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-02-26..2019-04-10+base%3Amaster+sort%3Amerged-desc+)
[View all 61 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-01-17T17%3A45%3A39Z..2019-02-19T08%3A24%3A05Z+base%3Amaster)
* New lint: [`assertions_on_constants`] to detect for example `assert!(true)`
* New lint: [`dbg_macro`] to detect uses of the `dbg!` macro
@ -3873,7 +3910,7 @@ Released 2019-04-10
Released 2019-02-26
[**View 83 PRs merged since 1.32**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2019-01-17..2019-02-26+base%3Amaster+sort%3Amerged-desc+)
[View all 120 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-11-28T06%3A19%3A50Z..2019-01-15T09%3A27%3A02Z+base%3Amaster)
* New lints: [`implicit_return`], [`vec_box`], [`cast_ref_to_mut`]
* The `rust-clippy` repository is now part of the `rust-lang` org.
@ -3906,7 +3943,7 @@ Released 2019-02-26
Released 2019-01-17
[**View 106 PRs merged since 1.31**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-12-06..2019-01-17+base%3Amaster+sort%3Amerged-desc+)
[View all 71 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-10-24T05%3A02%3A21Z..2018-11-27T17%3A29%3A34Z+base%3Amaster)
* New lints: [`slow_vector_initialization`], `mem_discriminant_non_enum`,
[`redundant_clone`], [`wildcard_dependencies`],
@ -3936,8 +3973,7 @@ Released 2019-01-17
Released 2018-12-06
[**View 85 PRs merged since 1.30**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-10-25..2018-12-06+base%3Amaster+sort%3Amerged-desc+)
[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
@ -3977,9 +4013,7 @@ Released 2018-12-06
Released 2018-10-25
[**View 106 PRs merged since 1.29**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2018-09-13..2018-10-25+base%3Amaster+sort%3Amerged-desc+)
[View all 88 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-08-02T16%3A54%3A12Z..2018-09-17T09%3A44%3A06Z+base%3Amaster)
* Deprecate `assign_ops` lint
* New lints: [`mistyped_literal_suffixes`], [`ptr_offset_with_cast`],
[`needless_collect`], [`copy_iterator`]
@ -4861,6 +4895,7 @@ Released 2018-09-13
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type
[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type
[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice
[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
@ -4941,6 +4976,8 @@ Released 2018-09-13
[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite
[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite
[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str
[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
@ -5047,6 +5084,7 @@ Released 2018-09-13
[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref
[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take
[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals
[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
@ -5134,6 +5172,7 @@ Released 2018-09-13
[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer
[`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_clone_in_vec_init
[`rc_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex
[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_line_without_trim
[`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec
[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl
[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
@ -5266,6 +5305,7 @@ Released 2018-09-13
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction
[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.72"
version = "0.1.73"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
@ -36,6 +36,17 @@ walkdir = "2.3"
filetime = "0.2"
itertools = "0.10.1"
# UI test dependencies
clippy_utils = { path = "clippy_utils" }
derive-new = "0.5"
if_chain = "1.0"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
syn = { version = "2.0", features = ["full"] }
futures = "0.3"
parking_lot = "0.12"
tokio = { version = "1", features = ["io-util"] }
[build-dependencies]
rustc_tools_util = "0.3.0"

View File

@ -5,7 +5,7 @@
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
[There are over 600 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are over 650 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.

View File

@ -6,7 +6,7 @@
A collection of lints to catch common mistakes and improve your
[Rust](https://github.com/rust-lang/rust) code.
[There are over 600 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are over 650 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

View File

@ -56,28 +56,6 @@ and open that file in your editor of choice.
When updating the changelog it's also a good idea to make sure that `commit1` is
already correct in the current changelog.
#### PR ranges
We developed the concept of PR ranges to help the user understand the size of a new update. To create a PR range,
get the current release date and the date that the last version was released (YYYY-MM-DD) and use the following link:
```
[**View <NUMBER OF PRs> PRs merged since 1.<LAST VERSION NUM>**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A<LAST VERSION DATE>..<CURRENT VERSION DATE>+base%3Amaster+sort%3Amerged-desc+)
```
> Note: Be sure to check click the link and check how many PRs got merged between
Example:
```
[**View 85 PRs merged since 1.69**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-04-20..2023-06-01+base%3Amaster+sort%3Amerged-desc+)
```
Which renders to:
[**View 85 PRs merged since 1.69**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-04-20..2023-06-01+base%3Amaster+sort%3Amerged-desc+)
Note that **commit ranges should not be included**, only PR ranges.
### 3. Authoring the final changelog
The above script should have dumped all the relevant PRs to the file you

View File

@ -0,0 +1,24 @@
# Speedtest
`SPEEDTEST` is the tool we use to measure lint's performance, it works by executing the same test several times.
It's useful for measuring changes to current lints and deciding if the performance changes too much. `SPEEDTEST` is
accessed by the `SPEEDTEST` (and `SPEEDTEST_*`) environment variables.
## Checking Speedtest
To do a simple speed test of a lint (e.g. `allow_attributes`), use this command.
```sh
$ SPEEDTEST=ui TESTNAME="allow_attributes" cargo uitest -- --nocapture
```
This will test all `ui` tests (`SPEEDTEST=ui`) whose names start with `allow_attributes`. By default, `SPEEDTEST` will
iterate your test 1000 times. But you can change this with `SPEEDTEST_ITERATIONS`.
```sh
$ SPEEDTEST=toml SPEEDTEST_ITERATIONS=100 TESTNAME="semicolon_block" cargo uitest -- --nocapture
```
> **WARNING**: Be sure to use `-- --nocapture` at the end of the command to see the average test time. If you don't
> use `-- --nocapture` (e.g. `SPEEDTEST=ui` `TESTNAME="let_underscore_untyped" cargo uitest -- --nocapture`), this
> will not show up.

View File

@ -175,7 +175,7 @@ The maximum amount of nesting a block can reside in
## `disallowed-names`
The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
`".."` can be used as part of the list to indicate, that the configured values should be appended to the
`".."` can be used as part of the list to indicate that the configured values should be appended to the
default configuration of Clippy. By default, any configuration will replace the default value.
**Default Value:** `["foo", "baz", "quux"]` (`Vec<String>`)

View File

@ -358,6 +358,10 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
let mod_file_path = ty_dir.join("mod.rs");
let context_import = setup_mod_file(&mod_file_path, lint)?;
let pass_lifetimes = match context_import {
"LateContext" => "<'_>",
_ => "",
};
let name_upper = lint.name.to_uppercase();
let mut lint_file_contents = String::new();
@ -372,7 +376,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
use super::{name_upper};
// TODO: Adjust the parameters as necessary
pub(super) fn check(cx: &{context_import}, msrv: &Msrv) {{
pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: &Msrv) {{
if !msrv.meets(todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
return;
}}
@ -389,7 +393,7 @@ pub(super) fn check(cx: &{context_import}, msrv: &Msrv) {{
use super::{name_upper};
// TODO: Adjust the parameters as necessary
pub(super) fn check(cx: &{context_import}) {{
pub(super) fn check(cx: &{context_import}{pass_lifetimes}) {{
todo!();
}}
"#

View File

@ -37,7 +37,7 @@ const fn new(name: &'static str, cargo_file: &'static str, lib_rs_file: &'static
pub fn setup_rustc_src(rustc_path: &str) {
let Ok(rustc_source_dir) = check_and_get_rustc_dir(rustc_path) else {
return
return;
};
for project in CLIPPY_PROJECTS {

View File

@ -340,7 +340,10 @@ fn finish(
let name_upper = name.to_uppercase();
let (mut lints, deprecated_lints, renamed_lints) = gather_all();
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else { eprintln!("error: failed to find lint `{name}`"); return; };
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else {
eprintln!("error: failed to find lint `{name}`");
return;
};
let mod_path = {
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
version = "0.1.72"
version = "0.1.73"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View File

@ -1,5 +1,6 @@
use ast::{AttrStyle, Attribute};
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_from_proc_macro;
use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_lint::{LateContext, LateLintPass, LintContext};

View File

@ -1,12 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::last_path_segment;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_lint::LateLintPass;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;
@ -15,8 +14,8 @@
/// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
///
/// ### Why is this bad?
/// Wrapping a type in Arc doesn't add thread safety to the underlying data, so data races
/// could occur when touching the underlying data.
/// `Arc<T>` is only `Send`/`Sync` when `T` is [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
///
/// ### Example
/// ```rust
@ -24,16 +23,17 @@
/// # use std::sync::Arc;
///
/// fn main() {
/// // This is safe, as `i32` implements `Send` and `Sync`.
/// // This is fine, as `i32` implements `Send` and `Sync`.
/// let a = Arc::new(42);
///
/// // This is not safe, as `RefCell` does not implement `Sync`.
/// // `RefCell` is `!Sync`, so either the `Arc` should be replaced with an `Rc`
/// // or the `RefCell` replaced with something like a `RwLock`
/// let b = Arc::new(RefCell::new(42));
/// }
/// ```
#[clippy::version = "1.72.0"]
pub ARC_WITH_NON_SEND_SYNC,
correctness,
suspicious,
"using `Arc` with a type that does not implement `Send` or `Sync`"
}
declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);
@ -41,32 +41,38 @@
impl LateLintPass<'_> for ArcWithNonSendSync {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let ty = cx.typeck_results().expr_ty(expr);
if_chain! {
if is_type_diagnostic_item(cx, ty, sym::Arc);
if let ExprKind::Call(func, [arg]) = expr.kind;
if let ExprKind::Path(func_path) = func.kind;
if last_path_segment(&func_path).ident.name == sym::new;
if let arg_ty = cx.typeck_results().expr_ty(arg);
if !matches!(arg_ty.kind(), ty::Param(_));
if !cx.tcx
.lang_items()
.sync_trait()
.map_or(false, |id| implements_trait(cx, arg_ty, id, &[])) ||
!cx.tcx
.get_diagnostic_item(sym::Send)
.map_or(false, |id| implements_trait(cx, arg_ty, id, &[]));
if is_type_diagnostic_item(cx, ty, sym::Arc)
&& let ExprKind::Call(func, [arg]) = expr.kind
&& let ExprKind::Path(func_path) = func.kind
&& last_path_segment(&func_path).ident.name == sym::new
&& let arg_ty = cx.typeck_results().expr_ty(arg)
// make sure that the type is not and does not contain any type parameters
&& arg_ty.walk().all(|arg| {
!matches!(arg.unpack(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_)))
})
&& let Some(send) = cx.tcx.get_diagnostic_item(sym::Send)
&& let Some(sync) = cx.tcx.lang_items().sync_trait()
&& let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[]))
&& !(is_send && is_sync)
{
span_lint_and_then(
cx,
ARC_WITH_NON_SEND_SYNC,
expr.span,
"usage of an `Arc` that is not `Send` or `Sync`",
|diag| with_forced_trimmed_paths!({
if !is_send {
diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`"));
}
if !is_sync {
diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`"));
}
then {
span_lint_and_help(
cx,
ARC_WITH_NON_SEND_SYNC,
expr.span,
"usage of `Arc<T>` where `T` is not `Send` or `Sync`",
None,
"consider using `Rc<T>` instead or wrapping `T` in a std::sync type like \
`Mutex<T>`",
);
}
diag.note(format!("required for `{ty}` to implement `Send` and `Sync`"));
diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`");
}
));
}
}
}

View File

@ -31,14 +31,20 @@
impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, e) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, e) else {
return;
};
let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
Some(sym::debug_assert_macro) => true,
Some(sym::assert_macro) => false,
_ => return,
};
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else { return };
let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else { return };
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else {
return;
};
let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else {
return;
};
if val {
span_lint_and_help(
cx,

View File

@ -1,12 +1,10 @@
//! checks for attributes
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::is_from_proc_macro;
use clippy_utils::macros::{is_panic, macro_backtrace};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
use clippy_utils::{
diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then},
is_from_proc_macro,
};
use if_chain::if_chain;
use rustc_ast::{AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
use rustc_errors::Applicability;

View File

@ -1,9 +1,8 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::get_parent_expr;
use clippy_utils::higher;
use clippy_utils::source::snippet_block_with_applicability;
use clippy_utils::ty::implements_trait;
use clippy_utils::visitors::{for_each_expr, Descend};
use clippy_utils::{get_parent_expr, higher};
use core::ops::ControlFlow;
use if_chain::if_chain;
use rustc_errors::Applicability;
@ -85,8 +84,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
);
}
} else {
let span =
block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
if span.from_expansion() || expr.span.from_expansion() {
return;
}

View File

@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
)
})
.map_or(false, |assoc_item| {
let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
nty.is_bool()
@ -70,14 +70,18 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let macro_name = cx.tcx.item_name(macro_call.def_id);
let eq_macro = match macro_name.as_str() {
"assert_eq" | "debug_assert_eq" => true,
"assert_ne" | "debug_assert_ne" => false,
_ => return,
};
let Some ((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
let Some((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
return;
};
let a_span = a.span.source_callsite();
let b_span = b.span.source_callsite();
@ -126,7 +130,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())];
if bool_value ^ eq_macro {
let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) else { return };
let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) else {
return;
};
suggestions.push((non_lit_expr.span, (!sugg).to_string()));
}

View File

@ -4,7 +4,9 @@
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use clippy_utils::{diagnostics::span_lint_and_then, in_constant, is_else_clause, is_integer_literal, sugg::Sugg};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sugg::Sugg;
use clippy_utils::{in_constant, is_else_clause, is_integer_literal};
use rustc_errors::Applicability;
declare_clippy_lint! {

View File

@ -1,9 +1,8 @@
use crate::reference::DEREF_ADDROF;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
use clippy_utils::{get_parent_expr, is_lint_allowed};
use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
use rustc_errors::Applicability;
use rustc_hir::{ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,12 +1,10 @@
use clippy_utils::{
diagnostics::span_lint_and_sugg, get_parent_node, is_default_equivalent, macros::macro_backtrace, match_path,
path_def_id, paths, ty::expr_sig,
};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::macro_backtrace;
use clippy_utils::ty::expr_sig;
use clippy_utils::{get_parent_node, is_default_equivalent, match_path, path_def_id, paths};
use rustc_errors::Applicability;
use rustc_hir::{
intravisit::{walk_ty, Visitor},
Block, Expr, ExprKind, Local, Node, QPath, TyKind,
};
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::print::with_forced_trimmed_paths;

View File

@ -3,10 +3,8 @@
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::{
mir::Mutability,
ty::{self, Ty, TypeAndMut},
};
use rustc_middle::mir::Mutability;
use rustc_middle::ty::{self, Ty, TypeAndMut};
use super::AS_PTR_CAST_MUT;

View File

@ -1,10 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::{diagnostics::span_lint_and_then, source};
use clippy_utils::source;
use if_chain::if_chain;
use rustc_ast::Mutability;
use rustc_hir::{Expr, ExprKind, Node};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, layout::LayoutOf, Ty, TypeAndMut};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Ty, TypeAndMut};
use super::CAST_SLICE_DIFFERENT_SIZES;

View File

@ -4,7 +4,8 @@
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{def_id::DefId, Expr, ExprKind};
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};

View File

@ -1,6 +1,6 @@
use clippy_utils::msrvs::POINTER_CAST_CONSTNESS;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{Msrv, POINTER_CAST_CONSTNESS};
use clippy_utils::sugg::Sugg;
use clippy_utils::{diagnostics::span_lint_and_sugg, msrvs::Msrv};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability};

View File

@ -56,7 +56,7 @@ pub(super) fn check<'tcx>(
&format!("casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"),
"try",
cast_str.clone(),
Applicability::MachineApplicable,
Applicability::MaybeIncorrect,
);
}
}

View File

@ -10,8 +10,7 @@
use core::ops::ControlFlow;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::intravisit;
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind};
use rustc_hir::{intravisit, BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::query::Key;
use rustc_session::{declare_tool_lint, impl_lint_pass};

View File

@ -5,7 +5,8 @@
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{symbol::sym, Span};
use rustc_span::symbol::sym;
use rustc_span::Span;
declare_clippy_lint! {
/// ### What it does

View File

@ -71,7 +71,9 @@ pub fn new(allow_dbg_in_tests: bool) -> Self {
impl LateLintPass<'_> for DbgMacro {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) {
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
if self.allow_dbg_in_tests

View File

@ -206,6 +206,7 @@
crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
crate::incorrect_impls::INCORRECT_CLONE_IMPL_ON_COPY_TYPE_INFO,
crate::incorrect_impls::INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE_INFO,
crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
crate::indexing_slicing::INDEXING_SLICING_INFO,
crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
@ -272,6 +273,8 @@
crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,
crate::manual_bits::MANUAL_BITS_INFO,
crate::manual_clamp::MANUAL_CLAMP_INFO,
crate::manual_float_methods::MANUAL_IS_FINITE_INFO,
crate::manual_float_methods::MANUAL_IS_INFINITE_INFO,
crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
crate::manual_let_else::MANUAL_LET_ELSE_INFO,
crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,
@ -388,6 +391,7 @@
crate::methods::OR_THEN_UNWRAP_INFO,
crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
crate::methods::RANGE_ZIP_WITH_LEN_INFO,
crate::methods::READ_LINE_WITHOUT_TRIM_INFO,
crate::methods::REPEAT_ONCE_INFO,
crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
crate::methods::SEARCH_IS_SOME_INFO,
@ -403,6 +407,7 @@
crate::methods::SUSPICIOUS_MAP_INFO,
crate::methods::SUSPICIOUS_SPLITN_INFO,
crate::methods::SUSPICIOUS_TO_OWNED_INFO,
crate::methods::TYPE_ID_ON_BOX_INFO,
crate::methods::UNINIT_ASSUMED_INIT_INFO,
crate::methods::UNIT_HASH_INFO,
crate::methods::UNNECESSARY_FILTER_MAP_INFO,
@ -468,6 +473,7 @@
crate::needless_if::NEEDLESS_IF_INFO,
crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,
crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,
crate::needless_pass_by_ref_mut::NEEDLESS_PASS_BY_REF_MUT_INFO,
crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,
crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO,
crate::needless_update::NEEDLESS_UPDATE_INFO,

View File

@ -1,5 +1,7 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, is_ty_alias, match_def_path, paths};
use hir::{def::Res, ExprKind};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{is_ty_alias, match_def_path, paths};
use hir::def::Res;
use hir::ExprKind;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::last_path_segment;
use clippy_utils::source::snippet_with_context;
use clippy_utils::{match_def_path, paths};
use clippy_utils::{last_path_segment, match_def_path, paths};
use rustc_errors::Applicability;
use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -4,15 +4,11 @@
use if_chain::if_chain;
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::{
intravisit::{walk_expr, walk_stmt, Visitor},
Body, Expr, ExprKind, HirId, ItemKind, Lit, Node, Stmt, StmtKind,
};
use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor};
use rustc_hir::{Body, Expr, ExprKind, HirId, ItemKind, Lit, Node, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{
lint::in_external_macro,
ty::{self, FloatTy, IntTy, PolyFnSig, Ty},
};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::iter;

View File

@ -12,12 +12,11 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
use rustc_errors::Applicability;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{
self as hir,
def_id::{DefId, LocalDefId},
BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId, ImplItem,
ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId,
ImplItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
TraitItemKind, TyKind, UnOp,
};
use rustc_index::bit_set::BitSet;
@ -30,9 +29,11 @@
ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults,
};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span, Symbol};
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{Obligation, ObligationCause};
use std::collections::VecDeque;
declare_clippy_lint! {
@ -77,6 +78,11 @@
/// Suggests that the receiver of the expression borrows
/// the expression.
///
/// ### Known problems
/// The lint cannot tell when the implementation of a trait
/// for `&T` and `T` do different things. Removing a borrow
/// in such a case can change the semantics of the code.
///
/// ### Example
/// ```rust
/// fn fun(_a: &i32) {}
@ -589,7 +595,7 @@ fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
pat.spans,
"this pattern creates a reference to a reference",
|diag| {
diag.multipart_suggestion("try this", replacements, app);
diag.multipart_suggestion("try", replacements, app);
},
);
}
@ -1123,7 +1129,9 @@ fn needless_borrow_impl_arg_position<'tcx>(
let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) };
let Some(callee_def_id) = fn_def_id(cx, parent) else {
return Position::Other(precedence);
};
let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
let args_with_expr_ty = cx
.typeck_results()
@ -1252,7 +1260,12 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
.in_definition_order()
.any(|assoc_item| {
if assoc_item.fn_has_self_parameter {
let self_ty = cx.tcx.fn_sig(assoc_item.def_id).instantiate_identity().skip_binder().inputs()[0];
let self_ty = cx
.tcx
.fn_sig(assoc_item.def_id)
.instantiate_identity()
.skip_binder()
.inputs()[0];
matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
} else {
false
@ -1296,8 +1309,8 @@ fn referent_used_exactly_once<'tcx>(
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
reference: &Expr<'tcx>,
) -> bool {
let mir = enclosing_mir(cx.tcx, reference.hir_id);
if let Some(local) = expr_local(cx.tcx, reference)
if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
&& let Some(local) = expr_local(cx.tcx, reference)
&& let [location] = *local_assignments(mir, local).as_slice()
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
@ -1442,9 +1455,7 @@ fn ty_auto_deref_stability<'tcx>(
ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => {
Position::ReborrowStable(precedence).into()
},
ty::Adt(_, args) if args.has_non_region_param() => {
TyPosition::new_deref_stable_for_result(precedence, ty)
},
ty::Adt(_, args) if args.has_non_region_param() => TyPosition::new_deref_stable_for_result(precedence, ty),
ty::Bool
| ty::Char
| ty::Int(_)
@ -1531,7 +1542,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
Mutability::Not => "explicit `deref` method call",
Mutability::Mut => "explicit `deref_mut` method call",
},
"try this",
"try",
format!("{addr_of_str}{deref_str}{expr_str}"),
app,
);
@ -1593,7 +1604,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
} else {
format!("{prefix}{snip}")
};
diag.span_suggestion(data.span, "try this", sugg, app);
diag.span_suggestion(data.span, "try", sugg, app);
},
);
},
@ -1620,7 +1631,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
|diag| {
let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0;
diag.span_suggestion(data.span, "try this", snip.into_owned(), app);
diag.span_suggestion(data.span, "try", snip.into_owned(), app);
},
);
},

View File

@ -3,10 +3,9 @@
use clippy_utils::source::indent_of;
use clippy_utils::{is_default_equivalent, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::{
self as hir,
def::{CtorKind, CtorOf, DefKind, Res},
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
self as hir, Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
@ -99,10 +98,11 @@ fn check_struct<'tcx>(
if let Some(PathSegment { args, .. }) = p.segments.last() {
let args = args.map(|a| a.args).unwrap_or(&[]);
// ty_args contains the generic parameters of the type declaration, while args contains the arguments
// used at instantiation time. If both len are not equal, it means that some parameters were not
// provided (which means that the default values were used); in this case we will not risk
// suggesting too broad a rewrite. We won't either if any argument is a type or a const.
// ty_args contains the generic parameters of the type declaration, while args contains the
// arguments used at instantiation time. If both len are not equal, it means that some
// parameters were not provided (which means that the default values were used); in this
// case we will not risk suggesting too broad a rewrite. We won't either if any argument
// is a type or a const.
if ty_args.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) {
return;
}

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::paths;
use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
use clippy_utils::{is_lint_allowed, match_def_path};
use clippy_utils::{is_lint_allowed, match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
@ -334,7 +333,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
Some(id) if trait_ref.trait_def_id() == Some(id) => id,
_ => return,
};
let Some(copy_id) = cx.tcx.lang_items().copy_trait() else { return };
let Some(copy_id) = cx.tcx.lang_items().copy_trait() else {
return;
};
let (ty_adt, ty_subs) = match *ty.kind() {
// Unions can't derive clone.
ty::Adt(adt, subs) if !adt.is_union() => (adt, subs),

View File

@ -94,7 +94,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
path_def_id(cx, expr)
};
let Some(def_id) = uncalled_path.or_else(|| fn_def_id(cx, expr)) else {
return
return;
};
let conf = match self.disallowed.get(&def_id) {
Some(&index) => &self.conf_disallowed[index],

View File

@ -1,4 +1,5 @@
use clippy_utils::{diagnostics::span_lint, is_test_module_or_function};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::is_test_module_or_function;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{Item, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -31,9 +31,8 @@
use rustc_span::edition::Edition;
use rustc_span::source_map::{BytePos, FilePathMapping, SourceMap, Span};
use rustc_span::{sym, FileName, Pos};
use std::io;
use std::ops::Range;
use std::thread;
use std::{io, thread};
use url::Url;
declare_clippy_lint! {
@ -295,7 +294,9 @@ fn check_crate(&mut self, cx: &LateContext<'tcx>) {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
match item.kind {
hir::ItemKind::Fn(ref sig, _, body_id) => {
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@ -339,7 +340,9 @@ fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
if !in_external_macro(cx.tcx.sess, item.span) {
lint_for_missing_headers(cx, item.owner_id, sig, headers, None, None);
@ -349,7 +352,9 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitIte
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
return;
}

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::get_parent_node;
use clippy_utils::is_must_use_func_call;
use clippy_utils::ty::{is_copy, is_must_use_ty, is_type_lang_item};
use clippy_utils::{get_parent_node, is_must_use_func_call};
use rustc_hir::{Arm, Expr, ExprKind, LangItem, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

View File

@ -1,4 +1,5 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, peel_blocks};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::peel_blocks;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, Node};

View File

@ -1,4 +1,5 @@
use clippy_utils::{diagnostics::span_lint_and_then, source::snippet_opt};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use rustc_ast::ast::{Item, ItemKind, VariantData};
use rustc_errors::Applicability;
use rustc_lexer::TokenKind;

View File

@ -1,8 +1,10 @@
use crate::Lint;
use clippy_utils::{diagnostics::span_lint_and_then, is_lint_allowed};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_lint_allowed;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{lint::in_external_macro, ty::Ty};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Symbol;
use std::borrow::Cow;

View File

@ -1,18 +1,14 @@
use clippy_utils::higher;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
use clippy_utils::{
can_move_expr_to_closure_no_visit,
diagnostics::span_lint_and_sugg,
is_expr_final_block_expr, is_expr_used_or_unified, match_def_path, paths, peel_hir_expr_while,
source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context},
SpanlessEq,
can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, match_def_path,
paths, peel_hir_expr_while, SpanlessEq,
};
use core::fmt::{self, Write};
use rustc_errors::Applicability;
use rustc_hir::{
hir_id::HirIdSet,
intravisit::{walk_expr, Visitor},
Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp,
};
use rustc_hir::hir_id::HirIdSet;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{Span, SyntaxContext, DUMMY_SP};
@ -69,16 +65,21 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
return;
}
let Some(higher::If { cond: cond_expr, then: then_expr, r#else: else_expr }) = higher::If::hir(expr) else {
return
let Some(higher::If {
cond: cond_expr,
then: then_expr,
r#else: else_expr,
}) = higher::If::hir(expr)
else {
return;
};
let Some((map_ty, contains_expr)) = try_parse_contains(cx, cond_expr) else {
return
return;
};
let Some(then_search) = find_insert_calls(cx, &contains_expr, then_expr) else {
return
return;
};
let mut app = Applicability::MachineApplicable;
@ -186,7 +187,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
MAP_ENTRY,
expr.span,
&format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name()),
"try this",
"try",
sugg,
app,
);

View File

@ -1,6 +1,5 @@
use clippy_utils::diagnostics::span_lint_hir;
use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
use rustc_hir::{self, intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,9 +1,8 @@
use clippy_utils::{diagnostics::span_lint_and_help, source::snippet};
use rustc_ast::{
node_id::NodeSet,
visit::{walk_block, walk_item, Visitor},
Block, Crate, Inline, Item, ItemKind, ModKind, NodeId,
};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet;
use rustc_ast::node_id::NodeSet;
use rustc_ast::visit::{walk_block, walk_item, Visitor};
use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};

View File

@ -100,7 +100,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
EXPLICIT_WRITE,
expr.span,
&format!("use of `{used}.unwrap()`"),
"try this",
"try",
format!("{prefix}{sugg_mac}!({inputs_snippet})"),
applicability,
);

View File

@ -1,6 +1,5 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
use clippy_utils::is_from_proc_macro;
use clippy_utils::trait_ref_of_method;
use clippy_utils::{is_from_proc_macro, trait_ref_of_method};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_impl_item, walk_item, walk_param_bound, walk_ty, Visitor};
@ -12,10 +11,8 @@
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{
def_id::{DefId, LocalDefId},
Span,
};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
declare_clippy_lint! {
/// ### What it does

View File

@ -1,10 +1,8 @@
use clippy_utils::consts::{
constant, constant_simple, Constant,
Constant::{Int, F32, F64},
};
use clippy_utils::consts::Constant::{Int, F32, F64};
use clippy_utils::consts::{constant, constant_simple, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{
diagnostics::span_lint_and_sugg, eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate,
numeric_literal, peel_blocks, sugg,
eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, numeric_literal, peel_blocks, sugg,
};
use if_chain::if_chain;
use rustc_errors::Applicability;

View File

@ -43,7 +43,9 @@
impl<'tcx> LateLintPass<'tcx> for UselessFormat {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
return;
}

View File

@ -14,10 +14,8 @@
FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
FormatPlaceholder, FormatTrait,
};
use rustc_errors::{
Applicability,
SuggestionStyle::{CompletelyHidden, ShowCode},
};
use rustc_errors::Applicability;
use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
@ -188,7 +186,9 @@ pub fn new(msrv: Msrv, allow_mixed_uninlined_format_args: bool) -> Self {
impl<'tcx> LateLintPass<'tcx> for FormatArgs {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if !is_format_macro(cx, macro_call.def_id) {
return;
}

View File

@ -7,8 +7,8 @@
use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
use rustc_span::{sym, symbol::kw, Symbol};
use rustc_span::symbol::kw;
use rustc_span::{sym, Span, Symbol};
declare_clippy_lint! {
/// ### What it does
@ -127,7 +127,9 @@ fn check_impl_item_post(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(format_trait_impl) = self.format_trait_impl else { return };
let Some(format_trait_impl) = self.format_trait_impl else {
return;
};
if format_trait_impl.name == sym::Display {
check_to_string_in_display(cx, expr);

View File

@ -10,7 +10,8 @@
TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::{hir::nested_filter::OnlyBodies, ty};
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::{kw, sym};
use rustc_span::{Span, Symbol};
@ -76,7 +77,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
&& let Some(into_trait_seg) = hir_trait_ref.path.segments.last()
// `impl Into<target_ty> for self_ty`
&& let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args
&& let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(ty::EarlyBinder::instantiate_identity)
&& let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
.map(ty::EarlyBinder::instantiate_identity)
&& cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id)
&& !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _))
{
@ -163,10 +165,14 @@ fn convert_to_from(
return None;
}
let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None };
let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {
return None;
};
let body = cx.tcx.hir().body(body_id);
let [input] = body.params else { return None };
let PatKind::Binding(.., self_ident, None) = input.pat.kind else { return None };
let PatKind::Binding(.., self_ident, None) = input.pat.kind else {
return None;
};
let from = snippet_opt(cx, self_ty.span)?;
let into = snippet_opt(cx, target_ty.span)?;

View File

@ -4,8 +4,7 @@
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::RawPtr;
use rustc_middle::ty::TypeAndMut;
use rustc_middle::ty::{RawPtr, TypeAndMut};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

View File

@ -1,6 +1,8 @@
use clippy_utils::{diagnostics::span_lint_and_then, is_in_test_function};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_in_test_function;
use rustc_hir::{intravisit::FnKind, Body, HirId};
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, HirId};
use rustc_lint::LateContext;
use rustc_span::Span;

View File

@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir::{intravisit::FnKind, Body, ExprKind, FnDecl, ImplicitSelfKind, Unsafety};
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Unsafety};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::Span;
@ -12,8 +13,8 @@
pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: &Body<'_>, span: Span) {
let FnKind::Method(ref ident, sig) = kind else {
return;
};
return;
};
// Takes only &(mut) self
if decl.inputs.len() != 1 {
@ -25,8 +26,8 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
let name = match decl.implicit_self {
ImplicitSelfKind::MutRef => {
let Some(name) = name.strip_suffix("_mut") else {
return;
};
return;
};
name
},
ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::ImmRef => name,
@ -76,7 +77,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
for adjusted_type in iter::once(typeck_results.expr_ty(self_data))
.chain(typeck_results.expr_adjustments(self_data).iter().map(|adj| adj.target))
{
let ty::Adt(def,_) = adjusted_type.kind() else {
let ty::Adt(def, _) = adjusted_type.kind() else {
continue;
};
@ -91,13 +92,15 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
}
let Some(used_field) = used_field else {
// Can happen if the field access is a tuple. We don't lint those because the getter name could not start with a number.
// Can happen if the field access is a tuple. We don't lint those because the getter name could not
// start with a number.
return;
};
let Some(correct_field) = correct_field else {
// There is no field corresponding to the getter name.
// FIXME: This can be a false positive if the correct field is reachable through deeper autodereferences than used_field is
// FIXME: This can be a false positive if the correct field is reachable through deeper
// autodereferences than used_field is
return;
};

View File

@ -1,14 +1,13 @@
use hir::FnSig;
use rustc_ast::ast::Attribute;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::{self as hir, def::Res, QPath};
use rustc_hir::{self as hir, QPath};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::{
lint::in_external_macro,
ty::{self, Ty},
};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_span::{sym, Span, Symbol};
use clippy_utils::attrs::is_proc_macro;

View File

@ -23,7 +23,7 @@ pub(super) fn check_fn(
}
let Some(code_snippet) = snippet_opt(cx, body.value.span) else {
return
return;
};
let mut line_count: u64 = 0;
let mut in_comment = false;

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::SpanlessEq;
use clippy_utils::{higher, SpanlessEq};
use if_chain::if_chain;
use rustc_errors::Diagnostic;
use rustc_hir::intravisit::{self as visit, Visitor};

View File

@ -119,7 +119,13 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
fn stmts_contains_early_return(stmts: &[Stmt<'_>]) -> bool {
stmts.iter().any(|stmt| {
let Stmt { kind: StmtKind::Semi(e), .. } = stmt else { return false };
let Stmt {
kind: StmtKind::Semi(e),
..
} = stmt
else {
return false;
};
contains_return(e)
})

View File

@ -1,9 +1,7 @@
use clippy_utils::{
diagnostics::span_lint_hir_and_then,
get_async_fn_body, is_async_fn,
source::{snippet_with_applicability, snippet_with_context, walk_span_to_context},
visitors::for_each_expr,
};
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
use clippy_utils::visitors::for_each_expr;
use clippy_utils::{get_async_fn_body, is_async_fn};
use core::ops::ControlFlow;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;

View File

@ -1,11 +1,15 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, get_parent_node, last_path_segment, ty::implements_trait};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::ty::implements_trait;
use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, path_res};
use rustc_errors::Applicability;
use rustc_hir::{ExprKind, ImplItem, ImplItemKind, ItemKind, Node, UnOp};
use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::EarlyBinder;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, symbol};
use rustc_span::sym;
use rustc_span::symbol::kw;
declare_clippy_lint! {
/// ### What it does
@ -46,25 +50,80 @@
correctness,
"manual implementation of `Clone` on a `Copy` type"
}
declare_lint_pass!(IncorrectImpls => [INCORRECT_CLONE_IMPL_ON_COPY_TYPE]);
declare_clippy_lint! {
/// ### What it does
/// Checks for manual implementations of both `PartialOrd` and `Ord` when only `Ord` is
/// necessary.
///
/// ### Why is this bad?
/// If both `PartialOrd` and `Ord` are implemented, they must agree. This is commonly done by
/// wrapping the result of `cmp` in `Some` for `partial_cmp`. Not doing this may silently
/// introduce an error upon refactoring.
///
/// ### Limitations
/// Will not lint if `Self` and `Rhs` do not have the same type.
///
/// ### Example
/// ```rust
/// # use std::cmp::Ordering;
/// #[derive(Eq, PartialEq)]
/// struct A(u32);
///
/// impl Ord for A {
/// fn cmp(&self, other: &Self) -> Ordering {
/// // ...
/// # todo!();
/// }
/// }
///
/// impl PartialOrd for A {
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// // ...
/// # todo!();
/// }
/// }
/// ```
/// Use instead:
/// ```rust
/// # use std::cmp::Ordering;
/// #[derive(Eq, PartialEq)]
/// struct A(u32);
///
/// impl Ord for A {
/// fn cmp(&self, other: &Self) -> Ordering {
/// // ...
/// # todo!();
/// }
/// }
///
/// impl PartialOrd for A {
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
/// ```
#[clippy::version = "1.72.0"]
pub INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE,
correctness,
"manual implementation of `PartialOrd` when `Ord` is already implemented"
}
declare_lint_pass!(IncorrectImpls => [INCORRECT_CLONE_IMPL_ON_COPY_TYPE, INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE]);
impl LateLintPass<'_> for IncorrectImpls {
#[expect(clippy::needless_return)]
#[expect(clippy::too_many_lines)]
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
let node = get_parent_node(cx.tcx, impl_item.hir_id());
let Some(Node::Item(item)) = node else {
return;
};
let ItemKind::Impl(imp) = item.kind else {
let Some(Node::Item(item)) = get_parent_node(cx.tcx, impl_item.hir_id()) else {
return;
};
let Some(trait_impl) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::skip_binder) else {
return;
};
let trait_impl_def_id = trait_impl.def_id;
if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) {
return;
}
let ItemKind::Impl(imp) = item.kind else {
return;
};
let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else {
return;
};
@ -72,15 +131,12 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
let ExprKind::Block(block, ..) = body.value.kind else {
return;
};
// Above is duplicated from the `duplicate_manual_partial_ord_impl` branch.
// Remove it while solving conflicts once that PR is merged.
// Actual implementation; remove this comment once aforementioned PR is merged
if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl_def_id)
if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id)
&& let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy)
&& implements_trait(
cx,
hir_ty_to_ty(cx.tcx, imp.self_ty),
trait_impl.self_ty(),
copy_def_id,
&[],
)
@ -88,9 +144,9 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
if impl_item.ident.name == sym::clone {
if block.stmts.is_empty()
&& let Some(expr) = block.expr
&& let ExprKind::Unary(UnOp::Deref, inner) = expr.kind
&& let ExprKind::Path(qpath) = inner.kind
&& last_path_segment(&qpath).ident.name == symbol::kw::SelfLower
&& let ExprKind::Unary(UnOp::Deref, deref) = expr.kind
&& let ExprKind::Path(qpath) = deref.kind
&& last_path_segment(&qpath).ident.name == kw::SelfLower
{} else {
span_lint_and_sugg(
cx,
@ -112,7 +168,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
impl_item.span,
"incorrect implementation of `clone_from` on a `Copy` type",
"remove this",
"remove it",
String::new(),
Applicability::MaybeIncorrect,
);
@ -120,5 +176,69 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
return;
}
}
if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
&& impl_item.ident.name == sym::partial_cmp
&& let Some(ord_def_id) = cx
.tcx
.diagnostic_items(trait_impl.def_id.krate)
.name_to_id
.get(&sym::Ord)
&& implements_trait(
cx,
hir_ty_to_ty(cx.tcx, imp.self_ty),
*ord_def_id,
trait_impl.args,
)
{
if block.stmts.is_empty()
&& let Some(expr) = block.expr
&& let ExprKind::Call(
Expr {
kind: ExprKind::Path(some_path),
hir_id: some_hir_id,
..
},
[cmp_expr],
) = expr.kind
&& is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome)
&& let ExprKind::MethodCall(cmp_path, _, [other_expr], ..) = cmp_expr.kind
&& cmp_path.ident.name == sym::cmp
&& let Res::Local(..) = path_res(cx, other_expr)
{} else {
// If `Self` and `Rhs` are not the same type, bail. This makes creating a valid
// suggestion tons more complex.
if let [lhs, rhs, ..] = trait_impl.args.as_slice() && lhs != rhs {
return;
}
span_lint_and_then(
cx,
INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE,
item.span,
"incorrect implementation of `partial_cmp` on an `Ord` type",
|diag| {
let [_, other] = body.params else {
return;
};
let suggs = if let Some(other_ident) = other.pat.simple_ident() {
vec![(block.span, format!("{{ Some(self.cmp({})) }}", other_ident.name))]
} else {
vec![
(block.span, "{ Some(self.cmp(other)) }".to_owned()),
(other.pat.span, "other".to_owned()),
]
};
diag.multipart_suggestion(
"change this to",
suggs,
Applicability::Unspecified,
);
}
);
}
}
}
}

View File

@ -13,7 +13,8 @@
use rustc_middle::hir::nested_filter;
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::Ident, Span};
use rustc_span::symbol::Ident;
use rustc_span::Span;
declare_clippy_lint! {
/// ### What it does

View File

@ -3,7 +3,8 @@
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::is_lint_allowed;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{def_id::LocalDefId, Item, ItemKind, Node};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;

View File

@ -71,7 +71,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
INIT_NUMBERED_FIELDS,
e.span,
"used a field initializer for a tuple struct",
"try this instead",
"try",
snippet,
appl,
);

View File

@ -7,7 +7,8 @@
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{source_map::Spanned, sym};
use rustc_span::source_map::Spanned;
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does

View File

@ -1,4 +1,5 @@
use clippy_utils::{diagnostics::span_lint_and_help, is_from_proc_macro, is_in_cfg_test};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::{is_from_proc_macro, is_in_cfg_test};
use rustc_hir::{HirId, ItemId, ItemKind, Mod};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
@ -32,7 +33,7 @@
/// // [...]
/// }
/// ```
#[clippy::version = "1.70.0"]
#[clippy::version = "1.71.0"]
pub ITEMS_AFTER_TEST_MODULE,
style,
"An item was found after the testing module `tests`"

View File

@ -1,5 +1,8 @@
use clippy_utils::{diagnostics::span_lint, get_parent_node, ty::implements_trait};
use rustc_hir::{def_id::LocalDefId, FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::get_parent_node;
use clippy_utils::ty::implements_trait;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;

View File

@ -1,10 +1,8 @@
//! lint when there is a large size difference between variants on an enum
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{
diagnostics::span_lint_and_then,
ty::{approx_ty_size, is_copy, AdtVariantInfo},
};
use clippy_utils::ty::{approx_ty_size, is_copy, AdtVariantInfo};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::implements_trait};
use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -2,8 +2,7 @@
use clippy_utils::is_lint_allowed;
use clippy_utils::macros::root_macro_call_first_node;
use rustc_ast::LitKind;
use rustc_hir::Expr;
use rustc_hir::ExprKind;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;

View File

@ -4,11 +4,9 @@
use clippy_utils::fn_has_unsatisfiable_preds;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::Body;
use rustc_hir::FnDecl;
use rustc_hir::{Body, FnDecl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_tool_lint;
use rustc_session::impl_lint_pass;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
declare_clippy_lint! {

View File

@ -1,22 +1,23 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet_with_context;
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators, sugg::Sugg};
use clippy_utils::sugg::Sugg;
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
def::Res, def_id::DefId, lang_items::LangItem, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg,
GenericBound, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, Node, PathSegment, PrimTy,
QPath, TraitItemRef, TyKind, TypeBindingKind,
AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
ImplicitSelfKind, Item, ItemKind, Mutability, Node, PathSegment, PrimTy, QPath, TraitItemRef, TyKind,
TypeBindingKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{
source_map::{Span, Spanned, Symbol},
symbol::sym,
};
use rustc_span::source_map::{Span, Spanned, Symbol};
use rustc_span::symbol::sym;
declare_clippy_lint! {
/// ### What it does
@ -145,7 +146,10 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
if let Some(local_id) = ty_id.as_local();
let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id);
if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder());
if let Some(output) = parse_len_output(
cx,
cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()
);
then {
let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),

View File

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::path_to_local_id;
use clippy_utils::source::snippet;
use clippy_utils::{path_to_local_id, visitors::is_local_used};
use clippy_utils::visitors::is_local_used;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;

View File

@ -1,12 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_from_proc_macro;
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::{is_must_use_func_call, paths};
use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
use rustc_hir::{Local, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::IsSuggestable;
use rustc_middle::ty::{GenericArgKind, IsSuggestable};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{BytePos, Span};

View File

@ -183,6 +183,7 @@
mod manual_async_fn;
mod manual_bits;
mod manual_clamp;
mod manual_float_methods;
mod manual_is_ascii_check;
mod manual_let_else;
mod manual_main_separator_str;
@ -228,6 +229,7 @@
mod needless_if;
mod needless_late_init;
mod needless_parens_on_range_literals;
mod needless_pass_by_ref_mut;
mod needless_pass_by_value;
mod needless_question_mark;
mod needless_update;
@ -345,11 +347,10 @@
mod zero_sized_map_values;
// end lints modules, do not remove this comment, its used in `update_lints`
use crate::utils::conf::metadata::get_configuration_metadata;
use crate::utils::conf::TryConf;
pub use crate::utils::conf::{lookup_conf_file, Conf};
use crate::utils::{
conf::{metadata::get_configuration_metadata, TryConf},
FindAll,
};
use crate::utils::FindAll;
/// Register all pre expansion lints
///
@ -662,7 +663,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
let matches_for_let_else = conf.matches_for_let_else;
store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv(), matches_for_let_else)));
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv())));
store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv())));
store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv())));
@ -722,7 +722,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(drop_forget_ref::DropForgetRef));
store.register_late_pass(|_| Box::new(empty_enum::EmptyEnum));
store.register_late_pass(|_| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
store.register_late_pass(|_| Box::new(regex::Regex));
store.register_late_pass(|_| Box::<regex::Regex>::default());
let ignore_interior_mutability = conf.ignore_interior_mutability.clone();
store.register_late_pass(move |_| Box::new(copies::CopyAndPaste::new(ignore_interior_mutability.clone())));
store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator));
@ -771,7 +771,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::<useless_conversion::UselessConversion>::default());
store.register_late_pass(|_| Box::new(implicit_hasher::ImplicitHasher));
store.register_late_pass(|_| Box::new(fallible_impl_from::FallibleImplFrom));
store.register_late_pass(|_| Box::<question_mark::QuestionMark>::default());
store.register_late_pass(move |_| Box::new(question_mark::QuestionMark::new(msrv(), matches_for_let_else)));
store.register_late_pass(|_| Box::new(question_mark_used::QuestionMarkUsed));
store.register_early_pass(|| Box::new(suspicious_operation_groupings::SuspiciousOperationGroupings));
store.register_late_pass(|_| Box::new(suspicious_trait_impl::SuspiciousImpl));
@ -1056,6 +1056,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
let stack_size_threshold = conf.stack_size_threshold;
store.register_late_pass(move |_| Box::new(large_stack_frames::LargeStackFrames::new(stack_size_threshold)));
store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit));
store.register_late_pass(move |_| {
Box::new(needless_pass_by_ref_mut::NeedlessPassByRefMut::new(
avoid_breaking_exported_api,
))
});
store.register_late_pass(|_| Box::new(incorrect_impls::IncorrectImpls));
store.register_late_pass(move |_| {
Box::new(single_call_fn::SingleCallFn {
@ -1072,6 +1077,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns));
store.register_early_pass(|| Box::new(visibility::Visibility));
store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() }));
store.register_late_pass(|_| Box::new(manual_float_methods::ManualFloatMethods));
// add lints here, do not remove this comment, it's used in `new_lint`
}

View File

@ -1,7 +1,6 @@
use clippy_utils::{
diagnostics::span_lint_and_then, is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths,
ty::match_type,
};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::match_type;
use clippy_utils::{is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths};
use rustc_errors::Applicability;
use rustc_hir::{Body, Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};

View File

@ -264,7 +264,7 @@ fn check_lit(self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
return;
}
if Self::is_literal_uuid_formatted(&mut num_lit) {
if Self::is_literal_uuid_formatted(&num_lit) {
return;
}
@ -376,7 +376,7 @@ fn check_for_mistyped_suffix(
///
/// Returns `true` if the radix is hexadecimal, and the groups match the
/// UUID format of 8-4-4-4-12.
fn is_literal_uuid_formatted(num_lit: &mut NumericLiteral<'_>) -> bool {
fn is_literal_uuid_formatted(num_lit: &NumericLiteral<'_>) -> bool {
if num_lit.radix != Radix::Hexadecimal {
return false;
}

View File

@ -1,14 +1,14 @@
use super::utils::make_iterator_snippet;
use super::MANUAL_FIND;
use clippy_utils::{
diagnostics::span_lint_and_then, higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt,
source::snippet_with_applicability, ty::implements_trait,
};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::implements_trait;
use clippy_utils::{higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{
def::Res, lang_items::LangItem, BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind,
};
use rustc_hir::def::Res;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind};
use rustc_lint::LateContext;
use rustc_span::source_map::Span;

View File

@ -1,9 +1,8 @@
use super::utils::make_iterator_snippet;
use super::MANUAL_FLATTEN;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher;
use clippy_utils::visitors::is_local_used;
use clippy_utils::{path_to_local_id, peel_blocks_with_stmt};
use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};

View File

@ -1,9 +1,6 @@
use clippy_utils::{
diagnostics::{multispan_sugg_with_applicability, span_lint_and_then},
match_def_path, paths,
source::snippet,
SpanlessEq,
};
use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::{match_def_path, paths, SpanlessEq};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp};
use rustc_lint::LateContext;

View File

@ -43,7 +43,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
MISSING_SPIN_LOOP,
body.span,
"busy-waiting loop should at least have a spin loop hint",
"try this",
"try",
(if is_no_std_crate(cx) {
"{ core::hint::spin_loop() }"
} else {

View File

@ -601,7 +601,7 @@
/// // use `number`
/// }
/// ```
#[clippy::version = "1.70.0"]
#[clippy::version = "1.71.0"]
pub MANUAL_WHILE_LET_SOME,
style,
"checking for emptiness of a `Vec` in the loop condition and popping an element in the body"

View File

@ -7,7 +7,8 @@
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::{mir::FakeReadCause, ty};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty;
use rustc_span::source_map::Span;
pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) {

View File

@ -1,9 +1,9 @@
use super::utils::make_iterator_snippet;
use super::NEVER_LOOP;
use clippy_utils::consts::constant;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop;
use clippy_utils::source::snippet;
use clippy_utils::{consts::Constant, diagnostics::span_lint_and_then};
use rustc_errors::Applicability;
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
use rustc_lint::LateContext;

View File

@ -6,8 +6,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::HirIdSet;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_hir::{Expr, ExprKind, HirIdSet, QPath};
use rustc_lint::LateContext;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {

View File

@ -1,18 +1,18 @@
use super::WHILE_LET_ON_ITERATOR;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{
get_enclosing_loop_or_multi_call_closure, is_refutable, is_res_lang_ctor, is_trait_method, visitors::is_res_used,
};
use clippy_utils::visitors::is_res_used;
use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable, is_res_lang_ctor, is_trait_method};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp};
use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty::adjustment::Adjust;
use rustc_span::{symbol::sym, Symbol};
use rustc_span::symbol::sym;
use rustc_span::Symbol;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let (scrutinee_expr, iter_expr_struct, iter_expr, some_pat, loop_expr) = if_chain! {
@ -332,7 +332,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if let Some(e) = get_enclosing_loop_or_multi_call_closure(cx, loop_expr) {
let Res::Local(local_id) = iter_expr.path else {
return true
return true;
};
let mut v = NestedLoopVisitor {
cx,

View File

@ -8,7 +8,8 @@
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, sym, Span};
use rustc_span::edition::Edition;
use rustc_span::{sym, Span};
declare_clippy_lint! {
/// ### What it does

View File

@ -4,21 +4,19 @@
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::implements_trait;
use clippy_utils::visitors::is_const_evaluatable;
use clippy_utils::MaybePath;
use clippy_utils::{
eq_expr_value, in_constant, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks,
peel_blocks_with_stmt,
peel_blocks_with_stmt, MaybePath,
};
use itertools::Itertools;
use rustc_errors::Applicability;
use rustc_errors::Diagnostic;
use rustc_hir::{
def::Res, Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind,
};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::def::Res;
use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span};
use rustc_span::symbol::sym;
use rustc_span::Span;
use std::ops::Deref;
declare_clippy_lint! {

View File

@ -0,0 +1,173 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use clippy_utils::{is_from_proc_macro, path_to_local};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// ### What it does
/// Checks for manual `is_infinite` reimplementations
/// (i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`).
///
/// ### Why is this bad?
/// The method `is_infinite` is shorter and more readable.
///
/// ### Example
/// ```rust
/// # let x = 1.0f32;
/// if x == f32::INFINITY || x == f32::NEG_INFINITY {}
/// ```
/// Use instead:
/// ```rust
/// # let x = 1.0f32;
/// if x.is_infinite() {}
/// ```
#[clippy::version = "1.72.0"]
pub MANUAL_IS_INFINITE,
style,
"use dedicated method to check if a float is infinite"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for manual `is_finite` reimplementations
/// (i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`).
///
/// ### Why is this bad?
/// The method `is_finite` is shorter and more readable.
///
/// ### Example
/// ```rust
/// # let x = 1.0f32;
/// if x != f32::INFINITY && x != f32::NEG_INFINITY {}
/// if x.abs() < f32::INFINITY {}
/// ```
/// Use instead:
/// ```rust
/// # let x = 1.0f32;
/// if x.is_finite() {}
/// if x.is_finite() {}
/// ```
#[clippy::version = "1.72.0"]
pub MANUAL_IS_FINITE,
style,
"use dedicated method to check if a float is finite"
}
declare_lint_pass!(ManualFloatMethods => [MANUAL_IS_INFINITE, MANUAL_IS_FINITE]);
#[derive(Clone, Copy)]
enum Variant {
ManualIsInfinite,
ManualIsFinite,
}
impl Variant {
pub fn lint(self) -> &'static Lint {
match self {
Self::ManualIsInfinite => MANUAL_IS_INFINITE,
Self::ManualIsFinite => MANUAL_IS_FINITE,
}
}
pub fn msg(self) -> &'static str {
match self {
Self::ManualIsInfinite => "manually checking if a float is infinite",
Self::ManualIsFinite => "manually checking if a float is finite",
}
}
}
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if !in_external_macro(cx.sess(), expr.span)
&& (!cx.param_env.is_const() || cx.tcx.features().active(sym!(const_float_classify)))
&& let ExprKind::Binary(kind, lhs, rhs) = expr.kind
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
// Checking all possible scenarios using a function would be a hopeless task, as we have
// 16 possible alignments of constants/operands. For now, let's use `partition`.
&& let (operands, constants) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
.into_iter()
.partition::<Vec<&Expr<'_>>, _>(|i| path_to_local(i).is_some())
&& let [first, second] = &*operands
&& let Some([const_1, const_2]) = constants
.into_iter()
.map(|i| constant(cx, cx.typeck_results(), i))
.collect::<Option<Vec<_>>>()
.as_deref()
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
// case somebody does that for some reason
&& (is_infinity(const_1) && is_neg_infinity(const_2)
|| is_neg_infinity(const_1) && is_infinity(const_2))
&& !is_from_proc_macro(cx, expr)
&& let Some(local_snippet) = snippet_opt(cx, first.span)
{
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite,
(BinOpKind::And, BinOpKind::Ne, BinOpKind::Ne) => Variant::ManualIsFinite,
_ => return,
};
span_lint_and_then(
cx,
variant.lint(),
expr.span,
variant.msg(),
|diag| {
match variant {
Variant::ManualIsInfinite => {
diag.span_suggestion(
expr.span,
"use the dedicated method instead",
format!("{local_snippet}.is_infinite()"),
Applicability::MachineApplicable,
);
},
Variant::ManualIsFinite => {
// TODO: There's probably some better way to do this, i.e., create
// multiple suggestions with notes between each of them
diag.span_suggestion_verbose(
expr.span,
"use the dedicated method instead",
format!("{local_snippet}.is_finite()"),
Applicability::MaybeIncorrect,
)
.span_suggestion_verbose(
expr.span,
"this will alter how it handles NaN; if that is a problem, use instead",
format!("{local_snippet}.is_finite() || {local_snippet}.is_nan()"),
Applicability::MaybeIncorrect,
)
.span_suggestion_verbose(
expr.span,
"or, for conciseness",
format!("!{local_snippet}.is_infinite()"),
Applicability::MaybeIncorrect,
);
},
}
},
);
}
}
}
fn is_infinity(constant: &Constant<'_>) -> bool {
match constant {
Constant::F32(float) => *float == f32::INFINITY,
Constant::F64(float) => *float == f64::INFINITY,
_ => false,
}
}
fn is_neg_infinity(constant: &Constant<'_>) -> bool {
match constant {
Constant::F32(float) => *float == f32::NEG_INFINITY,
Constant::F64(float) => *float == f64::NEG_INFINITY,
_ => false,
}
}

View File

@ -1,12 +1,16 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::root_macro_call;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, sugg::Sugg};
use clippy_utils::sugg::Sugg;
use clippy_utils::{higher, in_constant};
use rustc_ast::ast::RangeLimits;
use rustc_ast::LitKind::{Byte, Char};
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, PatKind, RangeEnd};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{def_id::DefId, sym, Span};
use rustc_span::def_id::DefId;
use rustc_span::{sym, Span};
declare_clippy_lint! {
/// ### What it does

View File

@ -1,18 +1,17 @@
use crate::question_mark::{QuestionMark, QUESTION_MARK};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLetOrMatch;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::peel_blocks;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::{Descend, Visitable};
use if_chain::if_chain;
use clippy_utils::{is_lint_allowed, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Expr, ExprKind, HirId, ItemId, Local, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind, Ty};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_session::declare_tool_lint;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use serde::Deserialize;
@ -50,25 +49,8 @@
"manual implementation of a let...else statement"
}
pub struct ManualLetElse {
msrv: Msrv,
matches_behaviour: MatchLintBehaviour,
}
impl ManualLetElse {
#[must_use]
pub fn new(msrv: Msrv, matches_behaviour: MatchLintBehaviour) -> Self {
Self {
msrv,
matches_behaviour,
}
}
}
impl_lint_pass!(ManualLetElse => [MANUAL_LET_ELSE]);
impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
impl<'tcx> QuestionMark {
pub(crate) fn check_manual_let_else(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
if !self.msrv.meets(msrvs::LET_ELSE) || in_external_macro(cx.sess(), stmt.span) {
return;
}
@ -81,11 +63,14 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
{
match if_let_or_match {
IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => if_chain! {
if let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then);
if let Some(if_else) = if_else;
if expr_diverges(cx, if_else);
then {
IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => {
if
let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then) &&
let Some(if_else) = if_else &&
expr_diverges(cx, if_else) &&
let qm_allowed = is_lint_allowed(cx, QUESTION_MARK, stmt.hir_id) &&
(qm_allowed || pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none())
{
emit_manual_let_else(cx, stmt.span, if_let_expr, &ident_map, let_pat, if_else);
}
},
@ -128,8 +113,6 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
}
};
}
extract_msrv_attr!(LateContext);
}
fn emit_manual_let_else(
@ -208,7 +191,9 @@ fn replace_in_pattern(
match pat.kind {
PatKind::Binding(_ann, _id, binding_name, opt_subpt) => {
let Some(pat_to_put) = ident_map.get(&binding_name.name) else { break 'a };
let Some(pat_to_put) = ident_map.get(&binding_name.name) else {
break 'a;
};
let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
if let Some(subpt) = opt_subpt {
let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);

View File

@ -2,12 +2,8 @@
use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_hir::ExprKind;
use rustc_hir::PatKind;
use rustc_hir::RangeEnd;
use rustc_lint::LintContext;
use rustc_lint::{LateContext, LateLintPass};
use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd, UnOp};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -19,6 +15,10 @@
/// ### Why is this bad?
/// Using an explicit range is more concise and easier to read.
///
/// ### Known issues
/// This lint intentionally does not handle numbers greater than `i128::MAX` for `u128` literals
/// in order to support negative numbers.
///
/// ### Example
/// ```rust
/// let x = 6;
@ -36,11 +36,14 @@
}
declare_lint_pass!(ManualRangePatterns => [MANUAL_RANGE_PATTERNS]);
fn expr_as_u128(expr: &Expr<'_>) -> Option<u128> {
if let ExprKind::Lit(lit) = expr.kind
fn expr_as_i128(expr: &Expr<'_>) -> Option<i128> {
if let ExprKind::Unary(UnOp::Neg, expr) = expr.kind {
expr_as_i128(expr).map(|num| -num)
} else if let ExprKind::Lit(lit) = expr.kind
&& let LitKind::Int(num, _) = lit.node
{
Some(num)
// Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now.
num.try_into().ok()
} else {
None
}
@ -56,22 +59,22 @@ fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) {
if let PatKind::Or(pats) = pat.kind
&& pats.len() >= 3
{
let mut min = u128::MAX;
let mut max = 0;
let mut min = i128::MAX;
let mut max = i128::MIN;
let mut numbers_found = FxHashSet::default();
let mut ranges_found = Vec::new();
for pat in pats {
if let PatKind::Lit(lit) = pat.kind
&& let Some(num) = expr_as_u128(lit)
&& let Some(num) = expr_as_i128(lit)
{
numbers_found.insert(num);
min = min.min(num);
max = max.max(num);
} else if let PatKind::Range(Some(left), Some(right), end) = pat.kind
&& let Some(left) = expr_as_u128(left)
&& let Some(right) = expr_as_u128(right)
&& let Some(left) = expr_as_i128(left)
&& let Some(right) = expr_as_i128(right)
&& right >= left
{
min = min.min(left);

View File

@ -119,7 +119,7 @@ fn check_for_either_unsigned_int_constant<'a>(
}
fn check_for_unsigned_int_constant<'a>(cx: &'a LateContext<'_>, expr: &'a Expr<'_>) -> Option<u128> {
let Some(int_const) = constant_full_int(cx, cx.typeck_results(), expr) else { return None };
let int_const = constant_full_int(cx, cx.typeck_results(), expr)?;
match int_const {
FullInt::S(s) => s.try_into().ok(),
FullInt::U(u) => Some(u),

View File

@ -8,8 +8,7 @@
use rustc_ast::ast::LitKind;
use rustc_hir::def::Res;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::BinOpKind;
use rustc_hir::{BorrowKind, Expr, ExprKind};
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};

View File

@ -226,7 +226,7 @@ fn lint_map_unit_fn(
);
span_lint_and_then(cx, lint, expr.span, &msg, |diag| {
diag.span_suggestion(stmt.span, "try this", suggestion, applicability);
diag.span_suggestion(stmt.span, "try", suggestion, applicability);
});
} else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) {
let msg = suggestion_msg("closure", map_type);
@ -241,7 +241,7 @@ fn lint_map_unit_fn(
snippet_with_applicability(cx, var_arg.span, "_", &mut applicability),
snippet_with_context(cx, reduced_expr_span, var_arg.span.ctxt(), "_", &mut applicability).0,
);
diag.span_suggestion(stmt.span, "try this", suggestion, applicability);
diag.span_suggestion(stmt.span, "try", suggestion, applicability);
} else {
let suggestion = format!(
"if let {0}({1}) = {2} {{ ... }}",
@ -249,7 +249,7 @@ fn lint_map_unit_fn(
snippet(cx, binding.pat.span, "_"),
snippet(cx, var_arg.span, "_"),
);
diag.span_suggestion(stmt.span, "try this", suggestion, Applicability::HasPlaceholders);
diag.span_suggestion(stmt.span, "try", suggestion, Applicability::HasPlaceholders);
}
});
}

View File

@ -1,8 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
use clippy_utils::is_res_lang_ctor;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{higher, is_res_lang_ctor};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, PatKind};

View File

@ -28,7 +28,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
local.span,
"you seem to be trying to use `match` to destructure a single infallible pattern. \
Consider using `let`",
"try this",
"try",
format!(
"let {}({}{}) = {};",
snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),

View File

@ -143,7 +143,7 @@ fn check<'tcx>(
MANUAL_FILTER,
expr.span,
"manual implementation of `Option::filter`",
"try this",
"try",
if sugg_info.needs_brackets {
format!(
"{{ {}{}.filter({body_str}) }}",

Some files were not shown because too many files have changed in this diff Show More