Merge commit 'a5d597637d
' into clippyup
This commit is contained in:
parent
35a0060aba
commit
8fea1d94f3
491 changed files with 9888 additions and 3255 deletions
18
.github/ISSUE_TEMPLATE/blank_issue.md
vendored
18
.github/ISSUE_TEMPLATE/blank_issue.md
vendored
|
@ -1,18 +0,0 @@
|
||||||
---
|
|
||||||
name: Blank Issue
|
|
||||||
about: Create a blank issue.
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Additional labels can be added to this issue by including the following command
|
|
||||||
(without the space after the @ symbol):
|
|
||||||
|
|
||||||
@ rustbot label +<label>
|
|
||||||
|
|
||||||
Common labels for this issue type are:
|
|
||||||
* C-an-interesting-project
|
|
||||||
* C-enhancement
|
|
||||||
* C-question
|
|
||||||
* C-tracking-issue
|
|
||||||
-->
|
|
44
.github/ISSUE_TEMPLATE/blank_issue.yml
vendored
Normal file
44
.github/ISSUE_TEMPLATE/blank_issue.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
name: Blank Issue
|
||||||
|
description: Create a blank issue.
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for filing an issue!
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: >
|
||||||
|
Please provide a discription of the issue, along with any information
|
||||||
|
you feel relevant to replicate it.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: "Rust version (`rustc -Vv`)"
|
||||||
|
placeholder: |
|
||||||
|
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
||||||
|
commit-date: 2020-06-20
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.46.0-nightly
|
||||||
|
LLVM version: 10.0
|
||||||
|
render: text
|
||||||
|
- type: textarea
|
||||||
|
id: labels
|
||||||
|
attributes:
|
||||||
|
label: Additional Labels
|
||||||
|
description: >
|
||||||
|
Additional labels can be added to this issue by including the following
|
||||||
|
command
|
||||||
|
placeholder: |
|
||||||
|
@rustbot label +<label>
|
||||||
|
|
||||||
|
Common labels for this issue type are:
|
||||||
|
* C-an-interesting-project
|
||||||
|
* C-enhancement
|
||||||
|
* C-question
|
||||||
|
* C-tracking-issue
|
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug Report
|
|
||||||
about: Create a bug report for Clippy
|
|
||||||
labels: C-bug
|
|
||||||
---
|
|
||||||
<!--
|
|
||||||
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
|
|
||||||
along with any information you feel relevant to replicating the bug.
|
|
||||||
-->
|
|
||||||
|
|
||||||
I tried this code:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
I expected to see this happen: *explanation*
|
|
||||||
|
|
||||||
Instead, this happened: *explanation*
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
|
|
||||||
**Rust version (`rustc -Vv`):**
|
|
||||||
|
|
||||||
```
|
|
||||||
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
|
||||||
binary: rustc
|
|
||||||
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
|
||||||
commit-date: 2020-06-20
|
|
||||||
host: x86_64-unknown-linux-gnu
|
|
||||||
release: 1.46.0-nightly
|
|
||||||
LLVM version: 10.0
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Additional labels can be added to this issue by including the following command
|
|
||||||
(without the space after the @ symbol):
|
|
||||||
|
|
||||||
@ rustbot label +<label>
|
|
||||||
|
|
||||||
Common labels for this issue type are:
|
|
||||||
* `I-suggestion-causes-error`
|
|
||||||
-->
|
|
57
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
57
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
name: Bug Report
|
||||||
|
description: Create a bug report for Clippy
|
||||||
|
labels: ["C-bug"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for filing a bug report! 🐛
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
description: >
|
||||||
|
Please provide a short summary of the bug, along with any information
|
||||||
|
you feel relevant to replicate the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproducer
|
||||||
|
attributes:
|
||||||
|
label: Reproducer
|
||||||
|
description: Please provide the code and steps to repoduce the bug
|
||||||
|
value: |
|
||||||
|
I tried this code:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
<code>
|
||||||
|
```
|
||||||
|
|
||||||
|
I expected to see this happen:
|
||||||
|
|
||||||
|
Instead, this happened:
|
||||||
|
- type: textarea
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: "Rust version (`rustc -Vv`)"
|
||||||
|
placeholder: |
|
||||||
|
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
||||||
|
commit-date: 2020-06-20
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.46.0-nightly
|
||||||
|
LLVM version: 10.0
|
||||||
|
render: text
|
||||||
|
- type: textarea
|
||||||
|
id: labels
|
||||||
|
attributes:
|
||||||
|
label: Additional Labels
|
||||||
|
description: >
|
||||||
|
Additional labels can be added to this issue by including the following
|
||||||
|
command
|
||||||
|
placeholder: |
|
||||||
|
@rustbot label +<label>
|
||||||
|
|
||||||
|
Common labels for this issue type are:
|
||||||
|
* `I-suggestion-causes-error`
|
35
.github/ISSUE_TEMPLATE/false_negative.md
vendored
35
.github/ISSUE_TEMPLATE/false_negative.md
vendored
|
@ -1,35 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug Report (False Negative)
|
|
||||||
about: Create a bug report about missing warnings from a lint
|
|
||||||
labels: C-bug, I-false-negative
|
|
||||||
---
|
|
||||||
<!--
|
|
||||||
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
|
|
||||||
along with any information you feel relevant to replicating the bug.
|
|
||||||
-->
|
|
||||||
Lint name:
|
|
||||||
|
|
||||||
|
|
||||||
I tried this code:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
I expected to see this happen: *explanation*
|
|
||||||
|
|
||||||
Instead, this happened: *explanation*
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
|
|
||||||
**Rust version (`rustc -Vv`):**
|
|
||||||
|
|
||||||
```
|
|
||||||
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
|
||||||
binary: rustc
|
|
||||||
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
|
||||||
commit-date: 2020-06-20
|
|
||||||
host: x86_64-unknown-linux-gnu
|
|
||||||
release: 1.46.0-nightly
|
|
||||||
LLVM version: 10.0
|
|
||||||
```
|
|
50
.github/ISSUE_TEMPLATE/false_negative.yml
vendored
Normal file
50
.github/ISSUE_TEMPLATE/false_negative.yml
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
name: Bug Report (False Negative)
|
||||||
|
description: Create a bug report about missing warnings from a lint
|
||||||
|
labels: ["C-bug", "I-false-negative"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for filing a bug report! 🐛
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
description: >
|
||||||
|
Please provide a short summary of the bug, along with any information
|
||||||
|
you feel relevant to replicate the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: lint-name
|
||||||
|
attributes:
|
||||||
|
label: Lint Name
|
||||||
|
description: Please provide the lint name.
|
||||||
|
- type: textarea
|
||||||
|
id: reproducer
|
||||||
|
attributes:
|
||||||
|
label: Reproducer
|
||||||
|
description: Please provide the code and steps to repoduce the bug
|
||||||
|
value: |
|
||||||
|
I tried this code:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
<code>
|
||||||
|
```
|
||||||
|
|
||||||
|
I expected to see this happen:
|
||||||
|
|
||||||
|
Instead, this happened:
|
||||||
|
- type: textarea
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: "Rust version (`rustc -Vv`)"
|
||||||
|
placeholder: |
|
||||||
|
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
||||||
|
commit-date: 2020-06-20
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.46.0-nightly
|
||||||
|
LLVM version: 10.0
|
||||||
|
render: text
|
44
.github/ISSUE_TEMPLATE/false_positive.md
vendored
44
.github/ISSUE_TEMPLATE/false_positive.md
vendored
|
@ -1,44 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug Report (False Positive)
|
|
||||||
about: Create a bug report about a wrongly emitted lint warning
|
|
||||||
labels: C-bug, I-false-positive
|
|
||||||
---
|
|
||||||
<!--
|
|
||||||
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
|
|
||||||
along with any information you feel relevant to replicating the bug.
|
|
||||||
-->
|
|
||||||
Lint name:
|
|
||||||
|
|
||||||
|
|
||||||
I tried this code:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
I expected to see this happen: *explanation*
|
|
||||||
|
|
||||||
Instead, this happened: *explanation*
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
|
|
||||||
**Rust version (`rustc -Vv`):**
|
|
||||||
```
|
|
||||||
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
|
||||||
binary: rustc
|
|
||||||
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
|
||||||
commit-date: 2020-06-20
|
|
||||||
host: x86_64-unknown-linux-gnu
|
|
||||||
release: 1.46.0-nightly
|
|
||||||
LLVM version: 10.0
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Additional labels can be added to this issue by including the following command
|
|
||||||
(without the space after the @ symbol):
|
|
||||||
|
|
||||||
@ rustbot label +<label>
|
|
||||||
|
|
||||||
Common labels for this issue type are:
|
|
||||||
* I-suggestion-causes-error
|
|
||||||
-->
|
|
68
.github/ISSUE_TEMPLATE/false_positive.yml
vendored
Normal file
68
.github/ISSUE_TEMPLATE/false_positive.yml
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
name: Bug Report (False Positive)
|
||||||
|
description: Create a bug report about a wrongly emitted lint warning
|
||||||
|
labels: ["C-bug", "I-false-positive"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for filing a bug report! 🐛
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
description: >
|
||||||
|
Please provide a short summary of the bug, along with any information
|
||||||
|
you feel relevant to replicate the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: lint-name
|
||||||
|
attributes:
|
||||||
|
label: Lint Name
|
||||||
|
description: Please provide the lint name.
|
||||||
|
- type: textarea
|
||||||
|
id: reproducer
|
||||||
|
attributes:
|
||||||
|
label: Reproducer
|
||||||
|
description: >
|
||||||
|
Please provide the code and steps to repoduce the bug together with the
|
||||||
|
output from Clippy.
|
||||||
|
value: |
|
||||||
|
I tried this code:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
<code>
|
||||||
|
```
|
||||||
|
|
||||||
|
I saw this happen:
|
||||||
|
|
||||||
|
```
|
||||||
|
<output>
|
||||||
|
```
|
||||||
|
|
||||||
|
I expected to see this happen:
|
||||||
|
- type: textarea
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: "Rust version (`rustc -Vv`)"
|
||||||
|
placeholder: |
|
||||||
|
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
||||||
|
commit-date: 2020-06-20
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.46.0-nightly
|
||||||
|
LLVM version: 10.0
|
||||||
|
render: text
|
||||||
|
- type: textarea
|
||||||
|
id: labels
|
||||||
|
attributes:
|
||||||
|
label: Additional Labels
|
||||||
|
description: >
|
||||||
|
Additional labels can be added to this issue by including the following
|
||||||
|
command
|
||||||
|
placeholder: |
|
||||||
|
@rustbot label +<label>
|
||||||
|
|
||||||
|
Common labels for this issue type are:
|
||||||
|
* `I-suggestion-causes-error`
|
52
.github/ISSUE_TEMPLATE/ice.md
vendored
52
.github/ISSUE_TEMPLATE/ice.md
vendored
|
@ -1,52 +0,0 @@
|
||||||
---
|
|
||||||
name: Internal Compiler Error
|
|
||||||
about: Create a report for an internal compiler error in Clippy.
|
|
||||||
labels: C-bug, I-ICE
|
|
||||||
---
|
|
||||||
<!--
|
|
||||||
Thank you for finding an Internal Compiler Error! 🧊 If possible, try to provide
|
|
||||||
a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for
|
|
||||||
how to create smaller examples.
|
|
||||||
|
|
||||||
http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Code
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
|
|
||||||
**Rust version (`rustc -Vv`):**
|
|
||||||
```
|
|
||||||
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
|
||||||
binary: rustc
|
|
||||||
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
|
||||||
commit-date: 2020-06-20
|
|
||||||
host: x86_64-unknown-linux-gnu
|
|
||||||
release: 1.46.0-nightly
|
|
||||||
LLVM version: 10.0
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error output
|
|
||||||
|
|
||||||
```
|
|
||||||
<output>
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
|
|
||||||
environment. E.g. `RUST_BACKTRACE=1 cargo clippy`.
|
|
||||||
-->
|
|
||||||
<details><summary>Backtrace</summary>
|
|
||||||
<p>
|
|
||||||
|
|
||||||
```
|
|
||||||
<backtrace>
|
|
||||||
```
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</details>
|
|
48
.github/ISSUE_TEMPLATE/ice.yml
vendored
Normal file
48
.github/ISSUE_TEMPLATE/ice.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
name: Internal Compiler Error
|
||||||
|
description: Create a report for an internal compiler error (ICE) in Clippy.
|
||||||
|
labels: ["C-bug", "I-ICE"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for finding an Internal Compiler Error! 🧊
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
description: |
|
||||||
|
If possible, try to provide a minimal verifiable example. You can read ["Rust Bug Minimization Patterns"][mve] for how to create smaller examples. Otherwise, provide the crate where the ICE occured.
|
||||||
|
|
||||||
|
[mve]: http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: "Rust version (`rustc -Vv`)"
|
||||||
|
placeholder: |
|
||||||
|
rustc 1.46.0-nightly (f455e46ea 2020-06-20)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f455e46eae1a227d735091091144601b467e1565
|
||||||
|
commit-date: 2020-06-20
|
||||||
|
host: x86_64-unknown-linux-gnu
|
||||||
|
release: 1.46.0-nightly
|
||||||
|
LLVM version: 10.0
|
||||||
|
render: text
|
||||||
|
- type: textarea
|
||||||
|
id: error
|
||||||
|
attributes:
|
||||||
|
label: Error output
|
||||||
|
description: >
|
||||||
|
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in
|
||||||
|
your environment. E.g. `RUST_BACKTRACE=1 cargo clippy`.
|
||||||
|
value: |
|
||||||
|
<details><summary>Backtrace</summary>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
```
|
||||||
|
<backtrace>
|
||||||
|
```
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
36
.github/ISSUE_TEMPLATE/new_lint.md
vendored
36
.github/ISSUE_TEMPLATE/new_lint.md
vendored
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
name: New lint suggestion
|
|
||||||
about: Suggest a new Clippy lint.
|
|
||||||
labels: A-lint
|
|
||||||
---
|
|
||||||
|
|
||||||
### What it does
|
|
||||||
|
|
||||||
*What does this lint do?*
|
|
||||||
|
|
||||||
### Categories (optional)
|
|
||||||
|
|
||||||
- Kind: *See <https://github.com/rust-lang/rust-clippy/blob/master/README.md#clippy> for list of lint kinds*
|
|
||||||
|
|
||||||
*What is the advantage of the recommended code over the original code*
|
|
||||||
|
|
||||||
For example:
|
|
||||||
- Remove bounds check inserted by ...
|
|
||||||
- Remove the need to duplicate/store ...
|
|
||||||
- Remove typo ...
|
|
||||||
|
|
||||||
### Drawbacks
|
|
||||||
|
|
||||||
None.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
Could be written as:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
<code>
|
|
||||||
```
|
|
71
.github/ISSUE_TEMPLATE/new_lint.yml
vendored
Normal file
71
.github/ISSUE_TEMPLATE/new_lint.yml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: New lint suggestion
|
||||||
|
description: Suggest a new Clippy lint.
|
||||||
|
labels: ["A-lint"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thank you for your lint idea!
|
||||||
|
- type: textarea
|
||||||
|
id: what
|
||||||
|
attributes:
|
||||||
|
label: What it does
|
||||||
|
description: What does this lint do?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: lint-name
|
||||||
|
attributes:
|
||||||
|
label: Lint Name
|
||||||
|
description: Please provide the lint name.
|
||||||
|
- type: dropdown
|
||||||
|
id: category
|
||||||
|
attributes:
|
||||||
|
label: Category
|
||||||
|
description: >
|
||||||
|
What category should this lint go into? If you're unsure you can select
|
||||||
|
multiple categories. You can find a category description in the
|
||||||
|
`README`.
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- correctness
|
||||||
|
- suspicious
|
||||||
|
- style
|
||||||
|
- complexity
|
||||||
|
- perf
|
||||||
|
- pedantic
|
||||||
|
- restriction
|
||||||
|
- cargo
|
||||||
|
- type: textarea
|
||||||
|
id: advantage
|
||||||
|
attributes:
|
||||||
|
label: Advantage
|
||||||
|
description: >
|
||||||
|
What is the advantage of the recommended code over the original code?
|
||||||
|
placeholder: |
|
||||||
|
- Remove bounds check inserted by ...
|
||||||
|
- Remove the need to duplicate/store ...
|
||||||
|
- Remove typo ...
|
||||||
|
- type: textarea
|
||||||
|
id: drawbacks
|
||||||
|
attributes:
|
||||||
|
label: Drawbacks
|
||||||
|
description: What might be possible drawbacks of such a lint?
|
||||||
|
- type: textarea
|
||||||
|
id: example
|
||||||
|
attributes:
|
||||||
|
label: Example
|
||||||
|
description: >
|
||||||
|
Include a short example showing when the lint should trigger together
|
||||||
|
with the improved code.
|
||||||
|
value: |
|
||||||
|
```rust
|
||||||
|
<code>
|
||||||
|
```
|
||||||
|
|
||||||
|
Could be written as:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
<code>
|
||||||
|
```
|
||||||
|
validations:
|
||||||
|
required: true
|
12
.github/workflows/clippy_dev.yml
vendored
12
.github/workflows/clippy_dev.yml
vendored
|
@ -25,18 +25,6 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2.3.3
|
uses: actions/checkout@v2.3.3
|
||||||
|
|
||||||
- name: remove toolchain file
|
|
||||||
run: rm rust-toolchain
|
|
||||||
|
|
||||||
- name: rust-toolchain
|
|
||||||
uses: actions-rs/toolchain@v1.0.6
|
|
||||||
with:
|
|
||||||
toolchain: nightly
|
|
||||||
target: x86_64-unknown-linux-gnu
|
|
||||||
profile: minimal
|
|
||||||
components: rustfmt
|
|
||||||
default: true
|
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --features deny-warnings
|
run: cargo build --features deny-warnings
|
||||||
|
|
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -70,7 +70,7 @@ Current beta, release 2021-12-02
|
||||||
[#7560](https://github.com/rust-lang/rust-clippy/pull/7560)
|
[#7560](https://github.com/rust-lang/rust-clippy/pull/7560)
|
||||||
* [`unnecessary_unwrap`]: Now also checks for `expect`s
|
* [`unnecessary_unwrap`]: Now also checks for `expect`s
|
||||||
[#7584](https://github.com/rust-lang/rust-clippy/pull/7584)
|
[#7584](https://github.com/rust-lang/rust-clippy/pull/7584)
|
||||||
* [`disallowed_method`]: Allow adding a reason that will be displayed with the
|
* [`disallowed_methods`]: Allow adding a reason that will be displayed with the
|
||||||
lint message
|
lint message
|
||||||
[#7621](https://github.com/rust-lang/rust-clippy/pull/7621)
|
[#7621](https://github.com/rust-lang/rust-clippy/pull/7621)
|
||||||
* [`approx_constant`]: Now checks the MSRV for `LOG10_2` and `LOG2_10`
|
* [`approx_constant`]: Now checks the MSRV for `LOG10_2` and `LOG2_10`
|
||||||
|
@ -174,7 +174,7 @@ Current stable, released 2021-10-21
|
||||||
|
|
||||||
* [`needless_continue`]: Now also lints in `loop { continue; }` case
|
* [`needless_continue`]: Now also lints in `loop { continue; }` case
|
||||||
[#7477](https://github.com/rust-lang/rust-clippy/pull/7477)
|
[#7477](https://github.com/rust-lang/rust-clippy/pull/7477)
|
||||||
* [`disallowed_type`]: Now also primitive types can be disallowed
|
* [`disallowed_types`]: Now also primitive types can be disallowed
|
||||||
[#7488](https://github.com/rust-lang/rust-clippy/pull/7488)
|
[#7488](https://github.com/rust-lang/rust-clippy/pull/7488)
|
||||||
* [`manual_swap`]: Now also lints on xor swaps
|
* [`manual_swap`]: Now also lints on xor swaps
|
||||||
[#7506](https://github.com/rust-lang/rust-clippy/pull/7506)
|
[#7506](https://github.com/rust-lang/rust-clippy/pull/7506)
|
||||||
|
@ -248,7 +248,7 @@ Released 2021-09-09
|
||||||
[#7403](https://github.com/rust-lang/rust-clippy/pull/7403)
|
[#7403](https://github.com/rust-lang/rust-clippy/pull/7403)
|
||||||
* [`disallowed_script_idents`]
|
* [`disallowed_script_idents`]
|
||||||
[#7400](https://github.com/rust-lang/rust-clippy/pull/7400)
|
[#7400](https://github.com/rust-lang/rust-clippy/pull/7400)
|
||||||
* [`disallowed_type`]
|
* [`disallowed_types`]
|
||||||
[#7315](https://github.com/rust-lang/rust-clippy/pull/7315)
|
[#7315](https://github.com/rust-lang/rust-clippy/pull/7315)
|
||||||
* [`missing_enforced_import_renames`]
|
* [`missing_enforced_import_renames`]
|
||||||
[#7300](https://github.com/rust-lang/rust-clippy/pull/7300)
|
[#7300](https://github.com/rust-lang/rust-clippy/pull/7300)
|
||||||
|
@ -294,7 +294,7 @@ Released 2021-09-09
|
||||||
[#7379](https://github.com/rust-lang/rust-clippy/pull/7379)
|
[#7379](https://github.com/rust-lang/rust-clippy/pull/7379)
|
||||||
* [`redundant_closure`]: Suggests `&mut` for `FnMut`
|
* [`redundant_closure`]: Suggests `&mut` for `FnMut`
|
||||||
[#7437](https://github.com/rust-lang/rust-clippy/pull/7437)
|
[#7437](https://github.com/rust-lang/rust-clippy/pull/7437)
|
||||||
* [`disallowed_method`], [`disallowed_type`]: The configuration values `disallowed-method` and `disallowed-type`
|
* [`disallowed_methods`], [`disallowed_types`]: The configuration values `disallowed-method` and `disallowed-type`
|
||||||
no longer require fully qualified paths
|
no longer require fully qualified paths
|
||||||
[#7345](https://github.com/rust-lang/rust-clippy/pull/7345)
|
[#7345](https://github.com/rust-lang/rust-clippy/pull/7345)
|
||||||
* [`zst_offset`]: Fixed lint invocation after it was accidentally suppressed
|
* [`zst_offset`]: Fixed lint invocation after it was accidentally suppressed
|
||||||
|
@ -703,7 +703,7 @@ Released 2021-05-06
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
* [`disallowed_method`]: Now supports functions in addition to methods
|
* [`disallowed_methods`]: Now supports functions in addition to methods
|
||||||
[#6674](https://github.com/rust-lang/rust-clippy/pull/6674)
|
[#6674](https://github.com/rust-lang/rust-clippy/pull/6674)
|
||||||
* [`upper_case_acronyms`]: Added a new configuration `upper-case-acronyms-aggressive` to
|
* [`upper_case_acronyms`]: Added a new configuration `upper-case-acronyms-aggressive` to
|
||||||
trigger the lint if there is more than one uppercase character next to each other
|
trigger the lint if there is more than one uppercase character next to each other
|
||||||
|
@ -1044,7 +1044,7 @@ Released 2020-12-31
|
||||||
|
|
||||||
* [`field_reassign_with_default`] [#5911](https://github.com/rust-lang/rust-clippy/pull/5911)
|
* [`field_reassign_with_default`] [#5911](https://github.com/rust-lang/rust-clippy/pull/5911)
|
||||||
* [`await_holding_refcell_ref`] [#6029](https://github.com/rust-lang/rust-clippy/pull/6029)
|
* [`await_holding_refcell_ref`] [#6029](https://github.com/rust-lang/rust-clippy/pull/6029)
|
||||||
* [`disallowed_method`] [#6081](https://github.com/rust-lang/rust-clippy/pull/6081)
|
* [`disallowed_methods`] [#6081](https://github.com/rust-lang/rust-clippy/pull/6081)
|
||||||
* [`inline_asm_x86_att_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
|
* [`inline_asm_x86_att_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
|
||||||
* [`inline_asm_x86_intel_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
|
* [`inline_asm_x86_intel_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)
|
||||||
* [`from_iter_instead_of_collect`] [#6101](https://github.com/rust-lang/rust-clippy/pull/6101)
|
* [`from_iter_instead_of_collect`] [#6101](https://github.com/rust-lang/rust-clippy/pull/6101)
|
||||||
|
@ -2821,9 +2821,9 @@ Released 2018-09-13
|
||||||
[`derivable_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls
|
[`derivable_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls
|
||||||
[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
|
[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
|
||||||
[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
|
[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
|
||||||
[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
|
[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods
|
||||||
[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents
|
[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents
|
||||||
[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
|
[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types
|
||||||
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
|
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
|
||||||
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
|
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
|
||||||
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
|
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
|
||||||
|
@ -2904,6 +2904,7 @@ Released 2018-09-13
|
||||||
[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
|
[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
|
||||||
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
|
[`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
|
[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
|
||||||
|
[`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
|
[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
|
||||||
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
|
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
|
||||||
[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string
|
[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string
|
||||||
|
@ -3032,12 +3033,14 @@ Released 2018-09-13
|
||||||
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
|
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
|
||||||
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
|
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
|
||||||
[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each
|
[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each
|
||||||
|
[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
|
||||||
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
|
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
|
||||||
[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref
|
[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref
|
||||||
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
|
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
|
||||||
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
|
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
|
||||||
[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
|
[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
|
||||||
[`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
|
[`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
|
||||||
|
[`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn
|
||||||
[`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update
|
[`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update
|
||||||
[`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord
|
[`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord
|
||||||
[`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply
|
[`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply
|
||||||
|
@ -3054,6 +3057,7 @@ Released 2018-09-13
|
||||||
[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
|
[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
|
||||||
[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
|
[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
|
||||||
[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
|
[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
|
||||||
|
[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/master/index.html#octal_escapes
|
||||||
[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
|
[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
|
||||||
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
|
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
|
||||||
[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref
|
[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.1.58"
|
version = "0.1.59"
|
||||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||||
repository = "https://github.com/rust-lang/rust-clippy"
|
repository = "https://github.com/rust-lang/rust-clippy"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -47,6 +47,7 @@ itertools = "0.10"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
syn = { version = "1.0", features = ["full"] }
|
syn = { version = "1.0", features = ["full"] }
|
||||||
|
parking_lot = "0.11.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
|
rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
|
||||||
|
|
|
@ -12,6 +12,7 @@ opener = "0.5"
|
||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
shell-escape = "0.1"
|
shell-escape = "0.1"
|
||||||
walkdir = "2.3"
|
walkdir = "2.3"
|
||||||
|
cargo_metadata = "0.14"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
deny-warnings = []
|
deny-warnings = []
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::clippy_project_root;
|
use crate::clippy_project_root;
|
||||||
|
use itertools::Itertools;
|
||||||
use shell_escape::escape;
|
use shell_escape::escape;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::{self, Command};
|
use std::process::{self, Command};
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
@ -56,15 +57,22 @@ pub fn run(check: bool, verbose: bool) {
|
||||||
success &= cargo_fmt(context, &project_root.join("rustc_tools_util"))?;
|
success &= cargo_fmt(context, &project_root.join("rustc_tools_util"))?;
|
||||||
success &= cargo_fmt(context, &project_root.join("lintcheck"))?;
|
success &= cargo_fmt(context, &project_root.join("lintcheck"))?;
|
||||||
|
|
||||||
for entry in WalkDir::new(project_root.join("tests")) {
|
let chunks = WalkDir::new(project_root.join("tests"))
|
||||||
let entry = entry?;
|
.into_iter()
|
||||||
let path = entry.path();
|
.filter_map(|entry| {
|
||||||
|
let entry = entry.expect("failed to find tests");
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
if path.extension() != Some("rs".as_ref()) || entry.file_name() == "ice-3891.rs" {
|
if path.extension() != Some("rs".as_ref()) || entry.file_name() == "ice-3891.rs" {
|
||||||
continue;
|
None
|
||||||
}
|
} else {
|
||||||
|
Some(entry.into_path().into_os_string())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chunks(250);
|
||||||
|
|
||||||
success &= rustfmt(context, path)?;
|
for chunk in &chunks {
|
||||||
|
success &= rustfmt(context, chunk)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(success)
|
Ok(success)
|
||||||
|
@ -149,7 +157,7 @@ fn exec(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cargo_fmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
|
fn cargo_fmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
|
||||||
let mut args = vec!["+nightly", "fmt", "--all"];
|
let mut args = vec!["fmt", "--all"];
|
||||||
if context.check {
|
if context.check {
|
||||||
args.push("--");
|
args.push("--");
|
||||||
args.push("--check");
|
args.push("--check");
|
||||||
|
@ -162,7 +170,7 @@ fn cargo_fmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
|
||||||
fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
|
fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
|
||||||
let program = "rustfmt";
|
let program = "rustfmt";
|
||||||
let dir = std::env::current_dir()?;
|
let dir = std::env::current_dir()?;
|
||||||
let args = &["+nightly", "--version"];
|
let args = &["--version"];
|
||||||
|
|
||||||
if context.verbose {
|
if context.verbose {
|
||||||
println!("{}", format_command(&program, &dir, args));
|
println!("{}", format_command(&program, &dir, args));
|
||||||
|
@ -185,14 +193,14 @@ fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rustfmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
|
fn rustfmt(context: &FmtContext, paths: impl Iterator<Item = OsString>) -> Result<bool, CliError> {
|
||||||
let mut args = vec!["+nightly".as_ref(), path.as_os_str()];
|
let mut args = Vec::new();
|
||||||
if context.check {
|
if context.check {
|
||||||
args.push("--check".as_ref());
|
args.push(OsString::from("--check"));
|
||||||
}
|
}
|
||||||
|
args.extend(paths);
|
||||||
|
|
||||||
let success = exec(context, "rustfmt", std::env::current_dir()?, &args)?;
|
let success = exec(context, "rustfmt", std::env::current_dir()?, &args)?;
|
||||||
if !success {
|
|
||||||
eprintln!("rustfmt failed on {}", path.display());
|
|
||||||
}
|
|
||||||
Ok(success)
|
Ok(success)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
pub mod bless;
|
pub mod bless;
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
|
pub mod lint;
|
||||||
pub mod new_lint;
|
pub mod new_lint;
|
||||||
pub mod serve;
|
pub mod serve;
|
||||||
pub mod setup;
|
pub mod setup;
|
||||||
|
|
20
clippy_dev/src/lint.rs
Normal file
20
clippy_dev/src/lint.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use std::process::{self, Command};
|
||||||
|
|
||||||
|
pub fn run(filename: &str) {
|
||||||
|
let code = Command::new("cargo")
|
||||||
|
.args(["run", "--bin", "clippy-driver", "--"])
|
||||||
|
.args(["-L", "./target/debug"])
|
||||||
|
.args(["-Z", "no-codegen"])
|
||||||
|
.args(["--edition", "2021"])
|
||||||
|
.arg(filename)
|
||||||
|
.env("__CLIPPY_INTERNAL_TESTS", "true")
|
||||||
|
.status()
|
||||||
|
.expect("failed to run cargo")
|
||||||
|
.code();
|
||||||
|
|
||||||
|
if code.is_none() {
|
||||||
|
eprintln!("Killed by signal");
|
||||||
|
}
|
||||||
|
|
||||||
|
process::exit(code.unwrap_or(1));
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||||
|
|
||||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
use clippy_dev::{bless, fmt, new_lint, serve, setup, update_lints};
|
use clippy_dev::{bless, fmt, lint, new_lint, serve, setup, update_lints};
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = get_clap_config();
|
let matches = get_clap_config();
|
||||||
|
|
||||||
|
@ -55,6 +55,10 @@ fn main() {
|
||||||
let lint = matches.value_of("lint");
|
let lint = matches.value_of("lint");
|
||||||
serve::run(port, lint);
|
serve::run(port, lint);
|
||||||
},
|
},
|
||||||
|
("lint", Some(matches)) => {
|
||||||
|
let filename = matches.value_of("filename").unwrap();
|
||||||
|
lint::run(filename);
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,5 +223,14 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
|
||||||
)
|
)
|
||||||
.arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
|
.arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("lint")
|
||||||
|
.about("Manually run clippy on a file")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("filename")
|
||||||
|
.required(true)
|
||||||
|
.help("The path to a file to lint"),
|
||||||
|
),
|
||||||
|
)
|
||||||
.get_matches()
|
.get_matches()
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,18 @@ fn to_camel_case(name: &str) -> String {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_stabilisation_version() -> String {
|
||||||
|
let mut command = cargo_metadata::MetadataCommand::new();
|
||||||
|
command.no_deps();
|
||||||
|
if let Ok(metadata) = command.exec() {
|
||||||
|
if let Some(pkg) = metadata.packages.iter().find(|pkg| pkg.name == "clippy") {
|
||||||
|
return format!("{}.{}.0", pkg.version.minor, pkg.version.patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String::from("<TODO set version(see doc/adding_lints.md)>")
|
||||||
|
}
|
||||||
|
|
||||||
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
|
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
|
||||||
let mut contents = format!(
|
let mut contents = format!(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
@ -178,6 +190,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let version = get_stabilisation_version();
|
||||||
let lint_name = lint.name;
|
let lint_name = lint.name;
|
||||||
let category = lint.category;
|
let category = lint.category;
|
||||||
let name_camel = to_camel_case(lint.name);
|
let name_camel = to_camel_case(lint.name);
|
||||||
|
@ -212,7 +225,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
||||||
});
|
});
|
||||||
|
|
||||||
result.push_str(&format!(
|
result.push_str(&format!(
|
||||||
indoc! {"
|
indoc! {r#"
|
||||||
declare_clippy_lint! {{
|
declare_clippy_lint! {{
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
///
|
///
|
||||||
|
@ -226,11 +239,13 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// // example code which does not raise clippy warning
|
/// // example code which does not raise clippy warning
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "{version}"]
|
||||||
pub {name_upper},
|
pub {name_upper},
|
||||||
{category},
|
{category},
|
||||||
\"default lint description\"
|
"default lint description"
|
||||||
}}
|
}}
|
||||||
"},
|
"#},
|
||||||
|
version = version,
|
||||||
name_upper = name_upper,
|
name_upper = name_upper,
|
||||||
category = category,
|
category = category,
|
||||||
));
|
));
|
||||||
|
|
|
@ -18,6 +18,7 @@ static DEC_CLIPPY_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
|
||||||
r#"(?x)
|
r#"(?x)
|
||||||
declare_clippy_lint!\s*[\{(]
|
declare_clippy_lint!\s*[\{(]
|
||||||
(?:\s+///.*)*
|
(?:\s+///.*)*
|
||||||
|
(?:\s*\#\[clippy::version\s*=\s*"[^"]*"\])?
|
||||||
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||||
(?P<cat>[a-z_]+)\s*,\s*
|
(?P<cat>[a-z_]+)\s*,\s*
|
||||||
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||||
|
@ -31,6 +32,7 @@ static DEC_DEPRECATED_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
|
||||||
r#"(?x)
|
r#"(?x)
|
||||||
declare_deprecated_lint!\s*[{(]\s*
|
declare_deprecated_lint!\s*[{(]\s*
|
||||||
(?:\s+///.*)*
|
(?:\s+///.*)*
|
||||||
|
(?:\s*\#\[clippy::version\s*=\s*"[^"]*"\])?
|
||||||
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||||
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||||
"#,
|
"#,
|
||||||
|
@ -495,6 +497,7 @@ fn test_parse_contents() {
|
||||||
let result: Vec<Lint> = parse_contents(
|
let result: Vec<Lint> = parse_contents(
|
||||||
r#"
|
r#"
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
#[clippy::version = "Hello Clippy!"]
|
||||||
pub PTR_ARG,
|
pub PTR_ARG,
|
||||||
style,
|
style,
|
||||||
"really long \
|
"really long \
|
||||||
|
@ -502,6 +505,7 @@ declare_clippy_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_clippy_lint!{
|
declare_clippy_lint!{
|
||||||
|
#[clippy::version = "Test version"]
|
||||||
pub DOC_MARKDOWN,
|
pub DOC_MARKDOWN,
|
||||||
pedantic,
|
pedantic,
|
||||||
"single line"
|
"single line"
|
||||||
|
@ -509,6 +513,7 @@ declare_clippy_lint!{
|
||||||
|
|
||||||
/// some doc comment
|
/// some doc comment
|
||||||
declare_deprecated_lint! {
|
declare_deprecated_lint! {
|
||||||
|
#[clippy::version = "I'm a version"]
|
||||||
pub SHOULD_ASSERT_EQ,
|
pub SHOULD_ASSERT_EQ,
|
||||||
"`assert!()` will be more flexible with RFC 2011"
|
"`assert!()` will be more flexible with RFC 2011"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.1.58"
|
version = "0.1.59"
|
||||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||||
repository = "https://github.com/rust-lang/rust-clippy"
|
repository = "https://github.com/rust-lang/rust-clippy"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
|
@ -36,6 +36,7 @@ declare_clippy_lint! {
|
||||||
/// if vec.len() <= 0 {}
|
/// if vec.len() <= 0 {}
|
||||||
/// if 100 > i32::MAX {}
|
/// if 100 > i32::MAX {}
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ABSURD_EXTREME_COMPARISONS,
|
pub ABSURD_EXTREME_COMPARISONS,
|
||||||
correctness,
|
correctness,
|
||||||
"a comparison with a maximum or minimum value that is always true or false"
|
"a comparison with a maximum or minimum value that is always true or false"
|
||||||
|
|
|
@ -33,6 +33,7 @@ declare_clippy_lint! {
|
||||||
/// let x = std::f32::consts::PI;
|
/// let x = std::f32::consts::PI;
|
||||||
/// let y = std::f64::consts::FRAC_1_PI;
|
/// let y = std::f64::consts::FRAC_1_PI;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub APPROX_CONSTANT,
|
pub APPROX_CONSTANT,
|
||||||
correctness,
|
correctness,
|
||||||
"the approximate of a known float constant (in `std::fXX::consts`)"
|
"the approximate of a known float constant (in `std::fXX::consts`)"
|
||||||
|
|
|
@ -25,6 +25,7 @@ declare_clippy_lint! {
|
||||||
/// # let a = 0;
|
/// # let a = 0;
|
||||||
/// a + 1;
|
/// a + 1;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub INTEGER_ARITHMETIC,
|
pub INTEGER_ARITHMETIC,
|
||||||
restriction,
|
restriction,
|
||||||
"any integer arithmetic expression which could overflow or panic"
|
"any integer arithmetic expression which could overflow or panic"
|
||||||
|
@ -43,6 +44,7 @@ declare_clippy_lint! {
|
||||||
/// # let a = 0.0;
|
/// # let a = 0.0;
|
||||||
/// a + 1.0;
|
/// a + 1.0;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FLOAT_ARITHMETIC,
|
pub FLOAT_ARITHMETIC,
|
||||||
restriction,
|
restriction,
|
||||||
"any floating-point arithmetic statement"
|
"any floating-point arithmetic statement"
|
||||||
|
|
|
@ -38,6 +38,7 @@ declare_clippy_lint! {
|
||||||
/// f(a.try_into().expect("Unexpected u16 overflow in f"));
|
/// f(a.try_into().expect("Unexpected u16 overflow in f"));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
#[clippy::version = "1.41.0"]
|
||||||
pub AS_CONVERSIONS,
|
pub AS_CONVERSIONS,
|
||||||
restriction,
|
restriction,
|
||||||
"using a potentially dangerous silent `as` conversion"
|
"using a potentially dangerous silent `as` conversion"
|
||||||
|
|
|
@ -75,6 +75,7 @@ declare_clippy_lint! {
|
||||||
/// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
|
/// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.49.0"]
|
||||||
pub INLINE_ASM_X86_INTEL_SYNTAX,
|
pub INLINE_ASM_X86_INTEL_SYNTAX,
|
||||||
restriction,
|
restriction,
|
||||||
"prefer AT&T x86 assembly syntax"
|
"prefer AT&T x86 assembly syntax"
|
||||||
|
@ -111,6 +112,7 @@ declare_clippy_lint! {
|
||||||
/// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
|
/// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.49.0"]
|
||||||
pub INLINE_ASM_X86_ATT_SYNTAX,
|
pub INLINE_ASM_X86_ATT_SYNTAX,
|
||||||
restriction,
|
restriction,
|
||||||
"prefer Intel x86 assembly syntax"
|
"prefer Intel x86 assembly syntax"
|
||||||
|
|
|
@ -26,6 +26,7 @@ declare_clippy_lint! {
|
||||||
/// const B: bool = false;
|
/// const B: bool = false;
|
||||||
/// assert!(B)
|
/// assert!(B)
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.34.0"]
|
||||||
pub ASSERTIONS_ON_CONSTANTS,
|
pub ASSERTIONS_ON_CONSTANTS,
|
||||||
style,
|
style,
|
||||||
"`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
|
"`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
|
||||||
|
|
|
@ -34,6 +34,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// a += b;
|
/// a += b;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ASSIGN_OP_PATTERN,
|
pub ASSIGN_OP_PATTERN,
|
||||||
style,
|
style,
|
||||||
"assigning the result of an operation on a variable to that same variable"
|
"assigning the result of an operation on a variable to that same variable"
|
||||||
|
@ -60,6 +61,7 @@ declare_clippy_lint! {
|
||||||
/// // ...
|
/// // ...
|
||||||
/// a += a + b;
|
/// a += a + b;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub MISREFACTORED_ASSIGN_OP,
|
pub MISREFACTORED_ASSIGN_OP,
|
||||||
suspicious,
|
suspicious,
|
||||||
"having a variable on both sides of an assign op"
|
"having a variable on both sides of an assign op"
|
||||||
|
|
|
@ -34,6 +34,7 @@ declare_clippy_lint! {
|
||||||
/// };
|
/// };
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.48.0"]
|
||||||
pub ASYNC_YIELDS_ASYNC,
|
pub ASYNC_YIELDS_ASYNC,
|
||||||
correctness,
|
correctness,
|
||||||
"async blocks that return a type that can be awaited"
|
"async blocks that return a type that can be awaited"
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
//! checks for attributes
|
//! checks for attributes
|
||||||
|
|
||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::match_panic_def_id;
|
use clippy_utils::msrvs;
|
||||||
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
|
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
|
||||||
|
use clippy_utils::{extract_msrv_attr, match_panic_def_id, meets_msrv};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
|
use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -12,7 +13,8 @@ use rustc_hir::{
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_semver::RustcVersion;
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
use rustc_span::symbol::{Symbol, SymbolStr};
|
use rustc_span::symbol::{Symbol, SymbolStr};
|
||||||
|
@ -64,6 +66,7 @@ declare_clippy_lint! {
|
||||||
/// #[inline(always)]
|
/// #[inline(always)]
|
||||||
/// fn not_quite_hot_code(..) { ... }
|
/// fn not_quite_hot_code(..) { ... }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub INLINE_ALWAYS,
|
pub INLINE_ALWAYS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"use of `#[inline(always)]`"
|
"use of `#[inline(always)]`"
|
||||||
|
@ -98,6 +101,7 @@ declare_clippy_lint! {
|
||||||
/// #[macro_use]
|
/// #[macro_use]
|
||||||
/// extern crate baz;
|
/// extern crate baz;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub USELESS_ATTRIBUTE,
|
pub USELESS_ATTRIBUTE,
|
||||||
correctness,
|
correctness,
|
||||||
"use of lint attributes on `extern crate` items"
|
"use of lint attributes on `extern crate` items"
|
||||||
|
@ -117,6 +121,7 @@ declare_clippy_lint! {
|
||||||
/// #[deprecated(since = "forever")]
|
/// #[deprecated(since = "forever")]
|
||||||
/// fn something_else() { /* ... */ }
|
/// fn something_else() { /* ... */ }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DEPRECATED_SEMVER,
|
pub DEPRECATED_SEMVER,
|
||||||
correctness,
|
correctness,
|
||||||
"use of `#[deprecated(since = \"x\")]` where x is not semver"
|
"use of `#[deprecated(since = \"x\")]` where x is not semver"
|
||||||
|
@ -154,6 +159,7 @@ declare_clippy_lint! {
|
||||||
/// #[allow(dead_code)]
|
/// #[allow(dead_code)]
|
||||||
/// fn this_is_fine_too() { }
|
/// fn this_is_fine_too() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||||
nursery,
|
nursery,
|
||||||
"empty line after outer attribute"
|
"empty line after outer attribute"
|
||||||
|
@ -177,6 +183,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![deny(clippy::as_conversions)]
|
/// #![deny(clippy::as_conversions)]
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.47.0"]
|
||||||
pub BLANKET_CLIPPY_RESTRICTION_LINTS,
|
pub BLANKET_CLIPPY_RESTRICTION_LINTS,
|
||||||
suspicious,
|
suspicious,
|
||||||
"enabling the complete restriction group"
|
"enabling the complete restriction group"
|
||||||
|
@ -208,6 +215,7 @@ declare_clippy_lint! {
|
||||||
/// #[rustfmt::skip]
|
/// #[rustfmt::skip]
|
||||||
/// fn main() { }
|
/// fn main() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.32.0"]
|
||||||
pub DEPRECATED_CFG_ATTR,
|
pub DEPRECATED_CFG_ATTR,
|
||||||
complexity,
|
complexity,
|
||||||
"usage of `cfg_attr(rustfmt)` instead of tool attributes"
|
"usage of `cfg_attr(rustfmt)` instead of tool attributes"
|
||||||
|
@ -240,6 +248,7 @@ declare_clippy_lint! {
|
||||||
/// fn conditional() { }
|
/// fn conditional() { }
|
||||||
/// ```
|
/// ```
|
||||||
/// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
|
/// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
|
||||||
|
#[clippy::version = "1.45.0"]
|
||||||
pub MISMATCHED_TARGET_OS,
|
pub MISMATCHED_TARGET_OS,
|
||||||
correctness,
|
correctness,
|
||||||
"usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
|
"usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
|
||||||
|
@ -497,7 +506,11 @@ fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(EarlyAttributes => [
|
pub struct EarlyAttributes {
|
||||||
|
pub msrv: Option<RustcVersion>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_lint_pass!(EarlyAttributes => [
|
||||||
DEPRECATED_CFG_ATTR,
|
DEPRECATED_CFG_ATTR,
|
||||||
MISMATCHED_TARGET_OS,
|
MISMATCHED_TARGET_OS,
|
||||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||||
|
@ -509,9 +522,11 @@ impl EarlyLintPass for EarlyAttributes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
|
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||||
check_deprecated_cfg_attr(cx, attr);
|
check_deprecated_cfg_attr(cx, attr, self.msrv);
|
||||||
check_mismatched_target_os(cx, attr);
|
check_mismatched_target_os(cx, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract_msrv_attr!(EarlyContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
|
fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
|
||||||
|
@ -548,8 +563,9 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) {
|
fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Option<RustcVersion>) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
|
if meets_msrv(msrv.as_ref(), &msrvs::TOOL_ATTRIBUTES);
|
||||||
// check cfg_attr
|
// check cfg_attr
|
||||||
if attr.has_name(sym::cfg_attr);
|
if attr.has_name(sym::cfg_attr);
|
||||||
if let Some(items) = attr.meta_item_list();
|
if let Some(items) = attr.meta_item_list();
|
||||||
|
|
|
@ -47,6 +47,7 @@ declare_clippy_lint! {
|
||||||
/// bar.await;
|
/// bar.await;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.45.0"]
|
||||||
pub AWAIT_HOLDING_LOCK,
|
pub AWAIT_HOLDING_LOCK,
|
||||||
pedantic,
|
pedantic,
|
||||||
"Inside an async function, holding a MutexGuard while calling await"
|
"Inside an async function, holding a MutexGuard while calling await"
|
||||||
|
@ -88,6 +89,7 @@ declare_clippy_lint! {
|
||||||
/// bar.await;
|
/// bar.await;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.49.0"]
|
||||||
pub AWAIT_HOLDING_REFCELL_REF,
|
pub AWAIT_HOLDING_REFCELL_REF,
|
||||||
pedantic,
|
pedantic,
|
||||||
"Inside an async function, holding a RefCell ref while calling await"
|
"Inside an async function, holding a RefCell ref while calling await"
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// # let x = 1;
|
/// # let x = 1;
|
||||||
/// if (x & 1 == 2) { }
|
/// if (x & 1 == 2) { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub BAD_BIT_MASK,
|
pub BAD_BIT_MASK,
|
||||||
correctness,
|
correctness,
|
||||||
"expressions of the form `_ & mask == select` that will only ever return `true` or `false`"
|
"expressions of the form `_ & mask == select` that will only ever return `true` or `false`"
|
||||||
|
@ -73,6 +74,7 @@ declare_clippy_lint! {
|
||||||
/// # let x = 1;
|
/// # let x = 1;
|
||||||
/// if (x | 1 > 3) { }
|
/// if (x | 1 > 3) { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub INEFFECTIVE_BIT_MASK,
|
pub INEFFECTIVE_BIT_MASK,
|
||||||
correctness,
|
correctness,
|
||||||
"expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`"
|
"expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`"
|
||||||
|
@ -95,6 +97,7 @@ declare_clippy_lint! {
|
||||||
/// # let x = 1;
|
/// # let x = 1;
|
||||||
/// if x & 0b1111 == 0 { }
|
/// if x & 0b1111 == 0 { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub VERBOSE_BIT_MASK,
|
pub VERBOSE_BIT_MASK,
|
||||||
pedantic,
|
pedantic,
|
||||||
"expressions where a bit mask is less readable than the corresponding method call"
|
"expressions where a bit mask is less readable than the corresponding method call"
|
||||||
|
|
|
@ -17,6 +17,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let foo = 3.14;
|
/// let foo = 3.14;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub BLACKLISTED_NAME,
|
pub BLACKLISTED_NAME,
|
||||||
style,
|
style,
|
||||||
"usage of a blacklisted/placeholder name"
|
"usage of a blacklisted/placeholder name"
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// let res = { let x = somefunc(); x };
|
/// let res = { let x = somefunc(); x };
|
||||||
/// if res { /* ... */ }
|
/// if res { /* ... */ }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.45.0"]
|
||||||
pub BLOCKS_IN_IF_CONDITIONS,
|
pub BLOCKS_IN_IF_CONDITIONS,
|
||||||
style,
|
style,
|
||||||
"useless or complex blocks that can be eliminated in conditions"
|
"useless or complex blocks that can be eliminated in conditions"
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// assert!(!"a".is_empty());
|
/// assert!(!"a".is_empty());
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.53.0"]
|
||||||
pub BOOL_ASSERT_COMPARISON,
|
pub BOOL_ASSERT_COMPARISON,
|
||||||
style,
|
style,
|
||||||
"Using a boolean as comparison value in an assert_* macro when there is no need"
|
"Using a boolean as comparison value in an assert_* macro when there is no need"
|
||||||
|
@ -72,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
|
||||||
if let Some(span) = is_direct_expn_of(expr.span, mac) {
|
if let Some(span) = is_direct_expn_of(expr.span, mac) {
|
||||||
if let Some(args) = higher::extract_assert_macro_args(expr) {
|
if let Some(args) = higher::extract_assert_macro_args(expr) {
|
||||||
if let [a, b, ..] = args[..] {
|
if let [a, b, ..] = args[..] {
|
||||||
let nb_bool_args = is_bool_lit(a) as usize + is_bool_lit(b) as usize;
|
let nb_bool_args = usize::from(is_bool_lit(a)) + usize::from(is_bool_lit(b));
|
||||||
|
|
||||||
if nb_bool_args != 1 {
|
if nb_bool_args != 1 {
|
||||||
// If there are two boolean arguments, we definitely don't understand
|
// If there are two boolean arguments, we definitely don't understand
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||||
use clippy_utils::{eq_expr_value, get_trait_def_id, in_macro, paths};
|
use clippy_utils::{eq_expr_value, get_trait_def_id, paths};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_ast::ast::LitKind;
|
use rustc_ast::ast::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// if a && true // should be: if a
|
/// if a && true // should be: if a
|
||||||
/// if !(a == b) // should be: if a != b
|
/// if !(a == b) // should be: if a != b
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub NONMINIMAL_BOOL,
|
pub NONMINIMAL_BOOL,
|
||||||
complexity,
|
complexity,
|
||||||
"boolean expressions that can be written more concisely"
|
"boolean expressions that can be written more concisely"
|
||||||
|
@ -52,6 +53,7 @@ declare_clippy_lint! {
|
||||||
/// if a && b || a { ... }
|
/// if a && b || a { ... }
|
||||||
/// ```
|
/// ```
|
||||||
/// The `b` is unnecessary, the expression is equivalent to `if a`.
|
/// The `b` is unnecessary, the expression is equivalent to `if a`.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub LOGIC_BUG,
|
pub LOGIC_BUG,
|
||||||
correctness,
|
correctness,
|
||||||
"boolean expressions that contain terminals which can be eliminated"
|
"boolean expressions that contain terminals which can be eliminated"
|
||||||
|
@ -453,22 +455,20 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
type Map = Map<'tcx>;
|
type Map = Map<'tcx>;
|
||||||
|
|
||||||
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
|
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
|
||||||
if in_macro(e.span) {
|
if !e.span.from_expansion() {
|
||||||
return;
|
match &e.kind {
|
||||||
}
|
ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => {
|
||||||
match &e.kind {
|
|
||||||
ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => {
|
|
||||||
self.bool_expr(e);
|
|
||||||
},
|
|
||||||
ExprKind::Unary(UnOp::Not, inner) => {
|
|
||||||
if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
|
|
||||||
self.bool_expr(e);
|
self.bool_expr(e);
|
||||||
} else {
|
},
|
||||||
walk_expr(self, e);
|
ExprKind::Unary(UnOp::Not, inner) => {
|
||||||
}
|
if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
|
||||||
},
|
self.bool_expr(e);
|
||||||
_ => walk_expr(self, e),
|
}
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
walk_expr(self, e);
|
||||||
}
|
}
|
||||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||||
NestedVisitorMap::None
|
NestedVisitorMap::None
|
||||||
|
|
|
@ -30,6 +30,7 @@ declare_clippy_lint! {
|
||||||
/// # let vec = vec![1_u8];
|
/// # let vec = vec![1_u8];
|
||||||
/// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead
|
/// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub NAIVE_BYTECOUNT,
|
pub NAIVE_BYTECOUNT,
|
||||||
pedantic,
|
pedantic,
|
||||||
"use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
|
"use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
|
||||||
|
@ -73,10 +74,10 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
|
||||||
if (p == sym::iter || p == sym!(iter_mut)) && args.len() == 1 {
|
if (p == sym::iter || p == sym!(iter_mut)) && args.len() == 1 {
|
||||||
&args[0]
|
&args[0]
|
||||||
} else {
|
} else {
|
||||||
&filter_recv
|
filter_recv
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
&filter_recv
|
filter_recv
|
||||||
};
|
};
|
||||||
let mut applicability = Applicability::MaybeIncorrect;
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
|
|
@ -42,6 +42,7 @@ declare_clippy_lint! {
|
||||||
/// keywords = ["clippy", "lint", "plugin"]
|
/// keywords = ["clippy", "lint", "plugin"]
|
||||||
/// categories = ["development-tools", "development-tools::cargo-plugins"]
|
/// categories = ["development-tools", "development-tools::cargo-plugins"]
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.32.0"]
|
||||||
pub CARGO_COMMON_METADATA,
|
pub CARGO_COMMON_METADATA,
|
||||||
cargo,
|
cargo,
|
||||||
"common metadata is defined in `Cargo.toml`"
|
"common metadata is defined in `Cargo.toml`"
|
||||||
|
|
|
@ -27,6 +27,7 @@ declare_clippy_lint! {
|
||||||
/// filename.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rs")) == Some(true)
|
/// filename.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rs")) == Some(true)
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
pub CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"Checks for calls to ends_with with case-sensitive file extensions"
|
"Checks for calls to ends_with with case-sensitive file extensions"
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::in_constant;
|
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::is_isize_or_usize;
|
use clippy_utils::ty::is_isize_or_usize;
|
||||||
|
use clippy_utils::{in_constant, meets_msrv, msrvs};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::{self, FloatTy, Ty};
|
use rustc_middle::ty::{self, FloatTy, Ty};
|
||||||
|
use rustc_semver::RustcVersion;
|
||||||
|
|
||||||
use super::{utils, CAST_LOSSLESS};
|
use super::{utils, CAST_LOSSLESS};
|
||||||
|
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
|
pub(super) fn check(
|
||||||
if !should_lint(cx, expr, cast_from, cast_to) {
|
cx: &LateContext<'_>,
|
||||||
|
expr: &Expr<'_>,
|
||||||
|
cast_op: &Expr<'_>,
|
||||||
|
cast_from: Ty<'_>,
|
||||||
|
cast_to: Ty<'_>,
|
||||||
|
msrv: &Option<RustcVersion>,
|
||||||
|
) {
|
||||||
|
if !should_lint(cx, expr, cast_from, cast_to, msrv) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,21 +40,36 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, c
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let message = if cast_from.is_bool() {
|
||||||
|
format!(
|
||||||
|
"casting `{0:}` to `{1:}` is more cleanly stated with `{1:}::from(_)`",
|
||||||
|
cast_from, cast_to
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"casting `{}` to `{}` may become silently lossy if you later change the type",
|
||||||
|
cast_from, cast_to
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
CAST_LOSSLESS,
|
CAST_LOSSLESS,
|
||||||
expr.span,
|
expr.span,
|
||||||
&format!(
|
&message,
|
||||||
"casting `{}` to `{}` may become silently lossy if you later change the type",
|
|
||||||
cast_from, cast_to
|
|
||||||
),
|
|
||||||
"try",
|
"try",
|
||||||
format!("{}::from({})", cast_to, sugg),
|
format!("{}::from({})", cast_to, sugg),
|
||||||
applicability,
|
applicability,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) -> bool {
|
fn should_lint(
|
||||||
|
cx: &LateContext<'_>,
|
||||||
|
expr: &Expr<'_>,
|
||||||
|
cast_from: Ty<'_>,
|
||||||
|
cast_to: Ty<'_>,
|
||||||
|
msrv: &Option<RustcVersion>,
|
||||||
|
) -> bool {
|
||||||
// Do not suggest using From in consts/statics until it is valid to do so (see #2267).
|
// Do not suggest using From in consts/statics until it is valid to do so (see #2267).
|
||||||
if in_constant(cx, expr.hir_id) {
|
if in_constant(cx, expr.hir_id) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -72,7 +95,7 @@ fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to
|
||||||
};
|
};
|
||||||
from_nbits < to_nbits
|
from_nbits < to_nbits
|
||||||
},
|
},
|
||||||
|
(false, true) if matches!(cast_from.kind(), ty::Bool) && meets_msrv(msrv.as_ref(), &msrvs::FROM_BOOL) => true,
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
|
matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,6 +40,7 @@ declare_clippy_lint! {
|
||||||
/// let x = u64::MAX;
|
/// let x = u64::MAX;
|
||||||
/// x as f64;
|
/// x as f64;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_PRECISION_LOSS,
|
pub CAST_PRECISION_LOSS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casts that cause loss of precision, e.g., `x as f32` where `x: u64`"
|
"casts that cause loss of precision, e.g., `x as f32` where `x: u64`"
|
||||||
|
@ -61,6 +62,7 @@ declare_clippy_lint! {
|
||||||
/// let y: i8 = -1;
|
/// let y: i8 = -1;
|
||||||
/// y as u128; // will return 18446744073709551615
|
/// y as u128; // will return 18446744073709551615
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_SIGN_LOSS,
|
pub CAST_SIGN_LOSS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`"
|
"casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`"
|
||||||
|
@ -83,6 +85,7 @@ declare_clippy_lint! {
|
||||||
/// x as u8
|
/// x as u8
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_POSSIBLE_TRUNCATION,
|
pub CAST_POSSIBLE_TRUNCATION,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`"
|
"casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`"
|
||||||
|
@ -106,6 +109,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// u32::MAX as i32; // will yield a value of `-1`
|
/// u32::MAX as i32; // will yield a value of `-1`
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_POSSIBLE_WRAP,
|
pub CAST_POSSIBLE_WRAP,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`"
|
"casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`"
|
||||||
|
@ -138,6 +142,7 @@ declare_clippy_lint! {
|
||||||
/// u64::from(x)
|
/// u64::from(x)
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_LOSSLESS,
|
pub CAST_LOSSLESS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`"
|
"casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`"
|
||||||
|
@ -163,6 +168,7 @@ declare_clippy_lint! {
|
||||||
/// let _ = 2_i32;
|
/// let _ = 2_i32;
|
||||||
/// let _ = 0.5_f32;
|
/// let _ = 0.5_f32;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub UNNECESSARY_CAST,
|
pub UNNECESSARY_CAST,
|
||||||
complexity,
|
complexity,
|
||||||
"cast to the same type, e.g., `x as i32` where `x: i32`"
|
"cast to the same type, e.g., `x as i32` where `x: i32`"
|
||||||
|
@ -190,6 +196,7 @@ declare_clippy_lint! {
|
||||||
/// (&1u8 as *const u8).cast::<u16>();
|
/// (&1u8 as *const u8).cast::<u16>();
|
||||||
/// (&mut 1u8 as *mut u8).cast::<u16>();
|
/// (&mut 1u8 as *mut u8).cast::<u16>();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_PTR_ALIGNMENT,
|
pub CAST_PTR_ALIGNMENT,
|
||||||
pedantic,
|
pedantic,
|
||||||
"cast from a pointer to a more-strictly-aligned pointer"
|
"cast from a pointer to a more-strictly-aligned pointer"
|
||||||
|
@ -217,6 +224,7 @@ declare_clippy_lint! {
|
||||||
/// fn fun2() -> i32 { 1 }
|
/// fn fun2() -> i32 { 1 }
|
||||||
/// let a = fun2 as usize;
|
/// let a = fun2 as usize;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FN_TO_NUMERIC_CAST,
|
pub FN_TO_NUMERIC_CAST,
|
||||||
style,
|
style,
|
||||||
"casting a function pointer to a numeric type other than usize"
|
"casting a function pointer to a numeric type other than usize"
|
||||||
|
@ -247,6 +255,7 @@ declare_clippy_lint! {
|
||||||
/// let fn_ptr = fn2 as usize;
|
/// let fn_ptr = fn2 as usize;
|
||||||
/// let fn_ptr_truncated = fn_ptr as i32;
|
/// let fn_ptr_truncated = fn_ptr as i32;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||||
style,
|
style,
|
||||||
"casting a function pointer to a numeric type not wide enough to store the address"
|
"casting a function pointer to a numeric type not wide enough to store the address"
|
||||||
|
@ -283,6 +292,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// let _ = fn3 as fn() -> u16;
|
/// let _ = fn3 as fn() -> u16;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.58.0"]
|
||||||
pub FN_TO_NUMERIC_CAST_ANY,
|
pub FN_TO_NUMERIC_CAST_ANY,
|
||||||
restriction,
|
restriction,
|
||||||
"casting a function pointer to any integer type"
|
"casting a function pointer to any integer type"
|
||||||
|
@ -317,6 +327,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.33.0"]
|
||||||
pub CAST_REF_TO_MUT,
|
pub CAST_REF_TO_MUT,
|
||||||
correctness,
|
correctness,
|
||||||
"a cast of reference to a mutable pointer"
|
"a cast of reference to a mutable pointer"
|
||||||
|
@ -344,6 +355,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// b'x'
|
/// b'x'
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CHAR_LIT_AS_U8,
|
pub CHAR_LIT_AS_U8,
|
||||||
complexity,
|
complexity,
|
||||||
"casting a character literal to `u8` truncates"
|
"casting a character literal to `u8` truncates"
|
||||||
|
@ -372,6 +384,7 @@ declare_clippy_lint! {
|
||||||
/// let _ = ptr.cast::<i32>();
|
/// let _ = ptr.cast::<i32>();
|
||||||
/// let _ = mut_ptr.cast::<i32>();
|
/// let _ = mut_ptr.cast::<i32>();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub PTR_AS_PTR,
|
pub PTR_AS_PTR,
|
||||||
pedantic,
|
pedantic,
|
||||||
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
|
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
|
||||||
|
@ -426,12 +439,16 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||||
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
|
|
||||||
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
|
||||||
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
|
if cast_from.is_numeric() {
|
||||||
cast_precision_loss::check(cx, expr, cast_from, cast_to);
|
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to);
|
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
|
||||||
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
|
cast_precision_loss::check(cx, expr, cast_from, cast_to);
|
||||||
|
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ declare_clippy_lint! {
|
||||||
/// i32::try_from(foo).is_ok()
|
/// i32::try_from(foo).is_ok()
|
||||||
/// # ;
|
/// # ;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.37.0"]
|
||||||
pub CHECKED_CONVERSIONS,
|
pub CHECKED_CONVERSIONS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`try_from` could replace manual bounds checking when casting"
|
"`try_from` could replace manual bounds checking when casting"
|
||||||
|
|
|
@ -27,6 +27,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// No. You'll see it when you get the warning.
|
/// No. You'll see it when you get the warning.
|
||||||
|
#[clippy::version = "1.35.0"]
|
||||||
pub COGNITIVE_COMPLEXITY,
|
pub COGNITIVE_COMPLEXITY,
|
||||||
nursery,
|
nursery,
|
||||||
"functions that should be split up into multiple functions"
|
"functions that should be split up into multiple functions"
|
||||||
|
|
|
@ -47,6 +47,7 @@ declare_clippy_lint! {
|
||||||
/// …
|
/// …
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub COLLAPSIBLE_IF,
|
pub COLLAPSIBLE_IF,
|
||||||
style,
|
style,
|
||||||
"nested `if`s that can be collapsed (e.g., `if x { if y { ... } }`"
|
"nested `if`s that can be collapsed (e.g., `if x { if y { ... } }`"
|
||||||
|
@ -82,6 +83,7 @@ declare_clippy_lint! {
|
||||||
/// …
|
/// …
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub COLLAPSIBLE_ELSE_IF,
|
pub COLLAPSIBLE_ELSE_IF,
|
||||||
style,
|
style,
|
||||||
"nested `else`-`if` expressions that can be collapsed (e.g., `else { if x { ... } }`)"
|
"nested `else`-`if` expressions that can be collapsed (e.g., `else { if x { ... } }`)"
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// };
|
/// };
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.50.0"]
|
||||||
pub COLLAPSIBLE_MATCH,
|
pub COLLAPSIBLE_MATCH,
|
||||||
style,
|
style,
|
||||||
"Nested `match` or `if let` expressions where the patterns may be \"collapsed\" together."
|
"Nested `match` or `if let` expressions where the patterns may be \"collapsed\" together."
|
||||||
|
|
|
@ -49,6 +49,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub COMPARISON_CHAIN,
|
pub COMPARISON_CHAIN,
|
||||||
style,
|
style,
|
||||||
"`if`s that can be rewritten with `match` and `cmp`"
|
"`if`s that can be rewritten with `match` and `cmp`"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
|
||||||
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
|
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
|
||||||
use clippy_utils::{
|
use clippy_utils::{
|
||||||
both, count_eq, eq_expr_value, get_enclosing_block, get_parent_expr, if_sequence, in_macro, is_else_clause,
|
both, count_eq, eq_expr_value, get_enclosing_block, get_parent_expr, if_sequence, is_else_clause, is_lint_allowed,
|
||||||
is_lint_allowed, search_same, ContainsName, SpanlessEq, SpanlessHash,
|
search_same, ContainsName, SpanlessEq, SpanlessHash,
|
||||||
};
|
};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// …
|
/// …
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IFS_SAME_COND,
|
pub IFS_SAME_COND,
|
||||||
correctness,
|
correctness,
|
||||||
"consecutive `if`s with the same condition"
|
"consecutive `if`s with the same condition"
|
||||||
|
@ -88,6 +89,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.41.0"]
|
||||||
pub SAME_FUNCTIONS_IN_IF_CONDITION,
|
pub SAME_FUNCTIONS_IN_IF_CONDITION,
|
||||||
pedantic,
|
pedantic,
|
||||||
"consecutive `if`s with the same function call"
|
"consecutive `if`s with the same function call"
|
||||||
|
@ -109,6 +111,7 @@ declare_clippy_lint! {
|
||||||
/// 42
|
/// 42
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IF_SAME_THEN_ELSE,
|
pub IF_SAME_THEN_ELSE,
|
||||||
correctness,
|
correctness,
|
||||||
"`if` with the same `then` and `else` blocks"
|
"`if` with the same `then` and `else` blocks"
|
||||||
|
@ -147,6 +150,7 @@ declare_clippy_lint! {
|
||||||
/// 42
|
/// 42
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.53.0"]
|
||||||
pub BRANCHES_SHARING_CODE,
|
pub BRANCHES_SHARING_CODE,
|
||||||
nursery,
|
nursery,
|
||||||
"`if` statement with shared code in all blocks"
|
"`if` statement with shared code in all blocks"
|
||||||
|
@ -623,7 +627,7 @@ fn lint_same_fns_in_if_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {
|
||||||
|
|
||||||
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool {
|
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool {
|
||||||
// Do not lint if any expr originates from a macro
|
// Do not lint if any expr originates from a macro
|
||||||
if in_macro(lhs.span) || in_macro(rhs.span) {
|
if lhs.span.from_expansion() || rhs.span.from_expansion() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Do not spawn warning if `IFS_SAME_COND` already produced it.
|
// Do not spawn warning if `IFS_SAME_COND` already produced it.
|
||||||
|
|
|
@ -28,6 +28,7 @@ declare_clippy_lint! {
|
||||||
/// let a: Vec<_> = my_iterator.take(1).collect();
|
/// let a: Vec<_> = my_iterator.take(1).collect();
|
||||||
/// let b: Vec<_> = my_iterator.collect();
|
/// let b: Vec<_> = my_iterator.collect();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.30.0"]
|
||||||
pub COPY_ITERATOR,
|
pub COPY_ITERATOR,
|
||||||
pedantic,
|
pedantic,
|
||||||
"implementing `Iterator` on a `Copy` type"
|
"implementing `Iterator` on a `Copy` type"
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// std::fs::create_dir_all("foo");
|
/// std::fs::create_dir_all("foo");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.48.0"]
|
||||||
pub CREATE_DIR,
|
pub CREATE_DIR,
|
||||||
restriction,
|
restriction,
|
||||||
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
|
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
|
||||||
|
|
|
@ -15,6 +15,14 @@ declare_clippy_lint! {
|
||||||
/// `dbg!` macro is intended as a debugging tool. It
|
/// `dbg!` macro is intended as a debugging tool. It
|
||||||
/// should not be in version control.
|
/// should not be in version control.
|
||||||
///
|
///
|
||||||
|
/// ### Known problems
|
||||||
|
/// * The lint level is unaffected by crate attributes. The level can still
|
||||||
|
/// be set for functions, modules and other items. To change the level for
|
||||||
|
/// the entire crate, please use command line flags. More information and a
|
||||||
|
/// configuration example can be found in [clippy#6610].
|
||||||
|
///
|
||||||
|
/// [clippy#6610]: https://github.com/rust-lang/rust-clippy/issues/6610#issuecomment-977120558
|
||||||
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// // Bad
|
/// // Bad
|
||||||
|
@ -23,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// true
|
/// true
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.34.0"]
|
||||||
pub DBG_MACRO,
|
pub DBG_MACRO,
|
||||||
restriction,
|
restriction,
|
||||||
"`dbg!` macro is intended as a debugging tool"
|
"`dbg!` macro is intended as a debugging tool"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
|
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
|
||||||
use clippy_utils::source::snippet_with_macro_callsite;
|
use clippy_utils::source::snippet_with_macro_callsite;
|
||||||
use clippy_utils::ty::{has_drop, is_copy};
|
use clippy_utils::ty::{has_drop, is_copy};
|
||||||
use clippy_utils::{any_parent_is_automatically_derived, contains_name, in_macro, match_def_path, paths};
|
use clippy_utils::{any_parent_is_automatically_derived, contains_name, match_def_path, paths};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -29,6 +29,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// let s = String::default();
|
/// let s = String::default();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DEFAULT_TRAIT_ACCESS,
|
pub DEFAULT_TRAIT_ACCESS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"checks for literal calls to `Default::default()`"
|
"checks for literal calls to `Default::default()`"
|
||||||
|
@ -62,6 +63,7 @@ declare_clippy_lint! {
|
||||||
/// .. Default::default()
|
/// .. Default::default()
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.49.0"]
|
||||||
pub FIELD_REASSIGN_WITH_DEFAULT,
|
pub FIELD_REASSIGN_WITH_DEFAULT,
|
||||||
style,
|
style,
|
||||||
"binding initialized with Default should have its fields set in the initializer"
|
"binding initialized with Default should have its fields set in the initializer"
|
||||||
|
@ -78,7 +80,7 @@ impl_lint_pass!(Default => [DEFAULT_TRAIT_ACCESS, FIELD_REASSIGN_WITH_DEFAULT]);
|
||||||
impl LateLintPass<'_> for Default {
|
impl LateLintPass<'_> for Default {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if !in_macro(expr.span);
|
if !expr.span.from_expansion();
|
||||||
// Avoid cases already linted by `field_reassign_with_default`
|
// Avoid cases already linted by `field_reassign_with_default`
|
||||||
if !self.reassigned_linted.contains(&expr.span);
|
if !self.reassigned_linted.contains(&expr.span);
|
||||||
if let ExprKind::Call(path, ..) = expr.kind;
|
if let ExprKind::Call(path, ..) = expr.kind;
|
||||||
|
@ -125,7 +127,7 @@ impl LateLintPass<'_> for Default {
|
||||||
if let StmtKind::Local(local) = stmt.kind;
|
if let StmtKind::Local(local) = stmt.kind;
|
||||||
if let Some(expr) = local.init;
|
if let Some(expr) = local.init;
|
||||||
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
|
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
|
||||||
if !in_macro(expr.span);
|
if !expr.span.from_expansion();
|
||||||
// only take bindings to identifiers
|
// only take bindings to identifiers
|
||||||
if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
|
if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
|
||||||
// only when assigning `... = Default::default()`
|
// only when assigning `... = Default::default()`
|
||||||
|
|
|
@ -46,6 +46,7 @@ declare_clippy_lint! {
|
||||||
/// let i = 10i32;
|
/// let i = 10i32;
|
||||||
/// let f = 1.23f64;
|
/// let f = 1.23f64;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.52.0"]
|
||||||
pub DEFAULT_NUMERIC_FALLBACK,
|
pub DEFAULT_NUMERIC_FALLBACK,
|
||||||
restriction,
|
restriction,
|
||||||
"usage of unconstrained numeric literals which may cause default numeric fallback."
|
"usage of unconstrained numeric literals which may cause default numeric fallback."
|
||||||
|
|
|
@ -21,6 +21,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This used to check for `assert!(a == b)` and recommend
|
/// This used to check for `assert!(a == b)` and recommend
|
||||||
/// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.
|
/// replacement with `assert_eq!(a, b)`, but this is no longer needed after RFC 2011.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub SHOULD_ASSERT_EQ,
|
pub SHOULD_ASSERT_EQ,
|
||||||
"`assert!()` will be more flexible with RFC 2011"
|
"`assert!()` will be more flexible with RFC 2011"
|
||||||
}
|
}
|
||||||
|
@ -32,6 +33,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This used to check for `Vec::extend`, which was slower than
|
/// This used to check for `Vec::extend`, which was slower than
|
||||||
/// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true.
|
/// `Vec::extend_from_slice`. Thanks to specialization, this is no longer true.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EXTEND_FROM_SLICE,
|
pub EXTEND_FROM_SLICE,
|
||||||
"`.extend_from_slice(_)` is a faster way to extend a Vec by a slice"
|
"`.extend_from_slice(_)` is a faster way to extend a Vec by a slice"
|
||||||
}
|
}
|
||||||
|
@ -45,6 +47,7 @@ declare_deprecated_lint! {
|
||||||
/// an infinite iterator, which is better expressed by `iter::repeat`,
|
/// an infinite iterator, which is better expressed by `iter::repeat`,
|
||||||
/// but the method has been removed for `Iterator::step_by` which panics
|
/// but the method has been removed for `Iterator::step_by` which panics
|
||||||
/// if given a zero
|
/// if given a zero
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub RANGE_STEP_BY_ZERO,
|
pub RANGE_STEP_BY_ZERO,
|
||||||
"`iterator.step_by(0)` panics nowadays"
|
"`iterator.step_by(0)` panics nowadays"
|
||||||
}
|
}
|
||||||
|
@ -56,6 +59,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This used to check for `Vec::as_slice`, which was unstable with good
|
/// This used to check for `Vec::as_slice`, which was unstable with good
|
||||||
/// stable alternatives. `Vec::as_slice` has now been stabilized.
|
/// stable alternatives. `Vec::as_slice` has now been stabilized.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub UNSTABLE_AS_SLICE,
|
pub UNSTABLE_AS_SLICE,
|
||||||
"`Vec::as_slice` has been stabilized in 1.7"
|
"`Vec::as_slice` has been stabilized in 1.7"
|
||||||
}
|
}
|
||||||
|
@ -67,6 +71,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This used to check for `Vec::as_mut_slice`, which was unstable with good
|
/// This used to check for `Vec::as_mut_slice`, which was unstable with good
|
||||||
/// stable alternatives. `Vec::as_mut_slice` has now been stabilized.
|
/// stable alternatives. `Vec::as_mut_slice` has now been stabilized.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub UNSTABLE_AS_MUT_SLICE,
|
pub UNSTABLE_AS_MUT_SLICE,
|
||||||
"`Vec::as_mut_slice` has been stabilized in 1.7"
|
"`Vec::as_mut_slice` has been stabilized in 1.7"
|
||||||
}
|
}
|
||||||
|
@ -80,6 +85,7 @@ declare_deprecated_lint! {
|
||||||
/// between non-pointer types of differing alignment is well-defined behavior (it's semantically
|
/// between non-pointer types of differing alignment is well-defined behavior (it's semantically
|
||||||
/// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
|
/// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
|
||||||
/// cast_ptr_alignment and transmute_ptr_to_ptr.
|
/// cast_ptr_alignment and transmute_ptr_to_ptr.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub MISALIGNED_TRANSMUTE,
|
pub MISALIGNED_TRANSMUTE,
|
||||||
"this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr"
|
"this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr"
|
||||||
}
|
}
|
||||||
|
@ -92,6 +98,7 @@ declare_deprecated_lint! {
|
||||||
/// This lint is too subjective, not having a good reason for being in clippy.
|
/// This lint is too subjective, not having a good reason for being in clippy.
|
||||||
/// Additionally, compound assignment operators may be overloaded separately from their non-assigning
|
/// Additionally, compound assignment operators may be overloaded separately from their non-assigning
|
||||||
/// counterparts, so this lint may suggest a change in behavior or the code may not compile.
|
/// counterparts, so this lint may suggest a change in behavior or the code may not compile.
|
||||||
|
#[clippy::version = "1.30.0"]
|
||||||
pub ASSIGN_OPS,
|
pub ASSIGN_OPS,
|
||||||
"using compound assignment operators (e.g., `+=`) is harmless"
|
"using compound assignment operators (e.g., `+=`) is harmless"
|
||||||
}
|
}
|
||||||
|
@ -104,6 +111,7 @@ declare_deprecated_lint! {
|
||||||
/// The original rule will only lint for `if let`. After
|
/// The original rule will only lint for `if let`. After
|
||||||
/// making it support to lint `match`, naming as `if let` is not suitable for it.
|
/// making it support to lint `match`, naming as `if let` is not suitable for it.
|
||||||
/// So, this lint is deprecated.
|
/// So, this lint is deprecated.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IF_LET_REDUNDANT_PATTERN_MATCHING,
|
pub IF_LET_REDUNDANT_PATTERN_MATCHING,
|
||||||
"this lint has been changed to redundant_pattern_matching"
|
"this lint has been changed to redundant_pattern_matching"
|
||||||
}
|
}
|
||||||
|
@ -117,6 +125,7 @@ declare_deprecated_lint! {
|
||||||
/// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The
|
/// Vec::with_capacity(n); vec.set_len(n);` with `let vec = vec![0; n];`. The
|
||||||
/// replacement has very different performance characteristics so the lint is
|
/// replacement has very different performance characteristics so the lint is
|
||||||
/// deprecated.
|
/// deprecated.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub UNSAFE_VECTOR_INITIALIZATION,
|
pub UNSAFE_VECTOR_INITIALIZATION,
|
||||||
"the replacement suggested by this lint had substantially different behavior"
|
"the replacement suggested by this lint had substantially different behavior"
|
||||||
}
|
}
|
||||||
|
@ -127,6 +136,7 @@ declare_deprecated_lint! {
|
||||||
///
|
///
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This lint has been superseded by #[must_use] in rustc.
|
/// This lint has been superseded by #[must_use] in rustc.
|
||||||
|
#[clippy::version = "1.39.0"]
|
||||||
pub UNUSED_COLLECT,
|
pub UNUSED_COLLECT,
|
||||||
"`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint"
|
"`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint"
|
||||||
}
|
}
|
||||||
|
@ -137,6 +147,7 @@ declare_deprecated_lint! {
|
||||||
///
|
///
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// Associated-constants are now preferred.
|
/// Associated-constants are now preferred.
|
||||||
|
#[clippy::version = "1.44.0"]
|
||||||
pub REPLACE_CONSTS,
|
pub REPLACE_CONSTS,
|
||||||
"associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants"
|
"associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants"
|
||||||
}
|
}
|
||||||
|
@ -147,6 +158,7 @@ declare_deprecated_lint! {
|
||||||
///
|
///
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// The regex! macro does not exist anymore.
|
/// The regex! macro does not exist anymore.
|
||||||
|
#[clippy::version = "1.47.0"]
|
||||||
pub REGEX_MACRO,
|
pub REGEX_MACRO,
|
||||||
"the regex! macro has been removed from the regex crate in 2018"
|
"the regex! macro has been removed from the regex crate in 2018"
|
||||||
}
|
}
|
||||||
|
@ -158,6 +170,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This lint has been replaced by `manual_find_map`, a
|
/// This lint has been replaced by `manual_find_map`, a
|
||||||
/// more specific lint.
|
/// more specific lint.
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub FIND_MAP,
|
pub FIND_MAP,
|
||||||
"this lint has been replaced by `manual_find_map`, a more specific lint"
|
"this lint has been replaced by `manual_find_map`, a more specific lint"
|
||||||
}
|
}
|
||||||
|
@ -169,6 +182,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// This lint has been replaced by `manual_filter_map`, a
|
/// This lint has been replaced by `manual_filter_map`, a
|
||||||
/// more specific lint.
|
/// more specific lint.
|
||||||
|
#[clippy::version = "1.53.0"]
|
||||||
pub FILTER_MAP,
|
pub FILTER_MAP,
|
||||||
"this lint has been replaced by `manual_filter_map`, a more specific lint"
|
"this lint has been replaced by `manual_filter_map`, a more specific lint"
|
||||||
}
|
}
|
||||||
|
@ -181,6 +195,7 @@ declare_deprecated_lint! {
|
||||||
/// The `avoid_breaking_exported_api` config option was added, which
|
/// The `avoid_breaking_exported_api` config option was added, which
|
||||||
/// enables the `enum_variant_names` lint for public items.
|
/// enables the `enum_variant_names` lint for public items.
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.54.0"]
|
||||||
pub PUB_ENUM_VARIANT_NAMES,
|
pub PUB_ENUM_VARIANT_NAMES,
|
||||||
"set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items"
|
"set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items"
|
||||||
}
|
}
|
||||||
|
@ -192,6 +207,7 @@ declare_deprecated_lint! {
|
||||||
/// ### Deprecation reason
|
/// ### Deprecation reason
|
||||||
/// The `avoid_breaking_exported_api` config option was added, which
|
/// The `avoid_breaking_exported_api` config option was added, which
|
||||||
/// enables the `wrong_self_conversion` lint for public items.
|
/// enables the `wrong_self_conversion` lint for public items.
|
||||||
|
#[clippy::version = "1.54.0"]
|
||||||
pub WRONG_PUB_SELF_CONVENTION,
|
pub WRONG_PUB_SELF_CONVENTION,
|
||||||
"set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items"
|
"set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::source::snippet_with_context;
|
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
|
||||||
use clippy_utils::ty::peel_mid_ty_refs;
|
use clippy_utils::ty::peel_mid_ty_refs;
|
||||||
use clippy_utils::{get_parent_node, in_macro, is_lint_allowed};
|
use clippy_utils::{get_parent_expr, get_parent_node, is_lint_allowed, path_to_local};
|
||||||
use rustc_ast::util::parser::PREC_PREFIX;
|
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
|
||||||
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, UnOp};
|
use rustc_hir::{
|
||||||
|
BindingAnnotation, Body, BodyId, BorrowKind, Destination, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
|
||||||
|
Pat, PatKind, UnOp,
|
||||||
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TyS, TypeckResults};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TyS, TypeckResults};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{symbol::sym, Span};
|
use rustc_span::{symbol::sym, Span};
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
|
@ -34,13 +40,70 @@ declare_clippy_lint! {
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// let _ = d.unwrap().deref();
|
/// let _ = d.unwrap().deref();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.44.0"]
|
||||||
pub EXPLICIT_DEREF_METHODS,
|
pub EXPLICIT_DEREF_METHODS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"Explicit use of deref or deref_mut method while not in a method chain."
|
"Explicit use of deref or deref_mut method while not in a method chain."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for address of operations (`&`) that are going to
|
||||||
|
/// be dereferenced immediately by the compiler.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// Suggests that the receiver of the expression borrows
|
||||||
|
/// the expression.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// fn fun(_a: &i32) {}
|
||||||
|
///
|
||||||
|
/// // Bad
|
||||||
|
/// let x: &i32 = &&&&&&5;
|
||||||
|
/// fun(&x);
|
||||||
|
///
|
||||||
|
/// // Good
|
||||||
|
/// let x: &i32 = &5;
|
||||||
|
/// fun(x);
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
pub NEEDLESS_BORROW,
|
||||||
|
style,
|
||||||
|
"taking a reference that is going to be automatically dereferenced"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for `ref` bindings which create a reference to a reference.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// The address-of operator at the use site is clearer about the need for a reference.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// // Bad
|
||||||
|
/// let x = Some("");
|
||||||
|
/// if let Some(ref x) = x {
|
||||||
|
/// // use `x` here
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Good
|
||||||
|
/// let x = Some("");
|
||||||
|
/// if let Some(x) = x {
|
||||||
|
/// // use `&x` here
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.54.0"]
|
||||||
|
pub REF_BINDING_TO_REFERENCE,
|
||||||
|
pedantic,
|
||||||
|
"`ref` binding to a reference"
|
||||||
|
}
|
||||||
|
|
||||||
impl_lint_pass!(Dereferencing => [
|
impl_lint_pass!(Dereferencing => [
|
||||||
EXPLICIT_DEREF_METHODS,
|
EXPLICIT_DEREF_METHODS,
|
||||||
|
NEEDLESS_BORROW,
|
||||||
|
REF_BINDING_TO_REFERENCE,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -51,6 +114,18 @@ pub struct Dereferencing {
|
||||||
// expression. This is to store the id of that expression so it can be skipped when
|
// expression. This is to store the id of that expression so it can be skipped when
|
||||||
// `check_expr` is called for it.
|
// `check_expr` is called for it.
|
||||||
skip_expr: Option<HirId>,
|
skip_expr: Option<HirId>,
|
||||||
|
|
||||||
|
/// The body the first local was found in. Used to emit lints when the traversal of the body has
|
||||||
|
/// been finished. Note we can't lint at the end of every body as they can be nested within each
|
||||||
|
/// other.
|
||||||
|
current_body: Option<BodyId>,
|
||||||
|
/// The list of locals currently being checked by the lint.
|
||||||
|
/// If the value is `None`, then the binding has been seen as a ref pattern, but is not linted.
|
||||||
|
/// This is needed for or patterns where one of the branches can be linted, but another can not
|
||||||
|
/// be.
|
||||||
|
///
|
||||||
|
/// e.g. `m!(x) | Foo::Bar(ref x)`
|
||||||
|
ref_locals: FxIndexMap<HirId, Option<RefPat>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StateData {
|
struct StateData {
|
||||||
|
@ -67,6 +142,9 @@ enum State {
|
||||||
ty_changed_count: usize,
|
ty_changed_count: usize,
|
||||||
is_final_ufcs: bool,
|
is_final_ufcs: bool,
|
||||||
},
|
},
|
||||||
|
DerefedBorrow {
|
||||||
|
count: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// A reference operation considered by this lint pass
|
// A reference operation considered by this lint pass
|
||||||
|
@ -76,15 +154,31 @@ enum RefOp {
|
||||||
AddrOf,
|
AddrOf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RefPat {
|
||||||
|
/// Whether every usage of the binding is dereferenced.
|
||||||
|
always_deref: bool,
|
||||||
|
/// The spans of all the ref bindings for this local.
|
||||||
|
spans: Vec<Span>,
|
||||||
|
/// The applicability of this suggestion.
|
||||||
|
app: Applicability,
|
||||||
|
/// All the replacements which need to be made.
|
||||||
|
replacements: Vec<(Span, String)>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for Dereferencing {
|
impl<'tcx> LateLintPass<'tcx> for Dereferencing {
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
// Skip path expressions from deref calls. e.g. `Deref::deref(e)`
|
// Skip path expressions from deref calls. e.g. `Deref::deref(e)`
|
||||||
if Some(expr.hir_id) == self.skip_expr.take() {
|
if Some(expr.hir_id) == self.skip_expr.take() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(local) = path_to_local(expr) {
|
||||||
|
self.check_local_usage(cx, expr, local);
|
||||||
|
}
|
||||||
|
|
||||||
// Stop processing sub expressions when a macro call is seen
|
// Stop processing sub expressions when a macro call is seen
|
||||||
if in_macro(expr.span) {
|
if expr.span.from_expansion() {
|
||||||
if let Some((state, data)) = self.state.take() {
|
if let Some((state, data)) = self.state.take() {
|
||||||
report(cx, expr, state, data);
|
report(cx, expr, state, data);
|
||||||
}
|
}
|
||||||
|
@ -127,6 +221,48 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
RefOp::AddrOf => {
|
||||||
|
// Find the number of times the borrow is auto-derefed.
|
||||||
|
let mut iter = find_adjustments(cx.tcx, typeck, expr).iter();
|
||||||
|
if let Some((i, adjust)) = iter.by_ref().enumerate().find_map(|(i, adjust)| {
|
||||||
|
if !matches!(adjust.kind, Adjust::Deref(_)) {
|
||||||
|
Some((i, adjust))
|
||||||
|
} else if !adjust.target.is_ref() {
|
||||||
|
// Add one to the number of references found.
|
||||||
|
Some((i + 1, adjust))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Found two consecutive derefs. At least one can be removed.
|
||||||
|
if i > 1 {
|
||||||
|
let target_mut = iter::once(adjust)
|
||||||
|
.chain(iter)
|
||||||
|
.find_map(|adjust| match adjust.kind {
|
||||||
|
Adjust::Borrow(AutoBorrow::Ref(_, m)) => Some(m.into()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
// This default should never happen. Auto-deref always reborrows.
|
||||||
|
.unwrap_or(Mutability::Not);
|
||||||
|
self.state = Some((
|
||||||
|
// Subtract one for the current borrow expression, and one to cover the last
|
||||||
|
// reference which can't be removed (it's either reborrowed, or needed for
|
||||||
|
// auto-deref to happen).
|
||||||
|
State::DerefedBorrow {
|
||||||
|
count:
|
||||||
|
// Truncation here would require more than a `u32::MAX` level reference. The compiler
|
||||||
|
// does not support this.
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
{ i as u32 - 2 }
|
||||||
|
},
|
||||||
|
StateData {
|
||||||
|
span: expr.span,
|
||||||
|
target_mut,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -143,10 +279,80 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
|
||||||
data,
|
data,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
(Some((State::DerefedBorrow { count }, data)), RefOp::AddrOf) if count != 0 => {
|
||||||
|
self.state = Some((State::DerefedBorrow { count: count - 1 }, data));
|
||||||
|
},
|
||||||
|
|
||||||
(Some((state, data)), _) => report(cx, expr, state, data),
|
(Some((state, data)), _) => report(cx, expr, state, data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||||
|
if let PatKind::Binding(BindingAnnotation::Ref, id, name, _) = pat.kind {
|
||||||
|
if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) {
|
||||||
|
// This binding id has been seen before. Add this pattern to the list of changes.
|
||||||
|
if let Some(prev_pat) = opt_prev_pat {
|
||||||
|
if pat.span.from_expansion() {
|
||||||
|
// Doesn't match the context of the previous pattern. Can't lint here.
|
||||||
|
*opt_prev_pat = None;
|
||||||
|
} else {
|
||||||
|
prev_pat.spans.push(pat.span);
|
||||||
|
prev_pat.replacements.push((
|
||||||
|
pat.span,
|
||||||
|
snippet_with_context(cx, name.span, pat.span.ctxt(), "..", &mut prev_pat.app)
|
||||||
|
.0
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if_chain! {
|
||||||
|
if !pat.span.from_expansion();
|
||||||
|
if let ty::Ref(_, tam, _) = *cx.typeck_results().pat_ty(pat).kind();
|
||||||
|
// only lint immutable refs, because borrowed `&mut T` cannot be moved out
|
||||||
|
if let ty::Ref(_, _, Mutability::Not) = *tam.kind();
|
||||||
|
then {
|
||||||
|
let mut app = Applicability::MachineApplicable;
|
||||||
|
let snip = snippet_with_context(cx, name.span, pat.span.ctxt(), "..", &mut app).0;
|
||||||
|
self.current_body = self.current_body.or(cx.enclosing_body);
|
||||||
|
self.ref_locals.insert(
|
||||||
|
id,
|
||||||
|
Some(RefPat {
|
||||||
|
always_deref: true,
|
||||||
|
spans: vec![pat.span],
|
||||||
|
app,
|
||||||
|
replacements: vec![(pat.span, snip.into())],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
|
||||||
|
if Some(body.id()) == self.current_body {
|
||||||
|
for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
|
||||||
|
let replacements = pat.replacements;
|
||||||
|
let app = pat.app;
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
if pat.always_deref {
|
||||||
|
NEEDLESS_BORROW
|
||||||
|
} else {
|
||||||
|
REF_BINDING_TO_REFERENCE
|
||||||
|
},
|
||||||
|
pat.spans,
|
||||||
|
"this pattern creates a reference to a reference",
|
||||||
|
|diag| {
|
||||||
|
diag.multipart_suggestion("try this", replacements, app);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.current_body = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_parse_ref_op(
|
fn try_parse_ref_op(
|
||||||
|
@ -250,6 +456,48 @@ fn is_linted_explicit_deref_position(parent: Option<Node<'_>>, child_id: HirId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adjustments are sometimes made in the parent block rather than the expression itself.
|
||||||
|
fn find_adjustments(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
typeck: &'tcx TypeckResults<'_>,
|
||||||
|
expr: &'tcx Expr<'_>,
|
||||||
|
) -> &'tcx [Adjustment<'tcx>] {
|
||||||
|
let map = tcx.hir();
|
||||||
|
let mut iter = map.parent_iter(expr.hir_id);
|
||||||
|
let mut prev = expr;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match typeck.expr_adjustments(prev) {
|
||||||
|
[] => (),
|
||||||
|
a => break a,
|
||||||
|
};
|
||||||
|
|
||||||
|
match iter.next().map(|(_, x)| x) {
|
||||||
|
Some(Node::Block(_)) => {
|
||||||
|
if let Some((_, Node::Expr(e))) = iter.next() {
|
||||||
|
prev = e;
|
||||||
|
} else {
|
||||||
|
// This shouldn't happen. Blocks are always contained in an expression.
|
||||||
|
break &[];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(Node::Expr(&Expr {
|
||||||
|
kind: ExprKind::Break(Destination { target_id: Ok(id), .. }, _),
|
||||||
|
..
|
||||||
|
})) => {
|
||||||
|
if let Some(Node::Expr(e)) = map.find(id) {
|
||||||
|
prev = e;
|
||||||
|
iter = map.parent_iter(id);
|
||||||
|
} else {
|
||||||
|
// This shouldn't happen. The destination should exist.
|
||||||
|
break &[];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => break &[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn report(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data: StateData) {
|
fn report(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data: StateData) {
|
||||||
match state {
|
match state {
|
||||||
|
@ -300,5 +548,83 @@ fn report(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data: Stat
|
||||||
app,
|
app,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
State::DerefedBorrow { .. } => {
|
||||||
|
let mut app = Applicability::MachineApplicable;
|
||||||
|
let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0;
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
NEEDLESS_BORROW,
|
||||||
|
data.span,
|
||||||
|
&format!(
|
||||||
|
"this expression borrows a reference (`{}`) that is immediately dereferenced by the compiler",
|
||||||
|
cx.typeck_results().expr_ty(expr),
|
||||||
|
),
|
||||||
|
"change this to",
|
||||||
|
snip.into(),
|
||||||
|
app,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dereferencing {
|
||||||
|
fn check_local_usage(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, local: HirId) {
|
||||||
|
if let Some(outer_pat) = self.ref_locals.get_mut(&local) {
|
||||||
|
if let Some(pat) = outer_pat {
|
||||||
|
// Check for auto-deref
|
||||||
|
if !matches!(
|
||||||
|
cx.typeck_results().expr_adjustments(e),
|
||||||
|
[
|
||||||
|
Adjustment {
|
||||||
|
kind: Adjust::Deref(_),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
Adjustment {
|
||||||
|
kind: Adjust::Deref(_),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
match get_parent_expr(cx, e) {
|
||||||
|
// Field accesses are the same no matter the number of references.
|
||||||
|
Some(Expr {
|
||||||
|
kind: ExprKind::Field(..),
|
||||||
|
..
|
||||||
|
}) => (),
|
||||||
|
Some(&Expr {
|
||||||
|
span,
|
||||||
|
kind: ExprKind::Unary(UnOp::Deref, _),
|
||||||
|
..
|
||||||
|
}) if !span.from_expansion() => {
|
||||||
|
// Remove explicit deref.
|
||||||
|
let snip = snippet_with_context(cx, e.span, span.ctxt(), "..", &mut pat.app).0;
|
||||||
|
pat.replacements.push((span, snip.into()));
|
||||||
|
},
|
||||||
|
Some(parent) if !parent.span.from_expansion() => {
|
||||||
|
// Double reference might be needed at this point.
|
||||||
|
if parent.precedence().order() == PREC_POSTFIX {
|
||||||
|
// Parentheses would be needed here, don't lint.
|
||||||
|
*outer_pat = None;
|
||||||
|
} else {
|
||||||
|
pat.always_deref = false;
|
||||||
|
let snip = snippet_with_context(cx, e.span, parent.span.ctxt(), "..", &mut pat.app).0;
|
||||||
|
pat.replacements.push((e.span, format!("&{}", snip)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ if !e.span.from_expansion() => {
|
||||||
|
// Double reference might be needed at this point.
|
||||||
|
pat.always_deref = false;
|
||||||
|
let snip = snippet_with_applicability(cx, e.span, "..", &mut pat.app);
|
||||||
|
pat.replacements.push((e.span, format!("&{}", snip)));
|
||||||
|
},
|
||||||
|
// Edge case for macros. The span of the identifier will usually match the context of the
|
||||||
|
// binding, but not if the identifier was created in a macro. e.g. `concat_idents` and proc
|
||||||
|
// macros
|
||||||
|
_ => *outer_pat = None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::{in_macro, is_automatically_derived, is_default_equivalent, remove_blocks};
|
use clippy_utils::{is_automatically_derived, is_default_equivalent, remove_blocks};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
def::{DefKind, Res},
|
def::{DefKind, Res},
|
||||||
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
|
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
|
||||||
|
@ -46,6 +46,7 @@ declare_clippy_lint! {
|
||||||
/// has exactly equal bounds, and therefore this lint is disabled for types with
|
/// has exactly equal bounds, and therefore this lint is disabled for types with
|
||||||
/// generic parameters.
|
/// generic parameters.
|
||||||
///
|
///
|
||||||
|
#[clippy::version = "1.57.0"]
|
||||||
pub DERIVABLE_IMPLS,
|
pub DERIVABLE_IMPLS,
|
||||||
complexity,
|
complexity,
|
||||||
"manual implementation of the `Default` trait which is equal to a derive"
|
"manual implementation of the `Default` trait which is equal to a derive"
|
||||||
|
@ -72,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
|
||||||
}) = item.kind;
|
}) = item.kind;
|
||||||
if let attrs = cx.tcx.hir().attrs(item.hir_id());
|
if let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
if !is_automatically_derived(attrs);
|
if !is_automatically_derived(attrs);
|
||||||
if !in_macro(item.span);
|
if !item.span.from_expansion();
|
||||||
if let Some(def_id) = trait_ref.trait_def_id();
|
if let Some(def_id) = trait_ref.trait_def_id();
|
||||||
if cx.tcx.is_diagnostic_item(sym::Default, def_id);
|
if cx.tcx.is_diagnostic_item(sym::Default, def_id);
|
||||||
if let impl_item_hir = child.id.hir_id();
|
if let impl_item_hir = child.id.hir_id();
|
||||||
|
|
|
@ -37,6 +37,7 @@ declare_clippy_lint! {
|
||||||
/// ...
|
/// ...
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DERIVE_HASH_XOR_EQ,
|
pub DERIVE_HASH_XOR_EQ,
|
||||||
correctness,
|
correctness,
|
||||||
"deriving `Hash` but implementing `PartialEq` explicitly"
|
"deriving `Hash` but implementing `PartialEq` explicitly"
|
||||||
|
@ -87,6 +88,7 @@ declare_clippy_lint! {
|
||||||
/// #[derive(Ord, PartialOrd, PartialEq, Eq)]
|
/// #[derive(Ord, PartialOrd, PartialEq, Eq)]
|
||||||
/// struct Foo;
|
/// struct Foo;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.47.0"]
|
||||||
pub DERIVE_ORD_XOR_PARTIAL_ORD,
|
pub DERIVE_ORD_XOR_PARTIAL_ORD,
|
||||||
correctness,
|
correctness,
|
||||||
"deriving `Ord` but implementing `PartialOrd` explicitly"
|
"deriving `Ord` but implementing `PartialOrd` explicitly"
|
||||||
|
@ -113,6 +115,7 @@ declare_clippy_lint! {
|
||||||
/// // ..
|
/// // ..
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EXPL_IMPL_CLONE_ON_COPY,
|
pub EXPL_IMPL_CLONE_ON_COPY,
|
||||||
pedantic,
|
pedantic,
|
||||||
"implementing `Clone` explicitly on `Copy` types"
|
"implementing `Clone` explicitly on `Copy` types"
|
||||||
|
@ -146,6 +149,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.45.0"]
|
||||||
pub UNSAFE_DERIVE_DESERIALIZE,
|
pub UNSAFE_DERIVE_DESERIALIZE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"deriving `serde::Deserialize` on a type that has methods using `unsafe`"
|
"deriving `serde::Deserialize` on a type that has methods using `unsafe`"
|
||||||
|
|
|
@ -47,18 +47,19 @@ declare_clippy_lint! {
|
||||||
/// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
|
/// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
|
||||||
/// xs.push(123); // Vec::push is _not_ disallowed in the config.
|
/// xs.push(123); // Vec::push is _not_ disallowed in the config.
|
||||||
/// ```
|
/// ```
|
||||||
pub DISALLOWED_METHOD,
|
#[clippy::version = "1.49.0"]
|
||||||
|
pub DISALLOWED_METHODS,
|
||||||
nursery,
|
nursery,
|
||||||
"use of a disallowed method call"
|
"use of a disallowed method call"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisallowedMethod {
|
pub struct DisallowedMethods {
|
||||||
conf_disallowed: Vec<conf::DisallowedMethod>,
|
conf_disallowed: Vec<conf::DisallowedMethod>,
|
||||||
disallowed: DefIdMap<Option<String>>,
|
disallowed: DefIdMap<Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisallowedMethod {
|
impl DisallowedMethods {
|
||||||
pub fn new(conf_disallowed: Vec<conf::DisallowedMethod>) -> Self {
|
pub fn new(conf_disallowed: Vec<conf::DisallowedMethod>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conf_disallowed,
|
conf_disallowed,
|
||||||
|
@ -67,9 +68,9 @@ impl DisallowedMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
|
impl_lint_pass!(DisallowedMethods => [DISALLOWED_METHODS]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
|
impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
|
||||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||||
for conf in &self.conf_disallowed {
|
for conf in &self.conf_disallowed {
|
||||||
let (path, reason) = match conf {
|
let (path, reason) = match conf {
|
||||||
|
@ -97,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
|
||||||
};
|
};
|
||||||
let func_path = cx.tcx.def_path_str(def_id);
|
let func_path = cx.tcx.def_path_str(def_id);
|
||||||
let msg = format!("use of a disallowed method `{}`", func_path);
|
let msg = format!("use of a disallowed method `{}`", func_path);
|
||||||
span_lint_and_then(cx, DISALLOWED_METHOD, expr.span, &msg, |diag| {
|
span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, &msg, |diag| {
|
||||||
if let Some(reason) = reason {
|
if let Some(reason) = reason {
|
||||||
diag.note(reason);
|
diag.note(reason);
|
||||||
}
|
}
|
|
@ -38,6 +38,7 @@ declare_clippy_lint! {
|
||||||
/// let zähler = 10; // OK, it's still latin.
|
/// let zähler = 10; // OK, it's still latin.
|
||||||
/// let カウンタ = 10; // Will spawn the lint.
|
/// let カウンタ = 10; // Will spawn the lint.
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.55.0"]
|
||||||
pub DISALLOWED_SCRIPT_IDENTS,
|
pub DISALLOWED_SCRIPT_IDENTS,
|
||||||
restriction,
|
restriction,
|
||||||
"usage of non-allowed Unicode scripts"
|
"usage of non-allowed Unicode scripts"
|
||||||
|
|
|
@ -42,18 +42,19 @@ declare_clippy_lint! {
|
||||||
/// // A similar type that is allowed by the config
|
/// // A similar type that is allowed by the config
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
/// ```
|
/// ```
|
||||||
pub DISALLOWED_TYPE,
|
#[clippy::version = "1.55.0"]
|
||||||
|
pub DISALLOWED_TYPES,
|
||||||
nursery,
|
nursery,
|
||||||
"use of a disallowed type"
|
"use of disallowed types"
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisallowedType {
|
pub struct DisallowedTypes {
|
||||||
conf_disallowed: Vec<conf::DisallowedType>,
|
conf_disallowed: Vec<conf::DisallowedType>,
|
||||||
def_ids: FxHashMap<DefId, Option<String>>,
|
def_ids: FxHashMap<DefId, Option<String>>,
|
||||||
prim_tys: FxHashMap<PrimTy, Option<String>>,
|
prim_tys: FxHashMap<PrimTy, Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisallowedType {
|
impl DisallowedTypes {
|
||||||
pub fn new(conf_disallowed: Vec<conf::DisallowedType>) -> Self {
|
pub fn new(conf_disallowed: Vec<conf::DisallowedType>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conf_disallowed,
|
conf_disallowed,
|
||||||
|
@ -79,9 +80,9 @@ impl DisallowedType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_lint_pass!(DisallowedType => [DISALLOWED_TYPE]);
|
impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for DisallowedType {
|
impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
|
||||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||||
for conf in &self.conf_disallowed {
|
for conf in &self.conf_disallowed {
|
||||||
let (path, reason) = match conf {
|
let (path, reason) = match conf {
|
||||||
|
@ -124,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
|
||||||
fn emit(cx: &LateContext<'_>, name: &str, span: Span, reason: Option<&str>) {
|
fn emit(cx: &LateContext<'_>, name: &str, span: Span, reason: Option<&str>) {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
DISALLOWED_TYPE,
|
DISALLOWED_TYPES,
|
||||||
span,
|
span,
|
||||||
&format!("`{}` is not allowed according to config", name),
|
&format!("`{}` is not allowed according to config", name),
|
||||||
|diag| {
|
|diag| {
|
|
@ -1,5 +1,5 @@
|
||||||
use clippy_utils::attrs::is_doc_hidden;
|
use clippy_utils::attrs::is_doc_hidden;
|
||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_then};
|
||||||
use clippy_utils::source::{first_line_of_span, snippet_with_applicability};
|
use clippy_utils::source::{first_line_of_span, snippet_with_applicability};
|
||||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||||
use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
|
use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
|
||||||
|
@ -10,7 +10,7 @@ use rustc_ast::token::CommentKind;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::emitter::EmitterWriter;
|
use rustc_errors::emitter::EmitterWriter;
|
||||||
use rustc_errors::{Applicability, Handler};
|
use rustc_errors::{Applicability, Handler, SuggestionStyle};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{AnonConst, Expr, ExprKind, QPath};
|
use rustc_hir::{AnonConst, Expr, ExprKind, QPath};
|
||||||
|
@ -67,6 +67,7 @@ declare_clippy_lint! {
|
||||||
/// /// [SmallVec]: SmallVec
|
/// /// [SmallVec]: SmallVec
|
||||||
/// fn main() {}
|
/// fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DOC_MARKDOWN,
|
pub DOC_MARKDOWN,
|
||||||
pedantic,
|
pedantic,
|
||||||
"presence of `_`, `::` or camel-case outside backticks in documentation"
|
"presence of `_`, `::` or camel-case outside backticks in documentation"
|
||||||
|
@ -101,6 +102,7 @@ declare_clippy_lint! {
|
||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.39.0"]
|
||||||
pub MISSING_SAFETY_DOC,
|
pub MISSING_SAFETY_DOC,
|
||||||
style,
|
style,
|
||||||
"`pub unsafe fn` without `# Safety` docs"
|
"`pub unsafe fn` without `# Safety` docs"
|
||||||
|
@ -129,6 +131,7 @@ declare_clippy_lint! {
|
||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.41.0"]
|
||||||
pub MISSING_ERRORS_DOC,
|
pub MISSING_ERRORS_DOC,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`pub fn` returns `Result` without `# Errors` in doc comment"
|
"`pub fn` returns `Result` without `# Errors` in doc comment"
|
||||||
|
@ -159,6 +162,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.52.0"]
|
||||||
pub MISSING_PANICS_DOC,
|
pub MISSING_PANICS_DOC,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`pub fn` may panic without `# Panics` in doc comment"
|
"`pub fn` may panic without `# Panics` in doc comment"
|
||||||
|
@ -187,6 +191,7 @@ declare_clippy_lint! {
|
||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
/// }
|
/// }
|
||||||
/// ``````
|
/// ``````
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub NEEDLESS_DOCTEST_MAIN,
|
pub NEEDLESS_DOCTEST_MAIN,
|
||||||
style,
|
style,
|
||||||
"presence of `fn main() {` in code examples"
|
"presence of `fn main() {` in code examples"
|
||||||
|
@ -639,7 +644,9 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
|
||||||
| ItemKind::ExternCrate(..)
|
| ItemKind::ExternCrate(..)
|
||||||
| ItemKind::ForeignMod(..) => return false,
|
| ItemKind::ForeignMod(..) => return false,
|
||||||
// We found a main function ...
|
// We found a main function ...
|
||||||
ItemKind::Fn(box Fn { sig, body: Some(block), .. }) if item.ident.name == sym::main => {
|
ItemKind::Fn(box Fn {
|
||||||
|
sig, body: Some(block), ..
|
||||||
|
}) if item.ident.name == sym::main => {
|
||||||
let is_async = matches!(sig.header.asyncness, Async::Yes { .. });
|
let is_async = matches!(sig.header.asyncness, Async::Yes { .. });
|
||||||
let returns_nothing = match &sig.decl.output {
|
let returns_nothing = match &sig.decl.output {
|
||||||
FnRetTy::Default(..) => true,
|
FnRetTy::Default(..) => true,
|
||||||
|
@ -763,14 +770,23 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
|
||||||
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
|
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
|
||||||
span_lint_and_sugg(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
DOC_MARKDOWN,
|
DOC_MARKDOWN,
|
||||||
span,
|
span,
|
||||||
"item in documentation is missing backticks",
|
"item in documentation is missing backticks",
|
||||||
"try",
|
|diag| {
|
||||||
format!("`{}`", snippet_with_applicability(cx, span, "..", &mut applicability)),
|
let snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
|
||||||
applicability,
|
diag.span_suggestion_with_style(
|
||||||
|
span,
|
||||||
|
"try",
|
||||||
|
format!("`{}`", snippet),
|
||||||
|
applicability,
|
||||||
|
// always show the suggestion in a separate line, since the
|
||||||
|
// inline presentation adds another pair of backticks
|
||||||
|
SuggestionStyle::ShowAlways,
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// # let y = 2;
|
/// # let y = 2;
|
||||||
/// if x <= y {}
|
/// if x <= y {}
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DOUBLE_COMPARISONS,
|
pub DOUBLE_COMPARISONS,
|
||||||
complexity,
|
complexity,
|
||||||
"unnecessary double comparisons that can be simplified"
|
"unnecessary double comparisons that can be simplified"
|
||||||
|
|
|
@ -32,6 +32,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// foo(0);
|
/// foo(0);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DOUBLE_PARENS,
|
pub DOUBLE_PARENS,
|
||||||
complexity,
|
complexity,
|
||||||
"Warn on unnecessary double parentheses"
|
"Warn on unnecessary double parentheses"
|
||||||
|
|
|
@ -25,6 +25,7 @@ declare_clippy_lint! {
|
||||||
/// // still locked
|
/// // still locked
|
||||||
/// operation_that_requires_mutex_to_be_unlocked();
|
/// operation_that_requires_mutex_to_be_unlocked();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DROP_REF,
|
pub DROP_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::drop` with a reference instead of an owned value"
|
"calls to `std::mem::drop` with a reference instead of an owned value"
|
||||||
|
@ -46,6 +47,7 @@ declare_clippy_lint! {
|
||||||
/// let x = Box::new(1);
|
/// let x = Box::new(1);
|
||||||
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
|
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FORGET_REF,
|
pub FORGET_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::forget` with a reference instead of an owned value"
|
"calls to `std::mem::forget` with a reference instead of an owned value"
|
||||||
|
@ -67,6 +69,7 @@ declare_clippy_lint! {
|
||||||
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the
|
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the
|
||||||
/// // original unaffected
|
/// // original unaffected
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DROP_COPY,
|
pub DROP_COPY,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::drop` with a value that implements Copy"
|
"calls to `std::mem::drop` with a value that implements Copy"
|
||||||
|
@ -94,6 +97,7 @@ declare_clippy_lint! {
|
||||||
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the
|
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the
|
||||||
/// // original unaffected
|
/// // original unaffected
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FORGET_COPY,
|
pub FORGET_COPY,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::forget` with a value that implements Copy"
|
"calls to `std::mem::forget` with a value that implements Copy"
|
||||||
|
|
|
@ -33,6 +33,7 @@ declare_clippy_lint! {
|
||||||
/// let _micros = dur.subsec_micros();
|
/// let _micros = dur.subsec_micros();
|
||||||
/// let _millis = dur.subsec_millis();
|
/// let _millis = dur.subsec_millis();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DURATION_SUBSEC,
|
pub DURATION_SUBSEC,
|
||||||
complexity,
|
complexity,
|
||||||
"checks for calculation of subsecond microseconds or milliseconds"
|
"checks for calculation of subsecond microseconds or milliseconds"
|
||||||
|
|
|
@ -40,6 +40,7 @@ declare_clippy_lint! {
|
||||||
/// // We don't care about zero.
|
/// // We don't care about zero.
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ELSE_IF_WITHOUT_ELSE,
|
pub ELSE_IF_WITHOUT_ELSE,
|
||||||
restriction,
|
restriction,
|
||||||
"`if` expression with an `else if`, but without a final `else` branch"
|
"`if` expression with an `else if`, but without a final `else` branch"
|
||||||
|
|
|
@ -34,6 +34,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// struct Test(!);
|
/// struct Test(!);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EMPTY_ENUM,
|
pub EMPTY_ENUM,
|
||||||
pedantic,
|
pedantic,
|
||||||
"enum with no variants"
|
"enum with no variants"
|
||||||
|
|
|
@ -54,6 +54,7 @@ declare_clippy_lint! {
|
||||||
/// # let v = 1;
|
/// # let v = 1;
|
||||||
/// map.entry(k).or_insert(v);
|
/// map.entry(k).or_insert(v);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub MAP_ENTRY,
|
pub MAP_ENTRY,
|
||||||
perf,
|
perf,
|
||||||
"use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`"
|
"use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`"
|
||||||
|
|
|
@ -28,6 +28,7 @@ declare_clippy_lint! {
|
||||||
/// Y = 0,
|
/// Y = 0,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ENUM_CLIKE_UNPORTABLE_VARIANT,
|
pub ENUM_CLIKE_UNPORTABLE_VARIANT,
|
||||||
correctness,
|
correctness,
|
||||||
"C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`"
|
"C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`"
|
||||||
|
|
|
@ -34,6 +34,7 @@ declare_clippy_lint! {
|
||||||
/// Battenberg,
|
/// Battenberg,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ENUM_VARIANT_NAMES,
|
pub ENUM_VARIANT_NAMES,
|
||||||
style,
|
style,
|
||||||
"enums where all variants share a prefix/postfix"
|
"enums where all variants share a prefix/postfix"
|
||||||
|
@ -59,6 +60,7 @@ declare_clippy_lint! {
|
||||||
/// struct BlackForest;
|
/// struct BlackForest;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.33.0"]
|
||||||
pub MODULE_NAME_REPETITIONS,
|
pub MODULE_NAME_REPETITIONS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"type names prefixed/postfixed with their containing module's name"
|
"type names prefixed/postfixed with their containing module's name"
|
||||||
|
@ -89,6 +91,7 @@ declare_clippy_lint! {
|
||||||
/// ...
|
/// ...
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub MODULE_INCEPTION,
|
pub MODULE_INCEPTION,
|
||||||
style,
|
style,
|
||||||
"modules that have the same name as their parent module"
|
"modules that have the same name as their parent module"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
|
use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
|
||||||
use clippy_utils::source::snippet;
|
use clippy_utils::source::snippet;
|
||||||
use clippy_utils::ty::{implements_trait, is_copy};
|
use clippy_utils::ty::{implements_trait, is_copy};
|
||||||
use clippy_utils::{
|
use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, is_expn_of, is_in_test_function};
|
||||||
ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of, is_in_test_function,
|
|
||||||
};
|
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
|
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
|
||||||
|
@ -36,6 +34,7 @@ declare_clippy_lint! {
|
||||||
/// # let b = 4;
|
/// # let b = 4;
|
||||||
/// assert_eq!(a, a);
|
/// assert_eq!(a, a);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EQ_OP,
|
pub EQ_OP,
|
||||||
correctness,
|
correctness,
|
||||||
"equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)"
|
"equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)"
|
||||||
|
@ -61,6 +60,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// x == *y
|
/// x == *y
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub OP_REF,
|
pub OP_REF,
|
||||||
style,
|
style,
|
||||||
"taking a reference to satisfy the type constraints on `==`"
|
"taking a reference to satisfy the type constraints on `==`"
|
||||||
|
@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
|
||||||
}
|
}
|
||||||
let macro_with_not_op = |expr_kind: &ExprKind<'_>| {
|
let macro_with_not_op = |expr_kind: &ExprKind<'_>| {
|
||||||
if let ExprKind::Unary(_, expr) = *expr_kind {
|
if let ExprKind::Unary(_, expr) = *expr_kind {
|
||||||
in_macro(expr.span)
|
expr.span.from_expansion()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ declare_clippy_lint! {
|
||||||
/// do_thing();
|
/// do_thing();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.57.0"]
|
||||||
pub EQUATABLE_IF_LET,
|
pub EQUATABLE_IF_LET,
|
||||||
nursery,
|
nursery,
|
||||||
"using pattern matching instead of equality"
|
"using pattern matching instead of equality"
|
||||||
|
|
|
@ -21,6 +21,7 @@ declare_clippy_lint! {
|
||||||
/// 0 * x;
|
/// 0 * x;
|
||||||
/// x & 0;
|
/// x & 0;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub ERASING_OP,
|
pub ERASING_OP,
|
||||||
correctness,
|
correctness,
|
||||||
"using erasing operations, e.g., `x * 0` or `y & 0`"
|
"using erasing operations, e.g., `x * 0` or `y & 0`"
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// foo(x);
|
/// foo(x);
|
||||||
/// println!("{}", x);
|
/// println!("{}", x);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub BOXED_LOCAL,
|
pub BOXED_LOCAL,
|
||||||
perf,
|
perf,
|
||||||
"using `Box<T>` where unnecessary"
|
"using `Box<T>` where unnecessary"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::higher::VecArgs;
|
use clippy_utils::higher::VecArgs;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::usage::UsedAfterExprVisitor;
|
use clippy_utils::usage::local_used_after_expr;
|
||||||
use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local_id};
|
use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local, path_to_local_id};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
@ -39,6 +39,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
/// where `foo(_)` is a plain function that takes the exact argument type of
|
/// where `foo(_)` is a plain function that takes the exact argument type of
|
||||||
/// `x`.
|
/// `x`.
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub REDUNDANT_CLOSURE,
|
pub REDUNDANT_CLOSURE,
|
||||||
style,
|
style,
|
||||||
"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
|
"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
|
||||||
|
@ -60,6 +61,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// Some('a').map(char::to_uppercase);
|
/// Some('a').map(char::to_uppercase);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.35.0"]
|
||||||
pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
|
pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"redundant closures for method calls"
|
"redundant closures for method calls"
|
||||||
|
@ -118,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||||
if let ty::Closure(_, substs) = callee_ty.peel_refs().kind();
|
if let ty::Closure(_, substs) = callee_ty.peel_refs().kind();
|
||||||
if substs.as_closure().kind() == ClosureKind::FnMut;
|
if substs.as_closure().kind() == ClosureKind::FnMut;
|
||||||
if get_enclosing_loop_or_closure(cx.tcx, expr).is_some()
|
if get_enclosing_loop_or_closure(cx.tcx, expr).is_some()
|
||||||
|| UsedAfterExprVisitor::is_found(cx, callee);
|
|| path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, callee));
|
||||||
|
|
||||||
then {
|
then {
|
||||||
// Mutable closure is used after current expr; we cannot consume it.
|
// Mutable closure is used after current expr; we cannot consume it.
|
||||||
|
|
|
@ -40,6 +40,7 @@ declare_clippy_lint! {
|
||||||
/// };
|
/// };
|
||||||
/// let a = tmp + x;
|
/// let a = tmp + x;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EVAL_ORDER_DEPENDENCE,
|
pub EVAL_ORDER_DEPENDENCE,
|
||||||
suspicious,
|
suspicious,
|
||||||
"whether a variable read occurs before a write depends on sub-expression evaluation order"
|
"whether a variable read occurs before a write depends on sub-expression evaluation order"
|
||||||
|
@ -67,6 +68,7 @@ declare_clippy_lint! {
|
||||||
/// let x = (a, b, c, panic!());
|
/// let x = (a, b, c, panic!());
|
||||||
/// // can simply be replaced by `panic!()`
|
/// // can simply be replaced by `panic!()`
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub DIVERGING_SUB_EXPRESSION,
|
pub DIVERGING_SUB_EXPRESSION,
|
||||||
complexity,
|
complexity,
|
||||||
"whether an expression contains a diverging sub expression"
|
"whether an expression contains a diverging sub expression"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::in_macro;
|
|
||||||
use rustc_ast::ast::{AssocItemKind, Extern, Fn, FnSig, Impl, Item, ItemKind, Trait, Ty, TyKind};
|
use rustc_ast::ast::{AssocItemKind, Extern, Fn, FnSig, Impl, Item, ItemKind, Trait, Ty, TyKind};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
@ -38,6 +37,7 @@ declare_clippy_lint! {
|
||||||
/// Finished,
|
/// Finished,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.43.0"]
|
||||||
pub STRUCT_EXCESSIVE_BOOLS,
|
pub STRUCT_EXCESSIVE_BOOLS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"using too many bools in a struct"
|
"using too many bools in a struct"
|
||||||
|
@ -76,6 +76,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// fn f(shape: Shape, temperature: Temperature) { ... }
|
/// fn f(shape: Shape, temperature: Temperature) { ... }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.43.0"]
|
||||||
pub FN_PARAMS_EXCESSIVE_BOOLS,
|
pub FN_PARAMS_EXCESSIVE_BOOLS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"using too many bools in function parameters"
|
"using too many bools in function parameters"
|
||||||
|
@ -135,7 +136,7 @@ fn is_bool_ty(ty: &Ty) -> bool {
|
||||||
|
|
||||||
impl EarlyLintPass for ExcessiveBools {
|
impl EarlyLintPass for ExcessiveBools {
|
||||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||||
if in_macro(item.span) {
|
if item.span.from_expansion() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
|
|
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// Baz
|
/// Baz
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub EXHAUSTIVE_ENUMS,
|
pub EXHAUSTIVE_ENUMS,
|
||||||
restriction,
|
restriction,
|
||||||
"detects exported enums that have not been marked #[non_exhaustive]"
|
"detects exported enums that have not been marked #[non_exhaustive]"
|
||||||
|
@ -60,6 +61,7 @@ declare_clippy_lint! {
|
||||||
/// baz: String,
|
/// baz: String,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub EXHAUSTIVE_STRUCTS,
|
pub EXHAUSTIVE_STRUCTS,
|
||||||
restriction,
|
restriction,
|
||||||
"detects exported structs that have not been marked #[non_exhaustive]"
|
"detects exported structs that have not been marked #[non_exhaustive]"
|
||||||
|
|
|
@ -18,6 +18,7 @@ declare_clippy_lint! {
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// std::process::exit(0)
|
/// std::process::exit(0)
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.41.0"]
|
||||||
pub EXIT,
|
pub EXIT,
|
||||||
restriction,
|
restriction,
|
||||||
"`std::process::exit` is called, terminating the program"
|
"`std::process::exit` is called, terminating the program"
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare_clippy_lint! {
|
||||||
/// // this would be clearer as `eprintln!("foo: {:?}", bar);`
|
/// // this would be clearer as `eprintln!("foo: {:?}", bar);`
|
||||||
/// writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
|
/// writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EXPLICIT_WRITE,
|
pub EXPLICIT_WRITE,
|
||||||
complexity,
|
complexity,
|
||||||
"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work"
|
"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work"
|
||||||
|
|
|
@ -44,6 +44,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub FALLIBLE_IMPL_FROM,
|
pub FALLIBLE_IMPL_FROM,
|
||||||
nursery,
|
nursery,
|
||||||
"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`"
|
"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`"
|
||||||
|
|
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// ghi = []
|
/// ghi = []
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
#[clippy::version = "1.57.0"]
|
||||||
pub REDUNDANT_FEATURE_NAMES,
|
pub REDUNDANT_FEATURE_NAMES,
|
||||||
cargo,
|
cargo,
|
||||||
"usage of a redundant feature name"
|
"usage of a redundant feature name"
|
||||||
|
@ -60,6 +61,7 @@ declare_clippy_lint! {
|
||||||
/// def = []
|
/// def = []
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.57.0"]
|
||||||
pub NEGATIVE_FEATURE_NAMES,
|
pub NEGATIVE_FEATURE_NAMES,
|
||||||
cargo,
|
cargo,
|
||||||
"usage of a negative feature name"
|
"usage of a negative feature name"
|
||||||
|
|
|
@ -37,6 +37,7 @@ declare_clippy_lint! {
|
||||||
/// (a - b).abs() < f32::EPSILON
|
/// (a - b).abs() < f32::EPSILON
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.48.0"]
|
||||||
pub FLOAT_EQUALITY_WITHOUT_ABS,
|
pub FLOAT_EQUALITY_WITHOUT_ABS,
|
||||||
suspicious,
|
suspicious,
|
||||||
"float equality check without `.abs()`"
|
"float equality check without `.abs()`"
|
||||||
|
|
|
@ -27,6 +27,7 @@ declare_clippy_lint! {
|
||||||
/// let v: f64 = 0.123_456_789_9;
|
/// let v: f64 = 0.123_456_789_9;
|
||||||
/// println!("{}", v); // 0.123_456_789_9
|
/// println!("{}", v); // 0.123_456_789_9
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub EXCESSIVE_PRECISION,
|
pub EXCESSIVE_PRECISION,
|
||||||
style,
|
style,
|
||||||
"excessive precision for float literal"
|
"excessive precision for float literal"
|
||||||
|
@ -50,6 +51,7 @@ declare_clippy_lint! {
|
||||||
/// let _: f32 = 16_777_216.0;
|
/// let _: f32 = 16_777_216.0;
|
||||||
/// let _: f64 = 16_777_217.0;
|
/// let _: f64 = 16_777_217.0;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.43.0"]
|
||||||
pub LOSSY_FLOAT_LITERAL,
|
pub LOSSY_FLOAT_LITERAL,
|
||||||
restriction,
|
restriction,
|
||||||
"lossy whole number float literals"
|
"lossy whole number float literals"
|
||||||
|
|
|
@ -4,7 +4,7 @@ use clippy_utils::consts::{
|
||||||
};
|
};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::higher;
|
use clippy_utils::higher;
|
||||||
use clippy_utils::{eq_expr_value, get_parent_expr, numeric_literal, sugg};
|
use clippy_utils::{eq_expr_value, get_parent_expr, in_constant, numeric_literal, sugg};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp};
|
||||||
|
@ -43,6 +43,7 @@ declare_clippy_lint! {
|
||||||
/// let _ = a.ln_1p();
|
/// let _ = a.ln_1p();
|
||||||
/// let _ = a.exp_m1();
|
/// let _ = a.exp_m1();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.43.0"]
|
||||||
pub IMPRECISE_FLOPS,
|
pub IMPRECISE_FLOPS,
|
||||||
nursery,
|
nursery,
|
||||||
"usage of imprecise floating point operations"
|
"usage of imprecise floating point operations"
|
||||||
|
@ -99,6 +100,7 @@ declare_clippy_lint! {
|
||||||
/// let _ = a.abs();
|
/// let _ = a.abs();
|
||||||
/// let _ = -a.abs();
|
/// let _ = -a.abs();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.43.0"]
|
||||||
pub SUBOPTIMAL_FLOPS,
|
pub SUBOPTIMAL_FLOPS,
|
||||||
nursery,
|
nursery,
|
||||||
"usage of sub-optimal floating point operations"
|
"usage of sub-optimal floating point operations"
|
||||||
|
@ -685,6 +687,11 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
|
impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
|
// All of these operations are currently not const.
|
||||||
|
if in_constant(cx, expr.hir_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind {
|
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind {
|
||||||
let recv_ty = cx.typeck_results().expr_ty(&args[0]);
|
let recv_ty = cx.typeck_results().expr_ty(&args[0]);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ declare_clippy_lint! {
|
||||||
/// // Good
|
/// // Good
|
||||||
/// foo.to_owned();
|
/// foo.to_owned();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub USELESS_FORMAT,
|
pub USELESS_FORMAT,
|
||||||
complexity,
|
complexity,
|
||||||
"useless use of `format!`"
|
"useless use of `format!`"
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::{sym, BytePos, ExpnData, ExpnKind, Span, Symbol};
|
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
|
@ -31,6 +31,7 @@ declare_clippy_lint! {
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: something failed at {}", Location::caller());
|
/// println!("error: something failed at {}", Location::caller());
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.58.0"]
|
||||||
pub FORMAT_IN_FORMAT_ARGS,
|
pub FORMAT_IN_FORMAT_ARGS,
|
||||||
perf,
|
perf,
|
||||||
"`format!` used in a macro that does formatting"
|
"`format!` used in a macro that does formatting"
|
||||||
|
@ -56,6 +57,7 @@ declare_clippy_lint! {
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: something failed at {}", Location::caller());
|
/// println!("error: something failed at {}", Location::caller());
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.58.0"]
|
||||||
pub TO_STRING_IN_FORMAT_ARGS,
|
pub TO_STRING_IN_FORMAT_ARGS,
|
||||||
perf,
|
perf,
|
||||||
"`to_string` applied to a type that implements `Display` in format args"
|
"`to_string` applied to a type that implements `Display` in format args"
|
||||||
|
@ -128,7 +130,7 @@ fn check_format_in_format_args(cx: &LateContext<'_>, call_site: Span, name: Symb
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
FORMAT_IN_FORMAT_ARGS,
|
FORMAT_IN_FORMAT_ARGS,
|
||||||
trim_semicolon(cx, call_site),
|
call_site,
|
||||||
&format!("`format!` in `{}!` args", name),
|
&format!("`format!` in `{}!` args", name),
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.help(&format!(
|
diag.help(&format!(
|
||||||
|
@ -192,13 +194,6 @@ fn is_aliased(args: &[FormatArgsArg<'_>], i: usize) -> bool {
|
||||||
.any(|(j, arg)| i != j && std::ptr::eq(value, arg.value))
|
.any(|(j, arg)| i != j && std::ptr::eq(value, arg.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim_semicolon(cx: &LateContext<'_>, span: Span) -> Span {
|
|
||||||
snippet_opt(cx, span).map_or(span, |snippet| {
|
|
||||||
let snippet = snippet.trim_end_matches(';');
|
|
||||||
span.with_hi(span.lo() + BytePos(u32::try_from(snippet.len()).unwrap()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>)
|
fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>)
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'tcx Adjustment<'tcx>>,
|
I: Iterator<Item = &'tcx Adjustment<'tcx>>,
|
||||||
|
|
|
@ -21,6 +21,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
|
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
pub SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||||
suspicious,
|
suspicious,
|
||||||
"suspicious formatting of `*=`, `-=` or `!=`"
|
"suspicious formatting of `*=`, `-=` or `!=`"
|
||||||
|
@ -43,6 +44,7 @@ declare_clippy_lint! {
|
||||||
/// if foo &&! bar { // this should be `foo && !bar` but looks like a different operator
|
/// if foo &&! bar { // this should be `foo && !bar` but looks like a different operator
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub SUSPICIOUS_UNARY_OP_FORMATTING,
|
pub SUSPICIOUS_UNARY_OP_FORMATTING,
|
||||||
suspicious,
|
suspicious,
|
||||||
"suspicious formatting of unary `-` or `!` on the RHS of a BinOp"
|
"suspicious formatting of unary `-` or `!` on the RHS of a BinOp"
|
||||||
|
@ -79,6 +81,7 @@ declare_clippy_lint! {
|
||||||
/// if bar { // this is the `else` block of the previous `if`, but should it be?
|
/// if bar { // this is the `else` block of the previous `if`, but should it be?
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub SUSPICIOUS_ELSE_FORMATTING,
|
pub SUSPICIOUS_ELSE_FORMATTING,
|
||||||
suspicious,
|
suspicious,
|
||||||
"suspicious formatting of `else`"
|
"suspicious formatting of `else`"
|
||||||
|
@ -99,6 +102,7 @@ declare_clippy_lint! {
|
||||||
/// -4, -5, -6
|
/// -4, -5, -6
|
||||||
/// ];
|
/// ];
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub POSSIBLE_MISSING_COMMA,
|
pub POSSIBLE_MISSING_COMMA,
|
||||||
correctness,
|
correctness,
|
||||||
"possible missing comma in array"
|
"possible missing comma in array"
|
||||||
|
|
|
@ -34,6 +34,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.51.0"]
|
||||||
pub FROM_OVER_INTO,
|
pub FROM_OVER_INTO,
|
||||||
style,
|
style,
|
||||||
"Warns on implementations of `Into<..>` to use `From<..>`"
|
"Warns on implementations of `Into<..>` to use `From<..>`"
|
||||||
|
|
|
@ -35,6 +35,7 @@ declare_clippy_lint! {
|
||||||
/// let input: &str = get_input();
|
/// let input: &str = get_input();
|
||||||
/// let num: u16 = input.parse()?;
|
/// let num: u16 = input.parse()?;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.52.0"]
|
||||||
pub FROM_STR_RADIX_10,
|
pub FROM_STR_RADIX_10,
|
||||||
style,
|
style,
|
||||||
"from_str_radix with radix 10"
|
"from_str_radix with radix 10"
|
||||||
|
|
|
@ -26,6 +26,7 @@ declare_clippy_lint! {
|
||||||
/// // ..
|
/// // ..
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub TOO_MANY_ARGUMENTS,
|
pub TOO_MANY_ARGUMENTS,
|
||||||
complexity,
|
complexity,
|
||||||
"functions with too many arguments"
|
"functions with too many arguments"
|
||||||
|
@ -49,6 +50,7 @@ declare_clippy_lint! {
|
||||||
/// println!("");
|
/// println!("");
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.34.0"]
|
||||||
pub TOO_MANY_LINES,
|
pub TOO_MANY_LINES,
|
||||||
pedantic,
|
pedantic,
|
||||||
"functions with too many lines"
|
"functions with too many lines"
|
||||||
|
@ -84,6 +86,7 @@ declare_clippy_lint! {
|
||||||
/// println!("{}", unsafe { *x });
|
/// println!("{}", unsafe { *x });
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub NOT_UNSAFE_PTR_ARG_DEREF,
|
pub NOT_UNSAFE_PTR_ARG_DEREF,
|
||||||
correctness,
|
correctness,
|
||||||
"public functions dereferencing raw pointer arguments but not marked `unsafe`"
|
"public functions dereferencing raw pointer arguments but not marked `unsafe`"
|
||||||
|
@ -103,6 +106,7 @@ declare_clippy_lint! {
|
||||||
/// #[must_use]
|
/// #[must_use]
|
||||||
/// fn useless() { }
|
/// fn useless() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub MUST_USE_UNIT,
|
pub MUST_USE_UNIT,
|
||||||
style,
|
style,
|
||||||
"`#[must_use]` attribute on a unit-returning function / method"
|
"`#[must_use]` attribute on a unit-returning function / method"
|
||||||
|
@ -126,6 +130,7 @@ declare_clippy_lint! {
|
||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub DOUBLE_MUST_USE,
|
pub DOUBLE_MUST_USE,
|
||||||
style,
|
style,
|
||||||
"`#[must_use]` attribute on a `#[must_use]`-returning function / method"
|
"`#[must_use]` attribute on a `#[must_use]`-returning function / method"
|
||||||
|
@ -155,6 +160,7 @@ declare_clippy_lint! {
|
||||||
/// // this could be annotated with `#[must_use]`.
|
/// // this could be annotated with `#[must_use]`.
|
||||||
/// fn id<T>(t: T) -> T { t }
|
/// fn id<T>(t: T) -> T { t }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.40.0"]
|
||||||
pub MUST_USE_CANDIDATE,
|
pub MUST_USE_CANDIDATE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"function or method that could take a `#[must_use]` attribute"
|
"function or method that could take a `#[must_use]` attribute"
|
||||||
|
@ -204,6 +210,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// Note that there are crates that simplify creating the error type, e.g.
|
/// Note that there are crates that simplify creating the error type, e.g.
|
||||||
/// [`thiserror`](https://docs.rs/thiserror).
|
/// [`thiserror`](https://docs.rs/thiserror).
|
||||||
|
#[clippy::version = "1.49.0"]
|
||||||
pub RESULT_UNIT_ERR,
|
pub RESULT_UNIT_ERR,
|
||||||
style,
|
style,
|
||||||
"public function returning `Result` with an `Err` type of `()`"
|
"public function returning `Result` with an `Err` type of `()`"
|
||||||
|
|
|
@ -56,8 +56,8 @@ pub(super) fn check_fn(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let multi_idx = line.find("/*").unwrap_or_else(|| line.len());
|
let multi_idx = line.find("/*").unwrap_or(line.len());
|
||||||
let single_idx = line.find("//").unwrap_or_else(|| line.len());
|
let single_idx = line.find("//").unwrap_or(line.len());
|
||||||
code_in_line |= multi_idx > 0 && single_idx > 0;
|
code_in_line |= multi_idx > 0 && single_idx > 0;
|
||||||
// Implies multi_idx is below line.len()
|
// Implies multi_idx is below line.len()
|
||||||
if multi_idx < single_idx {
|
if multi_idx < single_idx {
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare_clippy_lint! {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
|
/// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.44.0"]
|
||||||
pub FUTURE_NOT_SEND,
|
pub FUTURE_NOT_SEND,
|
||||||
nursery,
|
nursery,
|
||||||
"public Futures must be Send"
|
"public Futures must be Send"
|
||||||
|
|
|
@ -39,6 +39,7 @@ declare_clippy_lint! {
|
||||||
/// let x = vec![2, 3, 5];
|
/// let x = vec![2, 3, 5];
|
||||||
/// let last_element = x.last();
|
/// let last_element = x.last();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.37.0"]
|
||||||
pub GET_LAST_WITH_LEN,
|
pub GET_LAST_WITH_LEN,
|
||||||
complexity,
|
complexity,
|
||||||
"Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler"
|
"Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler"
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare_clippy_lint! {
|
||||||
/// # let x = 1;
|
/// # let x = 1;
|
||||||
/// x / 1 + 0 * 1 - 0 | 0;
|
/// x / 1 + 0 * 1 - 0 | 0;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IDENTITY_OP,
|
pub IDENTITY_OP,
|
||||||
complexity,
|
complexity,
|
||||||
"using identity operations, e.g., `x + 0` or `y / 1`"
|
"using identity operations, e.g., `x + 0` or `y / 1`"
|
||||||
|
|
|
@ -36,6 +36,7 @@ declare_clippy_lint! {
|
||||||
/// use_locked(locked);
|
/// use_locked(locked);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.45.0"]
|
||||||
pub IF_LET_MUTEX,
|
pub IF_LET_MUTEX,
|
||||||
correctness,
|
correctness,
|
||||||
"locking a `Mutex` in an `if let` block can cause deadlocks"
|
"locking a `Mutex` in an `if let` block can cause deadlocks"
|
||||||
|
|
|
@ -39,6 +39,7 @@ declare_clippy_lint! {
|
||||||
/// a()
|
/// a()
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IF_NOT_ELSE,
|
pub IF_NOT_ELSE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`if` branches that could be swapped so no negation operation is necessary on the condition"
|
"`if` branches that could be swapped so no negation operation is necessary on the condition"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::source::snippet_with_macro_callsite;
|
use clippy_utils::source::snippet_with_macro_callsite;
|
||||||
use clippy_utils::{higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs};
|
use clippy_utils::{contains_return, higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
|
@ -36,6 +36,7 @@ declare_clippy_lint! {
|
||||||
/// 42
|
/// 42
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "1.53.0"]
|
||||||
pub IF_THEN_SOME_ELSE_NONE,
|
pub IF_THEN_SOME_ELSE_NONE,
|
||||||
restriction,
|
restriction,
|
||||||
"Finds if-else that could be written using `bool::then`"
|
"Finds if-else that could be written using `bool::then`"
|
||||||
|
@ -81,6 +82,7 @@ impl LateLintPass<'_> for IfThenSomeElseNone {
|
||||||
if let Some(els_expr) = els_block.expr;
|
if let Some(els_expr) = els_block.expr;
|
||||||
if let ExprKind::Path(ref qpath) = els_expr.kind;
|
if let ExprKind::Path(ref qpath) = els_expr.kind;
|
||||||
if is_lang_ctor(cx, qpath, OptionNone);
|
if is_lang_ctor(cx, qpath, OptionNone);
|
||||||
|
if !stmts_contains_early_return(then_block.stmts);
|
||||||
then {
|
then {
|
||||||
let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");
|
let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");
|
||||||
let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
|
let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) {
|
||||||
|
@ -113,3 +115,11 @@ impl LateLintPass<'_> for IfThenSomeElseNone {
|
||||||
|
|
||||||
extract_msrv_attr!(LateContext);
|
extract_msrv_attr!(LateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stmts_contains_early_return(stmts: &[Stmt<'_>]) -> bool {
|
||||||
|
stmts.iter().any(|stmt| {
|
||||||
|
let Stmt { kind: StmtKind::Semi(e), .. } = stmt else { return false };
|
||||||
|
|
||||||
|
contains_return(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// pub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }
|
/// pub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub IMPLICIT_HASHER,
|
pub IMPLICIT_HASHER,
|
||||||
pedantic,
|
pedantic,
|
||||||
"missing generalization over different hashers"
|
"missing generalization over different hashers"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue