Merge commit 'd9c24d1b1ee61f276e550b967409c9f155eac4e3' into clippyup
This commit is contained in:
parent
fdb2e363d3
commit
d6d530fd0b
2
.github/workflows/clippy.yml
vendored
2
.github/workflows/clippy.yml
vendored
@ -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
|
||||
|
2
.github/workflows/clippy_bors.yml
vendored
2
.github/workflows/clippy_bors.yml
vendored
@ -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'
|
||||
|
180
CHANGELOG.md
180
CHANGELOG.md
@ -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
|
||||
|
13
Cargo.toml
13
Cargo.toml
@ -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"
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
24
book/src/development/speedtest.md
Normal file
24
book/src/development/speedtest.md
Normal 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.
|
@ -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>`)
|
||||
|
@ -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!();
|
||||
}}
|
||||
"#
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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"
|
||||
|
@ -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};
|
||||
|
@ -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`");
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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! {
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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],
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)?;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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`"
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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! {
|
||||
|
@ -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"),
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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, it’s 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`
|
||||
}
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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<'_>) {
|
||||
|
@ -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;
|
||||
|
@ -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<'_>) {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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! {
|
||||
|
173
clippy_lints/src/manual_float_methods.rs
Normal file
173
clippy_lints/src/manual_float_methods.rs
Normal 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,
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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};
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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),
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user