mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 07:04:18 +00:00
Merge commit '09ac14c901abc43bd0d617ae4a44e8a4fed98d9c' into clippyup
This commit is contained in:
parent
aae86ccc47
commit
77c1e3aaa1
418 changed files with 4900 additions and 3588 deletions
2
.github/workflows/clippy.yml
vendored
2
.github/workflows/clippy.yml
vendored
|
@ -60,7 +60,7 @@ jobs:
|
||||||
working-directory: clippy_lints
|
working-directory: clippy_lints
|
||||||
|
|
||||||
- name: Test clippy_utils
|
- name: Test clippy_utils
|
||||||
run: cargo test --features deny-warnings,internal
|
run: cargo test --features deny-warnings
|
||||||
working-directory: clippy_utils
|
working-directory: clippy_utils
|
||||||
|
|
||||||
- name: Test rustc_tools_util
|
- name: Test rustc_tools_util
|
||||||
|
|
6
.github/workflows/clippy_bors.yml
vendored
6
.github/workflows/clippy_bors.yml
vendored
|
@ -120,9 +120,13 @@ jobs:
|
||||||
working-directory: clippy_lints
|
working-directory: clippy_lints
|
||||||
|
|
||||||
- name: Test clippy_utils
|
- name: Test clippy_utils
|
||||||
run: cargo test --features deny-warnings,internal
|
run: cargo test --features deny-warnings
|
||||||
working-directory: clippy_utils
|
working-directory: clippy_utils
|
||||||
|
|
||||||
|
- name: Test clippy_config
|
||||||
|
run: cargo test --features deny-warnings
|
||||||
|
working-directory: clippy_config
|
||||||
|
|
||||||
- name: Test rustc_tools_util
|
- name: Test rustc_tools_util
|
||||||
run: cargo test --features deny-warnings
|
run: cargo test --features deny-warnings
|
||||||
working-directory: rustc_tools_util
|
working-directory: rustc_tools_util
|
||||||
|
|
|
@ -5528,6 +5528,7 @@ Released 2018-09-13
|
||||||
[`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#unknown_clippy_lints
|
[`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#unknown_clippy_lints
|
||||||
[`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns
|
[`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns
|
||||||
[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
|
[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
|
||||||
|
[`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions
|
||||||
[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
|
[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
|
||||||
[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map
|
[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map
|
||||||
[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
|
[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
|
||||||
|
@ -5560,6 +5561,7 @@ Released 2018-09-13
|
||||||
[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice
|
[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice
|
||||||
[`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async
|
[`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async
|
||||||
[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
|
[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
|
||||||
|
[`unused_enumerate_index`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_enumerate_index
|
||||||
[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs
|
[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs
|
||||||
[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
|
[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
|
||||||
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
|
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
|
||||||
|
@ -5589,6 +5591,7 @@ Released 2018-09-13
|
||||||
[`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask
|
[`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask
|
||||||
[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads
|
[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads
|
||||||
[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons
|
[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons
|
||||||
|
[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/master/index.html#waker_clone_wake
|
||||||
[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition
|
[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition
|
||||||
[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop
|
[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop
|
||||||
[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
|
[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
|
||||||
|
|
|
@ -21,11 +21,12 @@ name = "clippy-driver"
|
||||||
path = "src/driver.rs"
|
path = "src/driver.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clippy_config = { path = "clippy_config" }
|
||||||
clippy_lints = { path = "clippy_lints" }
|
clippy_lints = { path = "clippy_lints" }
|
||||||
rustc_tools_util = "0.3.0"
|
rustc_tools_util = "0.3.0"
|
||||||
tempfile = { version = "3.2", optional = true }
|
tempfile = { version = "3.2", optional = true }
|
||||||
termize = "0.1"
|
termize = "0.1"
|
||||||
color-print = "0.3.4" # Sync version with Cargo
|
color-print = "0.3.4"
|
||||||
anstream = "0.5.0"
|
anstream = "0.5.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -26,7 +26,7 @@ arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
|
||||||
A type, say `SomeType`, listed in this configuration has the same behavior of
|
A type, say `SomeType`, listed in this configuration has the same behavior of
|
||||||
`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
||||||
|
|
||||||
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -49,7 +49,7 @@ Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the
|
||||||
arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
|
arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<[String; 2]>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -65,7 +65,7 @@ Suppress checking of the passed type names in unary operations like "negation" (
|
||||||
arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -75,7 +75,7 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
||||||
## `avoid-breaking-exported-api`
|
## `avoid-breaking-exported-api`
|
||||||
Suppress lints whenever the suggested change would cause breakage for other crates.
|
Suppress lints whenever the suggested change would cause breakage for other crates.
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -98,9 +98,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat
|
||||||
|
|
||||||
|
|
||||||
## `msrv`
|
## `msrv`
|
||||||
The minimum rust version that the project supports
|
The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
|
||||||
|
|
||||||
**Default Value:** `Msrv { stack: [] }` (`crate::Msrv`)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -157,7 +155,7 @@ The minimum rust version that the project supports
|
||||||
## `cognitive-complexity-threshold`
|
## `cognitive-complexity-threshold`
|
||||||
The maximum cognitive complexity a function can have
|
The maximum cognitive complexity a function can have
|
||||||
|
|
||||||
**Default Value:** `25` (`u64`)
|
**Default Value:** `25`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -167,7 +165,7 @@ The maximum cognitive complexity a function can have
|
||||||
## `excessive-nesting-threshold`
|
## `excessive-nesting-threshold`
|
||||||
The maximum amount of nesting a block can reside in
|
The maximum amount of nesting a block can reside in
|
||||||
|
|
||||||
**Default Value:** `0` (`u64`)
|
**Default Value:** `0`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -179,7 +177,7 @@ The list of disallowed names to lint about. NB: `bar` is not here since it has l
|
||||||
`".."` can be used as part of the list to indicate that the configured values should be appended to the
|
`".."` can be used as part of the list to indicate that the configured values should be appended to the
|
||||||
default configuration of Clippy. By default, any configuration will replace the default value.
|
default configuration of Clippy. By default, any configuration will replace the default value.
|
||||||
|
|
||||||
**Default Value:** `["foo", "baz", "quux"]` (`Vec<String>`)
|
**Default Value:** `["foo", "baz", "quux"]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -189,7 +187,7 @@ default configuration of Clippy. By default, any configuration will replace the
|
||||||
## `semicolon-inside-block-ignore-singleline`
|
## `semicolon-inside-block-ignore-singleline`
|
||||||
Whether to lint only if it's multiline.
|
Whether to lint only if it's multiline.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -199,7 +197,7 @@ Whether to lint only if it's multiline.
|
||||||
## `semicolon-outside-block-ignore-multiline`
|
## `semicolon-outside-block-ignore-multiline`
|
||||||
Whether to lint only if it's singleline.
|
Whether to lint only if it's singleline.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -213,9 +211,7 @@ default configuration of Clippy. By default, any configuration will replace the
|
||||||
* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
|
* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
|
||||||
* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
|
* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
|
||||||
|
|
||||||
Default list:
|
**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
|
||||||
|
|
||||||
**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` (`Vec<String>`)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -225,7 +221,7 @@ Default list:
|
||||||
## `too-many-arguments-threshold`
|
## `too-many-arguments-threshold`
|
||||||
The maximum number of argument a function or method can have
|
The maximum number of argument a function or method can have
|
||||||
|
|
||||||
**Default Value:** `7` (`u64`)
|
**Default Value:** `7`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -235,7 +231,7 @@ The maximum number of argument a function or method can have
|
||||||
## `type-complexity-threshold`
|
## `type-complexity-threshold`
|
||||||
The maximum complexity a type can have
|
The maximum complexity a type can have
|
||||||
|
|
||||||
**Default Value:** `250` (`u64`)
|
**Default Value:** `250`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -245,7 +241,7 @@ The maximum complexity a type can have
|
||||||
## `single-char-binding-names-threshold`
|
## `single-char-binding-names-threshold`
|
||||||
The maximum number of single char bindings a scope may have
|
The maximum number of single char bindings a scope may have
|
||||||
|
|
||||||
**Default Value:** `4` (`u64`)
|
**Default Value:** `4`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -255,7 +251,7 @@ The maximum number of single char bindings a scope may have
|
||||||
## `too-large-for-stack`
|
## `too-large-for-stack`
|
||||||
The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
|
The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
|
||||||
|
|
||||||
**Default Value:** `200` (`u64`)
|
**Default Value:** `200`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -266,7 +262,7 @@ The maximum size of objects (in bytes) that will be linted. Larger objects are o
|
||||||
## `enum-variant-name-threshold`
|
## `enum-variant-name-threshold`
|
||||||
The minimum number of enum variants for the lints about variant names to trigger
|
The minimum number of enum variants for the lints about variant names to trigger
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -276,7 +272,7 @@ The minimum number of enum variants for the lints about variant names to trigger
|
||||||
## `struct-field-name-threshold`
|
## `struct-field-name-threshold`
|
||||||
The minimum number of struct fields for the lints about field names to trigger
|
The minimum number of struct fields for the lints about field names to trigger
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -286,7 +282,7 @@ The minimum number of struct fields for the lints about field names to trigger
|
||||||
## `enum-variant-size-threshold`
|
## `enum-variant-size-threshold`
|
||||||
The maximum size of an enum's variant to avoid box suggestion
|
The maximum size of an enum's variant to avoid box suggestion
|
||||||
|
|
||||||
**Default Value:** `200` (`u64`)
|
**Default Value:** `200`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -296,7 +292,7 @@ The maximum size of an enum's variant to avoid box suggestion
|
||||||
## `verbose-bit-mask-threshold`
|
## `verbose-bit-mask-threshold`
|
||||||
The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
|
The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
|
||||||
|
|
||||||
**Default Value:** `1` (`u64`)
|
**Default Value:** `1`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -306,7 +302,7 @@ The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
|
||||||
## `literal-representation-threshold`
|
## `literal-representation-threshold`
|
||||||
The lower bound for linting decimal literals
|
The lower bound for linting decimal literals
|
||||||
|
|
||||||
**Default Value:** `16384` (`u64`)
|
**Default Value:** `16384`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -314,9 +310,8 @@ The lower bound for linting decimal literals
|
||||||
|
|
||||||
|
|
||||||
## `trivial-copy-size-limit`
|
## `trivial-copy-size-limit`
|
||||||
The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference.
|
The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
|
||||||
|
reference. By default there is no limit
|
||||||
**Default Value:** `None` (`Option<u64>`)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -326,7 +321,7 @@ The maximum size (in bytes) to consider a `Copy` type for passing by value inste
|
||||||
## `pass-by-value-size-limit`
|
## `pass-by-value-size-limit`
|
||||||
The minimum size (in bytes) to consider a type for passing by reference instead of by value.
|
The minimum size (in bytes) to consider a type for passing by reference instead of by value.
|
||||||
|
|
||||||
**Default Value:** `256` (`u64`)
|
**Default Value:** `256`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -336,7 +331,7 @@ The minimum size (in bytes) to consider a type for passing by reference instead
|
||||||
## `too-many-lines-threshold`
|
## `too-many-lines-threshold`
|
||||||
The maximum number of lines a function or method can have
|
The maximum number of lines a function or method can have
|
||||||
|
|
||||||
**Default Value:** `100` (`u64`)
|
**Default Value:** `100`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -346,7 +341,7 @@ The maximum number of lines a function or method can have
|
||||||
## `array-size-threshold`
|
## `array-size-threshold`
|
||||||
The maximum allowed size for arrays on the stack
|
The maximum allowed size for arrays on the stack
|
||||||
|
|
||||||
**Default Value:** `512000` (`u64`)
|
**Default Value:** `512000`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -357,7 +352,7 @@ The maximum allowed size for arrays on the stack
|
||||||
## `stack-size-threshold`
|
## `stack-size-threshold`
|
||||||
The maximum allowed stack size for functions in bytes
|
The maximum allowed stack size for functions in bytes
|
||||||
|
|
||||||
**Default Value:** `512000` (`u64`)
|
**Default Value:** `512000`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -367,7 +362,7 @@ The maximum allowed stack size for functions in bytes
|
||||||
## `vec-box-size-threshold`
|
## `vec-box-size-threshold`
|
||||||
The size of the boxed type in bytes, where boxing in a `Vec` is allowed
|
The size of the boxed type in bytes, where boxing in a `Vec` is allowed
|
||||||
|
|
||||||
**Default Value:** `4096` (`u64`)
|
**Default Value:** `4096`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -377,7 +372,7 @@ The size of the boxed type in bytes, where boxing in a `Vec` is allowed
|
||||||
## `max-trait-bounds`
|
## `max-trait-bounds`
|
||||||
The maximum number of bounds a trait can have to be linted
|
The maximum number of bounds a trait can have to be linted
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -387,7 +382,7 @@ The maximum number of bounds a trait can have to be linted
|
||||||
## `max-struct-bools`
|
## `max-struct-bools`
|
||||||
The maximum number of bool fields a struct can have
|
The maximum number of bool fields a struct can have
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -397,7 +392,7 @@ The maximum number of bool fields a struct can have
|
||||||
## `max-fn-params-bools`
|
## `max-fn-params-bools`
|
||||||
The maximum number of bool parameters a function can have
|
The maximum number of bool parameters a function can have
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -407,7 +402,7 @@ The maximum number of bool parameters a function can have
|
||||||
## `warn-on-all-wildcard-imports`
|
## `warn-on-all-wildcard-imports`
|
||||||
Whether to allow certain wildcard imports (prelude, super in tests).
|
Whether to allow certain wildcard imports (prelude, super in tests).
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -417,7 +412,7 @@ Whether to allow certain wildcard imports (prelude, super in tests).
|
||||||
## `disallowed-macros`
|
## `disallowed-macros`
|
||||||
The list of disallowed macros, written as fully qualified paths.
|
The list of disallowed macros, written as fully qualified paths.
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -427,7 +422,7 @@ The list of disallowed macros, written as fully qualified paths.
|
||||||
## `disallowed-methods`
|
## `disallowed-methods`
|
||||||
The list of disallowed methods, written as fully qualified paths.
|
The list of disallowed methods, written as fully qualified paths.
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -437,7 +432,7 @@ The list of disallowed methods, written as fully qualified paths.
|
||||||
## `disallowed-types`
|
## `disallowed-types`
|
||||||
The list of disallowed types, written as fully qualified paths.
|
The list of disallowed types, written as fully qualified paths.
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -447,7 +442,7 @@ The list of disallowed types, written as fully qualified paths.
|
||||||
## `unreadable-literal-lint-fractions`
|
## `unreadable-literal-lint-fractions`
|
||||||
Should the fraction of a decimal be linted to include separators.
|
Should the fraction of a decimal be linted to include separators.
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -457,7 +452,7 @@ Should the fraction of a decimal be linted to include separators.
|
||||||
## `upper-case-acronyms-aggressive`
|
## `upper-case-acronyms-aggressive`
|
||||||
Enables verbose mode. Triggers if there is more than one uppercase char next to each other
|
Enables verbose mode. Triggers if there is more than one uppercase char next to each other
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -468,7 +463,7 @@ Enables verbose mode. Triggers if there is more than one uppercase char next to
|
||||||
Whether the matches should be considered by the lint, and whether there should
|
Whether the matches should be considered by the lint, and whether there should
|
||||||
be filtering for common types.
|
be filtering for common types.
|
||||||
|
|
||||||
**Default Value:** `WellKnownTypes` (`crate::manual_let_else::MatchLintBehaviour`)
|
**Default Value:** `"WellKnownTypes"`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -478,11 +473,11 @@ be filtering for common types.
|
||||||
## `cargo-ignore-publish`
|
## `cargo-ignore-publish`
|
||||||
For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
* [`_cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata)
|
* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)
|
||||||
|
|
||||||
|
|
||||||
## `standard-macro-braces`
|
## `standard-macro-braces`
|
||||||
|
@ -492,7 +487,7 @@ A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If
|
||||||
could be used with a full path two `MacroMatcher`s have to be added one with the full path
|
could be used with a full path two `MacroMatcher`s have to be added one with the full path
|
||||||
`crate_name::macro_name` and one with just the macro name.
|
`crate_name::macro_name` and one with just the macro name.
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::nonstandard_macro_braces::MacroMatcher>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -502,7 +497,7 @@ could be used with a full path two `MacroMatcher`s have to be added one with the
|
||||||
## `enforced-import-renames`
|
## `enforced-import-renames`
|
||||||
The list of imports to always rename, a fully qualified path followed by the rename.
|
The list of imports to always rename, a fully qualified path followed by the rename.
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::utils::conf::Rename>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -512,7 +507,7 @@ The list of imports to always rename, a fully qualified path followed by the ren
|
||||||
## `allowed-scripts`
|
## `allowed-scripts`
|
||||||
The list of unicode scripts allowed to be used in the scope.
|
The list of unicode scripts allowed to be used in the scope.
|
||||||
|
|
||||||
**Default Value:** `["Latin"]` (`Vec<String>`)
|
**Default Value:** `["Latin"]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -522,7 +517,7 @@ The list of unicode scripts allowed to be used in the scope.
|
||||||
## `enable-raw-pointer-heuristic-for-send`
|
## `enable-raw-pointer-heuristic-for-send`
|
||||||
Whether to apply the raw pointer heuristic to determine if a type is `Send`.
|
Whether to apply the raw pointer heuristic to determine if a type is `Send`.
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -534,7 +529,7 @@ When Clippy suggests using a slice pattern, this is the maximum number of elemen
|
||||||
the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
|
the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
|
||||||
For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||||
|
|
||||||
**Default Value:** `3` (`u64`)
|
**Default Value:** `3`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -544,7 +539,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||||
## `await-holding-invalid-types`
|
## `await-holding-invalid-types`
|
||||||
|
|
||||||
|
|
||||||
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -554,7 +549,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||||
## `max-include-file-size`
|
## `max-include-file-size`
|
||||||
The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||||
|
|
||||||
**Default Value:** `1000000` (`u64`)
|
**Default Value:** `1000000`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -564,7 +559,7 @@ The maximum size of a file included via `include_bytes!()` or `include_str!()`,
|
||||||
## `allow-expect-in-tests`
|
## `allow-expect-in-tests`
|
||||||
Whether `expect` should be allowed in test functions or `#[cfg(test)]`
|
Whether `expect` should be allowed in test functions or `#[cfg(test)]`
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -574,7 +569,7 @@ Whether `expect` should be allowed in test functions or `#[cfg(test)]`
|
||||||
## `allow-unwrap-in-tests`
|
## `allow-unwrap-in-tests`
|
||||||
Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
|
Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -584,7 +579,7 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
|
||||||
## `allow-dbg-in-tests`
|
## `allow-dbg-in-tests`
|
||||||
Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
|
Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -594,7 +589,7 @@ Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
|
||||||
## `allow-print-in-tests`
|
## `allow-print-in-tests`
|
||||||
Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
|
Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -605,7 +600,7 @@ Whether print macros (ex. `println!`) should be allowed in test functions or `#[
|
||||||
## `large-error-threshold`
|
## `large-error-threshold`
|
||||||
The maximum size of the `Err`-variant in a `Result` returned from a function
|
The maximum size of the `Err`-variant in a `Result` returned from a function
|
||||||
|
|
||||||
**Default Value:** `128` (`u64`)
|
**Default Value:** `128`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -616,7 +611,7 @@ The maximum size of the `Err`-variant in a `Result` returned from a function
|
||||||
A list of paths to types that should be treated like `Arc`, i.e. ignored but
|
A list of paths to types that should be treated like `Arc`, i.e. ignored but
|
||||||
for the generic parameters for determining interior mutability
|
for the generic parameters for determining interior mutability
|
||||||
|
|
||||||
**Default Value:** `["bytes::Bytes"]` (`Vec<String>`)
|
**Default Value:** `["bytes::Bytes"]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -627,7 +622,7 @@ for the generic parameters for determining interior mutability
|
||||||
## `allow-mixed-uninlined-format-args`
|
## `allow-mixed-uninlined-format-args`
|
||||||
Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
|
Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -641,7 +636,7 @@ suggested counterparts are unavailable in constant code. This
|
||||||
configuration will cause restriction lints to trigger even
|
configuration will cause restriction lints to trigger even
|
||||||
if no suggestion can be made.
|
if no suggestion can be made.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -652,7 +647,7 @@ if no suggestion can be made.
|
||||||
Whether to **only** check for missing documentation in items visible within the current
|
Whether to **only** check for missing documentation in items visible within the current
|
||||||
crate. For example, `pub(crate)` items.
|
crate. For example, `pub(crate)` items.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -662,7 +657,7 @@ crate. For example, `pub(crate)` items.
|
||||||
## `future-size-threshold`
|
## `future-size-threshold`
|
||||||
The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
|
The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
|
||||||
|
|
||||||
**Default Value:** `16384` (`u64`)
|
**Default Value:** `16384`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -672,7 +667,7 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large
|
||||||
## `unnecessary-box-size`
|
## `unnecessary-box-size`
|
||||||
The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
||||||
|
|
||||||
**Default Value:** `128` (`u64`)
|
**Default Value:** `128`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -682,7 +677,7 @@ The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::u
|
||||||
## `allow-private-module-inception`
|
## `allow-private-module-inception`
|
||||||
Whether to allow module inception if it's not public.
|
Whether to allow module inception if it's not public.
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -694,7 +689,7 @@ Allowed names below the minimum allowed characters. The value `".."` can be used
|
||||||
the list to indicate, that the configured values should be appended to the default
|
the list to indicate, that the configured values should be appended to the default
|
||||||
configuration of Clippy. By default, any configuration will replace the default value.
|
configuration of Clippy. By default, any configuration will replace the default value.
|
||||||
|
|
||||||
**Default Value:** `{"j", "z", "i", "y", "n", "x", "w"}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -704,7 +699,7 @@ configuration of Clippy. By default, any configuration will replace the default
|
||||||
## `min-ident-chars-threshold`
|
## `min-ident-chars-threshold`
|
||||||
Minimum chars an ident can have, anything below or equal to this will be linted.
|
Minimum chars an ident can have, anything below or equal to this will be linted.
|
||||||
|
|
||||||
**Default Value:** `1` (`u64`)
|
**Default Value:** `1`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -714,7 +709,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
|
||||||
## `accept-comment-above-statement`
|
## `accept-comment-above-statement`
|
||||||
Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
|
Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -724,7 +719,7 @@ Whether to accept a safety comment to be placed above the statement containing t
|
||||||
## `accept-comment-above-attributes`
|
## `accept-comment-above-attributes`
|
||||||
Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
|
Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
|
||||||
|
|
||||||
**Default Value:** `true` (`bool`)
|
**Default Value:** `true`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -734,7 +729,7 @@ Whether to accept a safety comment to be placed above the attributes for the `un
|
||||||
## `allow-one-hash-in-raw-strings`
|
## `allow-one-hash-in-raw-strings`
|
||||||
Whether to allow `r#""#` when `r""` can be used
|
Whether to allow `r#""#` when `r""` can be used
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -745,7 +740,7 @@ Whether to allow `r#""#` when `r""` can be used
|
||||||
The maximum number of segments a path can have before being linted, anything above this will
|
The maximum number of segments a path can have before being linted, anything above this will
|
||||||
be linted.
|
be linted.
|
||||||
|
|
||||||
**Default Value:** `2` (`u64`)
|
**Default Value:** `2`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -755,7 +750,7 @@ be linted.
|
||||||
## `absolute-paths-allowed-crates`
|
## `absolute-paths-allowed-crates`
|
||||||
Which crates to allow absolute paths from
|
Which crates to allow absolute paths from
|
||||||
|
|
||||||
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -765,7 +760,7 @@ Which crates to allow absolute paths from
|
||||||
## `allowed-dotfiles`
|
## `allowed-dotfiles`
|
||||||
Additional dotfiles (files or directories starting with a dot) to allow
|
Additional dotfiles (files or directories starting with a dot) to allow
|
||||||
|
|
||||||
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
**Default Value:** `[]`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
@ -774,7 +769,7 @@ Additional dotfiles (files or directories starting with a dot) to allow
|
||||||
|
|
||||||
## `enforce-iter-loop-reborrow`
|
## `enforce-iter-loop-reborrow`
|
||||||
#### Example
|
#### Example
|
||||||
```
|
```no_run
|
||||||
let mut vec = vec![1, 2, 3];
|
let mut vec = vec![1, 2, 3];
|
||||||
let rmvec = &mut vec;
|
let rmvec = &mut vec;
|
||||||
for _ in rmvec.iter() {}
|
for _ in rmvec.iter() {}
|
||||||
|
@ -782,14 +777,14 @@ for _ in rmvec.iter_mut() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
Use instead:
|
Use instead:
|
||||||
```
|
```no_run
|
||||||
let mut vec = vec![1, 2, 3];
|
let mut vec = vec![1, 2, 3];
|
||||||
let rmvec = &mut vec;
|
let rmvec = &mut vec;
|
||||||
for _ in &*rmvec {}
|
for _ in &*rmvec {}
|
||||||
for _ in &mut *rmvec {}
|
for _ in &mut *rmvec {}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Default Value:** `false` (`bool`)
|
**Default Value:** `false`
|
||||||
|
|
||||||
---
|
---
|
||||||
**Affected lints:**
|
**Affected lints:**
|
||||||
|
|
21
clippy_config/Cargo.toml
Normal file
21
clippy_config/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[package]
|
||||||
|
name = "clippy_config"
|
||||||
|
version = "0.1.75"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rustc-semver = "1.1"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
toml = "0.7.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
walkdir = "2.3"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
deny-warnings = []
|
||||||
|
|
||||||
|
[package.metadata.rust-analyzer]
|
||||||
|
# This crate uses #[feature(rustc_private)]
|
||||||
|
rustc_private = true
|
|
@ -1,11 +1,11 @@
|
||||||
//! Read configurations files.
|
use crate::msrvs::Msrv;
|
||||||
|
use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename};
|
||||||
#![allow(clippy::module_name_repetitions)]
|
use crate::ClippyConfiguration;
|
||||||
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
|
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
|
||||||
use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor};
|
use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -38,43 +38,12 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
|
||||||
const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"];
|
const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"];
|
||||||
const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"];
|
const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"];
|
||||||
|
|
||||||
/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
|
||||||
pub struct Rename {
|
|
||||||
pub path: String,
|
|
||||||
pub rename: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum DisallowedPath {
|
|
||||||
Simple(String),
|
|
||||||
WithReason { path: String, reason: Option<String> },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DisallowedPath {
|
|
||||||
pub fn path(&self) -> &str {
|
|
||||||
let (Self::Simple(path) | Self::WithReason { path, .. }) = self;
|
|
||||||
|
|
||||||
path
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reason(&self) -> Option<String> {
|
|
||||||
match self {
|
|
||||||
Self::WithReason {
|
|
||||||
reason: Some(reason), ..
|
|
||||||
} => Some(format!("{reason} (from clippy.toml)")),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Conf with parse errors
|
/// Conf with parse errors
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TryConf {
|
struct TryConf {
|
||||||
pub conf: Conf,
|
conf: Conf,
|
||||||
pub errors: Vec<ConfError>,
|
errors: Vec<ConfError>,
|
||||||
pub warnings: Vec<ConfError>,
|
warnings: Vec<ConfError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryConf {
|
impl TryConf {
|
||||||
|
@ -88,9 +57,9 @@ impl TryConf {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ConfError {
|
struct ConfError {
|
||||||
pub message: String,
|
message: String,
|
||||||
pub span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfError {
|
impl ConfError {
|
||||||
|
@ -112,10 +81,31 @@ impl ConfError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! wrap_option {
|
||||||
|
() => {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
($x:literal) => {
|
||||||
|
Some($x)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! default_text {
|
||||||
|
($value:expr) => {{
|
||||||
|
let mut text = String::new();
|
||||||
|
$value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap();
|
||||||
|
text
|
||||||
|
}};
|
||||||
|
($value:expr, $override:expr) => {
|
||||||
|
$override.to_string()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! define_Conf {
|
macro_rules! define_Conf {
|
||||||
($(
|
($(
|
||||||
$(#[doc = $doc:literal])+
|
$(#[doc = $doc:literal])+
|
||||||
$(#[conf_deprecated($dep:literal, $new_conf:ident)])?
|
$(#[conf_deprecated($dep:literal, $new_conf:ident)])?
|
||||||
|
$(#[default_text = $default_text:expr])?
|
||||||
($name:ident: $ty:ty = $default:expr),
|
($name:ident: $ty:ty = $default:expr),
|
||||||
)*) => {
|
)*) => {
|
||||||
/// Clippy lint configuration
|
/// Clippy lint configuration
|
||||||
|
@ -124,6 +114,7 @@ macro_rules! define_Conf {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod defaults {
|
mod defaults {
|
||||||
|
use super::*;
|
||||||
$(pub fn $name() -> $ty { $default })*
|
$(pub fn $name() -> $ty { $default })*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,31 +181,21 @@ macro_rules! define_Conf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod metadata {
|
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
|
||||||
use crate::utils::ClippyConfiguration;
|
vec![
|
||||||
|
$(
|
||||||
|
{
|
||||||
|
let deprecation_reason = wrap_option!($($dep)?);
|
||||||
|
|
||||||
macro_rules! wrap_option {
|
ClippyConfiguration::new(
|
||||||
() => (None);
|
stringify!($name),
|
||||||
($x:literal) => (Some($x));
|
default_text!(defaults::$name() $(, $default_text)?),
|
||||||
}
|
concat!($($doc, '\n',)*),
|
||||||
|
deprecation_reason,
|
||||||
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
|
)
|
||||||
vec![
|
},
|
||||||
$(
|
)+
|
||||||
{
|
]
|
||||||
let deprecation_reason = wrap_option!($($dep)?);
|
|
||||||
|
|
||||||
ClippyConfiguration::new(
|
|
||||||
stringify!($name),
|
|
||||||
stringify!($ty),
|
|
||||||
format!("{:?}", super::defaults::$name()),
|
|
||||||
concat!($($doc, '\n',)*),
|
|
||||||
deprecation_reason,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)+
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -236,7 +217,7 @@ define_Conf! {
|
||||||
///
|
///
|
||||||
/// A type, say `SomeType`, listed in this configuration has the same behavior of
|
/// A type, say `SomeType`, listed in this configuration has the same behavior of
|
||||||
/// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
/// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
||||||
(arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
|
(arithmetic_side_effects_allowed: FxHashSet<String> = <_>::default()),
|
||||||
/// Lint: ARITHMETIC_SIDE_EFFECTS.
|
/// Lint: ARITHMETIC_SIDE_EFFECTS.
|
||||||
///
|
///
|
||||||
/// Suppress checking of the passed type pair names in binary operations like addition or
|
/// Suppress checking of the passed type pair names in binary operations like addition or
|
||||||
|
@ -263,15 +244,16 @@ define_Conf! {
|
||||||
/// ```toml
|
/// ```toml
|
||||||
/// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
/// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
||||||
/// ```
|
/// ```
|
||||||
(arithmetic_side_effects_allowed_unary: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
|
(arithmetic_side_effects_allowed_unary: FxHashSet<String> = <_>::default()),
|
||||||
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN.
|
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN.
|
||||||
///
|
///
|
||||||
/// Suppress lints whenever the suggested change would cause breakage for other crates.
|
/// Suppress lints whenever the suggested change would cause breakage for other crates.
|
||||||
(avoid_breaking_exported_api: bool = true),
|
(avoid_breaking_exported_api: bool = true),
|
||||||
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE.
|
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE.
|
||||||
///
|
///
|
||||||
/// The minimum rust version that the project supports
|
/// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
|
||||||
(msrv: crate::Msrv = crate::Msrv::empty()),
|
#[default_text = ""]
|
||||||
|
(msrv: Msrv = Msrv::empty()),
|
||||||
/// DEPRECATED LINT: BLACKLISTED_NAME.
|
/// DEPRECATED LINT: BLACKLISTED_NAME.
|
||||||
///
|
///
|
||||||
/// Use the Disallowed Names lint instead
|
/// Use the Disallowed Names lint instead
|
||||||
|
@ -295,7 +277,7 @@ define_Conf! {
|
||||||
/// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
|
/// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
|
||||||
/// `".."` can be used as part of the list to indicate that the configured values should be appended to the
|
/// `".."` can be used as part of the list to indicate that the configured values should be appended to the
|
||||||
/// default configuration of Clippy. By default, any configuration will replace the default value.
|
/// default configuration of Clippy. By default, any configuration will replace the default value.
|
||||||
(disallowed_names: Vec<String> = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()),
|
(disallowed_names: Vec<String> = DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()),
|
||||||
/// Lint: SEMICOLON_INSIDE_BLOCK.
|
/// Lint: SEMICOLON_INSIDE_BLOCK.
|
||||||
///
|
///
|
||||||
/// Whether to lint only if it's multiline.
|
/// Whether to lint only if it's multiline.
|
||||||
|
@ -311,9 +293,7 @@ define_Conf! {
|
||||||
/// default configuration of Clippy. By default, any configuration will replace the default value. For example:
|
/// default configuration of Clippy. By default, any configuration will replace the default value. For example:
|
||||||
/// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
|
/// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
|
||||||
/// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
|
/// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
|
||||||
///
|
(doc_valid_idents: Vec<String> = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()),
|
||||||
/// Default list:
|
|
||||||
(doc_valid_idents: Vec<String> = super::DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()),
|
|
||||||
/// Lint: TOO_MANY_ARGUMENTS.
|
/// Lint: TOO_MANY_ARGUMENTS.
|
||||||
///
|
///
|
||||||
/// The maximum number of argument a function or method can have
|
/// The maximum number of argument a function or method can have
|
||||||
|
@ -352,7 +332,9 @@ define_Conf! {
|
||||||
(literal_representation_threshold: u64 = 16384),
|
(literal_representation_threshold: u64 = 16384),
|
||||||
/// Lint: TRIVIALLY_COPY_PASS_BY_REF.
|
/// Lint: TRIVIALLY_COPY_PASS_BY_REF.
|
||||||
///
|
///
|
||||||
/// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference.
|
/// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
|
||||||
|
/// reference. By default there is no limit
|
||||||
|
#[default_text = ""]
|
||||||
(trivial_copy_size_limit: Option<u64> = None),
|
(trivial_copy_size_limit: Option<u64> = None),
|
||||||
/// Lint: LARGE_TYPES_PASSED_BY_VALUE.
|
/// Lint: LARGE_TYPES_PASSED_BY_VALUE.
|
||||||
///
|
///
|
||||||
|
@ -393,15 +375,15 @@ define_Conf! {
|
||||||
/// Lint: DISALLOWED_MACROS.
|
/// Lint: DISALLOWED_MACROS.
|
||||||
///
|
///
|
||||||
/// The list of disallowed macros, written as fully qualified paths.
|
/// The list of disallowed macros, written as fully qualified paths.
|
||||||
(disallowed_macros: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
(disallowed_macros: Vec<DisallowedPath> = Vec::new()),
|
||||||
/// Lint: DISALLOWED_METHODS.
|
/// Lint: DISALLOWED_METHODS.
|
||||||
///
|
///
|
||||||
/// The list of disallowed methods, written as fully qualified paths.
|
/// The list of disallowed methods, written as fully qualified paths.
|
||||||
(disallowed_methods: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
(disallowed_methods: Vec<DisallowedPath> = Vec::new()),
|
||||||
/// Lint: DISALLOWED_TYPES.
|
/// Lint: DISALLOWED_TYPES.
|
||||||
///
|
///
|
||||||
/// The list of disallowed types, written as fully qualified paths.
|
/// The list of disallowed types, written as fully qualified paths.
|
||||||
(disallowed_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
(disallowed_types: Vec<DisallowedPath> = Vec::new()),
|
||||||
/// Lint: UNREADABLE_LITERAL.
|
/// Lint: UNREADABLE_LITERAL.
|
||||||
///
|
///
|
||||||
/// Should the fraction of a decimal be linted to include separators.
|
/// Should the fraction of a decimal be linted to include separators.
|
||||||
|
@ -414,9 +396,8 @@ define_Conf! {
|
||||||
///
|
///
|
||||||
/// Whether the matches should be considered by the lint, and whether there should
|
/// Whether the matches should be considered by the lint, and whether there should
|
||||||
/// be filtering for common types.
|
/// be filtering for common types.
|
||||||
(matches_for_let_else: crate::manual_let_else::MatchLintBehaviour =
|
(matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes),
|
||||||
crate::manual_let_else::MatchLintBehaviour::WellKnownTypes),
|
/// Lint: CARGO_COMMON_METADATA.
|
||||||
/// Lint: _CARGO_COMMON_METADATA.
|
|
||||||
///
|
///
|
||||||
/// For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
/// For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
||||||
(cargo_ignore_publish: bool = false),
|
(cargo_ignore_publish: bool = false),
|
||||||
|
@ -427,11 +408,11 @@ define_Conf! {
|
||||||
/// A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
|
/// A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
|
||||||
/// could be used with a full path two `MacroMatcher`s have to be added one with the full path
|
/// could be used with a full path two `MacroMatcher`s have to be added one with the full path
|
||||||
/// `crate_name::macro_name` and one with just the macro name.
|
/// `crate_name::macro_name` and one with just the macro name.
|
||||||
(standard_macro_braces: Vec<crate::nonstandard_macro_braces::MacroMatcher> = Vec::new()),
|
(standard_macro_braces: Vec<MacroMatcher> = Vec::new()),
|
||||||
/// Lint: MISSING_ENFORCED_IMPORT_RENAMES.
|
/// Lint: MISSING_ENFORCED_IMPORT_RENAMES.
|
||||||
///
|
///
|
||||||
/// The list of imports to always rename, a fully qualified path followed by the rename.
|
/// The list of imports to always rename, a fully qualified path followed by the rename.
|
||||||
(enforced_import_renames: Vec<crate::utils::conf::Rename> = Vec::new()),
|
(enforced_import_renames: Vec<Rename> = Vec::new()),
|
||||||
/// Lint: DISALLOWED_SCRIPT_IDENTS.
|
/// Lint: DISALLOWED_SCRIPT_IDENTS.
|
||||||
///
|
///
|
||||||
/// The list of unicode scripts allowed to be used in the scope.
|
/// The list of unicode scripts allowed to be used in the scope.
|
||||||
|
@ -447,7 +428,7 @@ define_Conf! {
|
||||||
/// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
/// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||||
(max_suggested_slice_pattern_length: u64 = 3),
|
(max_suggested_slice_pattern_length: u64 = 3),
|
||||||
/// Lint: AWAIT_HOLDING_INVALID_TYPE.
|
/// Lint: AWAIT_HOLDING_INVALID_TYPE.
|
||||||
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
(await_holding_invalid_types: Vec<DisallowedPath> = Vec::new()),
|
||||||
/// Lint: LARGE_INCLUDE_FILE.
|
/// Lint: LARGE_INCLUDE_FILE.
|
||||||
///
|
///
|
||||||
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||||
|
@ -511,8 +492,8 @@ define_Conf! {
|
||||||
/// Allowed names below the minimum allowed characters. The value `".."` can be used as part of
|
/// Allowed names below the minimum allowed characters. The value `".."` can be used as part of
|
||||||
/// the list to indicate, that the configured values should be appended to the default
|
/// the list to indicate, that the configured values should be appended to the default
|
||||||
/// configuration of Clippy. By default, any configuration will replace the default value.
|
/// configuration of Clippy. By default, any configuration will replace the default value.
|
||||||
(allowed_idents_below_min_chars: rustc_data_structures::fx::FxHashSet<String> =
|
(allowed_idents_below_min_chars: FxHashSet<String> =
|
||||||
super::DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()),
|
DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()),
|
||||||
/// Lint: MIN_IDENT_CHARS.
|
/// Lint: MIN_IDENT_CHARS.
|
||||||
///
|
///
|
||||||
/// Minimum chars an ident can have, anything below or equal to this will be linted.
|
/// Minimum chars an ident can have, anything below or equal to this will be linted.
|
||||||
|
@ -537,19 +518,17 @@ define_Conf! {
|
||||||
/// Lint: ABSOLUTE_PATHS.
|
/// Lint: ABSOLUTE_PATHS.
|
||||||
///
|
///
|
||||||
/// Which crates to allow absolute paths from
|
/// Which crates to allow absolute paths from
|
||||||
(absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet<String> =
|
(absolute_paths_allowed_crates: FxHashSet<String> = FxHashSet::default()),
|
||||||
rustc_data_structures::fx::FxHashSet::default()),
|
|
||||||
/// Lint: PATH_ENDS_WITH_EXT.
|
/// Lint: PATH_ENDS_WITH_EXT.
|
||||||
///
|
///
|
||||||
/// Additional dotfiles (files or directories starting with a dot) to allow
|
/// Additional dotfiles (files or directories starting with a dot) to allow
|
||||||
(allowed_dotfiles: rustc_data_structures::fx::FxHashSet<String> =
|
(allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
|
||||||
rustc_data_structures::fx::FxHashSet::default()),
|
|
||||||
/// Lint: EXPLICIT_ITER_LOOP
|
/// Lint: EXPLICIT_ITER_LOOP
|
||||||
///
|
///
|
||||||
/// Whether to recommend using implicit into iter for reborrowed values.
|
/// Whether to recommend using implicit into iter for reborrowed values.
|
||||||
///
|
///
|
||||||
/// #### Example
|
/// #### Example
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// let mut vec = vec![1, 2, 3];
|
/// let mut vec = vec![1, 2, 3];
|
||||||
/// let rmvec = &mut vec;
|
/// let rmvec = &mut vec;
|
||||||
/// for _ in rmvec.iter() {}
|
/// for _ in rmvec.iter() {}
|
||||||
|
@ -557,7 +536,7 @@ define_Conf! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// let mut vec = vec![1, 2, 3];
|
/// let mut vec = vec![1, 2, 3];
|
||||||
/// let rmvec = &mut vec;
|
/// let rmvec = &mut vec;
|
||||||
/// for _ in &*rmvec {}
|
/// for _ in &*rmvec {}
|
||||||
|
@ -779,7 +758,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn configs_are_tested() {
|
fn configs_are_tested() {
|
||||||
let mut names: FxHashSet<String> = super::metadata::get_configuration_metadata()
|
let mut names: FxHashSet<String> = crate::get_configuration_metadata()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|meta| meta.name.replace('_', "-"))
|
.map(|meta| meta.name.replace('_', "-"))
|
||||||
.collect();
|
.collect();
|
23
clippy_config/src/lib.rs
Normal file
23
clippy_config/src/lib.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#![feature(rustc_private, let_chains)]
|
||||||
|
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||||
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||||
|
#![allow(
|
||||||
|
clippy::must_use_candidate,
|
||||||
|
clippy::missing_panics_doc,
|
||||||
|
rustc::untranslatable_diagnostic_trivial
|
||||||
|
)]
|
||||||
|
|
||||||
|
extern crate rustc_ast;
|
||||||
|
extern crate rustc_data_structures;
|
||||||
|
#[allow(unused_extern_crates)]
|
||||||
|
extern crate rustc_driver;
|
||||||
|
extern crate rustc_session;
|
||||||
|
extern crate rustc_span;
|
||||||
|
|
||||||
|
mod conf;
|
||||||
|
mod metadata;
|
||||||
|
pub mod msrvs;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
|
pub use conf::{get_configuration_metadata, lookup_conf_file, Conf};
|
||||||
|
pub use metadata::ClippyConfiguration;
|
116
clippy_config/src/metadata.rs
Normal file
116
clippy_config/src/metadata.rs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct ClippyConfiguration {
|
||||||
|
pub name: String,
|
||||||
|
pub default: String,
|
||||||
|
pub lints: Vec<String>,
|
||||||
|
pub doc: String,
|
||||||
|
pub deprecation_reason: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ClippyConfiguration {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "- `{}`: {}", self.name, self.doc)?;
|
||||||
|
if !self.default.is_empty() {
|
||||||
|
write!(f, " (default: `{}`)", self.default)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClippyConfiguration {
|
||||||
|
pub fn new(
|
||||||
|
name: &'static str,
|
||||||
|
default: String,
|
||||||
|
doc_comment: &'static str,
|
||||||
|
deprecation_reason: Option<&'static str>,
|
||||||
|
) -> Self {
|
||||||
|
let (lints, doc) = parse_config_field_doc(doc_comment)
|
||||||
|
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
|
||||||
|
|
||||||
|
Self {
|
||||||
|
name: to_kebab(name),
|
||||||
|
lints,
|
||||||
|
doc,
|
||||||
|
default,
|
||||||
|
deprecation_reason,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_markdown_paragraph(&self) -> String {
|
||||||
|
let mut out = format!(
|
||||||
|
"## `{}`\n{}\n\n",
|
||||||
|
self.name,
|
||||||
|
self.doc
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.strip_prefix(" ").unwrap_or(line))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n"),
|
||||||
|
);
|
||||||
|
|
||||||
|
if !self.default.is_empty() {
|
||||||
|
write!(out, "**Default Value:** `{}`\n\n", self.default).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(
|
||||||
|
out,
|
||||||
|
"---\n**Affected lints:**\n{}\n\n",
|
||||||
|
self.lints
|
||||||
|
.iter()
|
||||||
|
.map(|name| name.to_string().split_whitespace().next().unwrap().to_string())
|
||||||
|
.map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n"),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_markdown_link(&self) -> String {
|
||||||
|
const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html";
|
||||||
|
format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This parses the field documentation of the config struct.
|
||||||
|
///
|
||||||
|
/// ```rust, ignore
|
||||||
|
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Would yield:
|
||||||
|
/// ```rust, ignore
|
||||||
|
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
|
||||||
|
/// ```
|
||||||
|
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
|
||||||
|
const DOC_START: &str = " Lint: ";
|
||||||
|
if doc_comment.starts_with(DOC_START)
|
||||||
|
&& let Some(split_pos) = doc_comment.find('.')
|
||||||
|
{
|
||||||
|
let mut doc_comment = doc_comment.to_string();
|
||||||
|
let mut documentation = doc_comment.split_off(split_pos);
|
||||||
|
|
||||||
|
// Extract lints
|
||||||
|
doc_comment.make_ascii_lowercase();
|
||||||
|
let lints: Vec<String> = doc_comment
|
||||||
|
.split_off(DOC_START.len())
|
||||||
|
.split(", ")
|
||||||
|
.map(str::to_string)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Format documentation correctly
|
||||||
|
// split off leading `.` from lint name list and indent for correct formatting
|
||||||
|
documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n ");
|
||||||
|
|
||||||
|
Some((lints, documentation))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
|
||||||
|
fn to_kebab(config_name: &str) -> String {
|
||||||
|
config_name.replace('_', "-")
|
||||||
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::Attribute;
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_span::{sym, Symbol};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::attrs::get_unique_attr;
|
|
||||||
|
|
||||||
macro_rules! msrv_aliases {
|
macro_rules! msrv_aliases {
|
||||||
($($major:literal,$minor:literal,$patch:literal {
|
($($major:literal,$minor:literal,$patch:literal {
|
||||||
$($name:ident),* $(,)?
|
$($name:ident),* $(,)?
|
||||||
|
@ -101,7 +100,16 @@ impl Msrv {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
|
fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
|
||||||
if let Some(msrv_attr) = get_unique_attr(sess, attrs, "msrv") {
|
let sym_msrv = Symbol::intern("msrv");
|
||||||
|
let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv]));
|
||||||
|
|
||||||
|
if let Some(msrv_attr) = msrv_attrs.next() {
|
||||||
|
if let Some(duplicate) = msrv_attrs.last() {
|
||||||
|
sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
|
||||||
|
.span_note(msrv_attr.span, "first definition found here")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(msrv) = msrv_attr.value_str() {
|
if let Some(msrv) = msrv_attr.value_str() {
|
||||||
if let Ok(version) = RustcVersion::parse(msrv.as_str()) {
|
if let Ok(version) = RustcVersion::parse(msrv.as_str()) {
|
||||||
return Some(version);
|
return Some(version);
|
142
clippy_config/src/types.rs
Normal file
142
clippy_config/src/types.rs
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
use serde::de::{self, Deserializer, Visitor};
|
||||||
|
use serde::{ser, Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
pub struct Rename {
|
||||||
|
pub path: String,
|
||||||
|
pub rename: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DisallowedPath {
|
||||||
|
Simple(String),
|
||||||
|
WithReason { path: String, reason: Option<String> },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DisallowedPath {
|
||||||
|
pub fn path(&self) -> &str {
|
||||||
|
let (Self::Simple(path) | Self::WithReason { path, .. }) = self;
|
||||||
|
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reason(&self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
Self::WithReason {
|
||||||
|
reason: Some(reason), ..
|
||||||
|
} => Some(format!("{reason} (from clippy.toml)")),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||||
|
pub enum MatchLintBehaviour {
|
||||||
|
AllTypes,
|
||||||
|
WellKnownTypes,
|
||||||
|
Never,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct MacroMatcher {
|
||||||
|
pub name: String,
|
||||||
|
pub braces: (String, String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for MacroMatcher {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.name.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for MacroMatcher {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.name == other.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Eq for MacroMatcher {}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for MacroMatcher {
|
||||||
|
fn deserialize<D>(deser: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(field_identifier, rename_all = "lowercase")]
|
||||||
|
enum Field {
|
||||||
|
Name,
|
||||||
|
Brace,
|
||||||
|
}
|
||||||
|
struct MacVisitor;
|
||||||
|
impl<'de> Visitor<'de> for MacVisitor {
|
||||||
|
type Value = MacroMatcher;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
formatter.write_str("struct MacroMatcher")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
|
||||||
|
where
|
||||||
|
V: de::MapAccess<'de>,
|
||||||
|
{
|
||||||
|
let mut name = None;
|
||||||
|
let mut brace: Option<String> = None;
|
||||||
|
while let Some(key) = map.next_key()? {
|
||||||
|
match key {
|
||||||
|
Field::Name => {
|
||||||
|
if name.is_some() {
|
||||||
|
return Err(de::Error::duplicate_field("name"));
|
||||||
|
}
|
||||||
|
name = Some(map.next_value()?);
|
||||||
|
},
|
||||||
|
Field::Brace => {
|
||||||
|
if brace.is_some() {
|
||||||
|
return Err(de::Error::duplicate_field("brace"));
|
||||||
|
}
|
||||||
|
brace = Some(map.next_value()?);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
|
||||||
|
let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?;
|
||||||
|
Ok(MacroMatcher {
|
||||||
|
name,
|
||||||
|
braces: [("(", ")"), ("{", "}"), ("[", "]")]
|
||||||
|
.into_iter()
|
||||||
|
.find(|b| b.0 == brace)
|
||||||
|
.map(|(o, c)| (o.to_owned(), c.to_owned()))
|
||||||
|
.ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FIELDS: &[&str] = &["name", "brace"];
|
||||||
|
deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// these impls are never actually called but are used by the various config options that default to
|
||||||
|
// empty lists
|
||||||
|
macro_rules! unimplemented_serialize {
|
||||||
|
($($t:ty,)*) => {
|
||||||
|
$(
|
||||||
|
impl Serialize for $t {
|
||||||
|
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: ser::Serializer,
|
||||||
|
{
|
||||||
|
Err(ser::Error::custom("unimplemented"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unimplemented_serialize! {
|
||||||
|
DisallowedPath,
|
||||||
|
Rename,
|
||||||
|
MacroMatcher,
|
||||||
|
}
|
|
@ -199,7 +199,6 @@ fn get_clap_config() -> ArgMatches {
|
||||||
"cargo",
|
"cargo",
|
||||||
"nursery",
|
"nursery",
|
||||||
"internal",
|
"internal",
|
||||||
"internal_warn",
|
|
||||||
]),
|
]),
|
||||||
Arg::new("type").long("type").help("What directory the lint belongs in"),
|
Arg::new("type").long("type").help("What directory the lint belongs in"),
|
||||||
Arg::new("msrv")
|
Arg::new("msrv")
|
||||||
|
|
|
@ -346,11 +346,11 @@ fn get_lint_declaration(name_upper: &str, category: &str) -> String {
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // example code where clippy issues a warning
|
/// // example code where clippy issues a warning
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // example code which does not raise clippy warning
|
/// // example code which does not raise clippy warning
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "{}"]
|
#[clippy::version = "{}"]
|
||||||
|
|
|
@ -588,7 +588,7 @@ impl Lint {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all internal lints (not `internal_warn` lints)
|
/// Returns all internal lints
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn internal_lints(lints: &[Self]) -> Vec<Self> {
|
fn internal_lints(lints: &[Self]) -> Vec<Self> {
|
||||||
lints.iter().filter(|l| l.group == "internal").cloned().collect()
|
lints.iter().filter(|l| l.group == "internal").cloned().collect()
|
||||||
|
|
|
@ -11,6 +11,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arrayvec = { version = "0.7", default-features = false }
|
arrayvec = { version = "0.7", default-features = false }
|
||||||
cargo_metadata = "0.15.3"
|
cargo_metadata = "0.15.3"
|
||||||
|
clippy_config = { path = "../clippy_config" }
|
||||||
clippy_utils = { path = "../clippy_utils" }
|
clippy_utils = { path = "../clippy_utils" }
|
||||||
declare_clippy_lint = { path = "../declare_clippy_lint" }
|
declare_clippy_lint = { path = "../declare_clippy_lint" }
|
||||||
if_chain = "1.0"
|
if_chain = "1.0"
|
||||||
|
@ -32,9 +33,9 @@ url = "2.2"
|
||||||
walkdir = "2.3"
|
walkdir = "2.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
deny-warnings = ["clippy_utils/deny-warnings"]
|
deny-warnings = ["clippy_config/deny-warnings", "clippy_utils/deny-warnings"]
|
||||||
# build clippy with internal lints enabled, off by default
|
# build clippy with internal lints enabled, off by default
|
||||||
internal = ["clippy_utils/internal", "serde_json", "tempfile", "regex"]
|
internal = ["serde_json", "tempfile", "regex"]
|
||||||
|
|
||||||
[package.metadata.rust-analyzer]
|
[package.metadata.rust-analyzer]
|
||||||
# This crate uses #[feature(rustc_private)]
|
# This crate uses #[feature(rustc_private)]
|
||||||
|
|
|
@ -24,11 +24,11 @@ declare_clippy_lint! {
|
||||||
/// using absolute paths is the proper way of referencing items in one.
|
/// using absolute paths is the proper way of referencing items in one.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = std::f64::consts::PI;
|
/// let x = std::f64::consts::PI;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use any of the below instead, or anything else:
|
/// Use any of the below instead, or anything else:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::f64;
|
/// use std::f64;
|
||||||
/// use std::f64::consts;
|
/// use std::f64::consts;
|
||||||
/// use std::f64::consts::PI;
|
/// use std::f64::consts::PI;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::{trim_span, walk_span_to_context};
|
use clippy_utils::source::{trim_span, walk_span_to_context};
|
||||||
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
|
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -17,11 +17,11 @@ declare_clippy_lint! {
|
||||||
/// This (`'a'..'z'`) is almost certainly a typo meant to include all letters.
|
/// This (`'a'..'z'`) is almost certainly a typo meant to include all letters.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = 'a'..'z';
|
/// let _ = 'a'..'z';
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = 'a'..='z';
|
/// let _ = 'a'..='z';
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.68.0"]
|
#[clippy::version = "1.68.0"]
|
||||||
|
@ -82,33 +82,20 @@ fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg
|
||||||
(
|
(
|
||||||
Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
|
Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
|
||||||
Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
|
Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
|
||||||
)
|
) | (
|
||||||
| (
|
|
||||||
Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
|
Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
|
||||||
Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
|
Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
|
||||||
)
|
) | (
|
||||||
| (
|
|
||||||
Ok(LitKind::Byte(b'0') | LitKind::Char('0')),
|
Ok(LitKind::Byte(b'0') | LitKind::Char('0')),
|
||||||
Ok(LitKind::Byte(b'9') | LitKind::Char('9')),
|
Ok(LitKind::Byte(b'9') | LitKind::Char('9')),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
&& !in_external_macro(cx.sess(), span)
|
&& !in_external_macro(cx.sess(), span)
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(cx, ALMOST_COMPLETE_RANGE, span, "almost complete ascii range", |diag| {
|
||||||
cx,
|
if let Some((span, sugg)) = sugg {
|
||||||
ALMOST_COMPLETE_RANGE,
|
diag.span_suggestion(span, "use an inclusive range", sugg, Applicability::MaybeIncorrect);
|
||||||
span,
|
|
||||||
"almost complete ascii range",
|
|
||||||
|diag| {
|
|
||||||
if let Some((span, sugg)) = sugg {
|
|
||||||
diag.span_suggestion(
|
|
||||||
span,
|
|
||||||
"use an inclusive range",
|
|
||||||
sugg,
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
@ -24,12 +24,12 @@ declare_clippy_lint! {
|
||||||
/// issue](https://github.com/rust-lang/rust/issues).
|
/// issue](https://github.com/rust-lang/rust/issues).
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = 3.14;
|
/// let x = 3.14;
|
||||||
/// let y = 1_f64 / x;
|
/// let y = 1_f64 / x;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// 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;
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -18,7 +18,7 @@ declare_clippy_lint! {
|
||||||
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
|
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::cell::RefCell;
|
/// # use std::cell::RefCell;
|
||||||
/// # use std::sync::Arc;
|
/// # use std::sync::Arc;
|
||||||
///
|
///
|
||||||
|
@ -62,19 +62,21 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {
|
||||||
ARC_WITH_NON_SEND_SYNC,
|
ARC_WITH_NON_SEND_SYNC,
|
||||||
expr.span,
|
expr.span,
|
||||||
"usage of an `Arc` that is not `Send` or `Sync`",
|
"usage of an `Arc` that is not `Send` or `Sync`",
|
||||||
|diag| with_forced_trimmed_paths!({
|
|diag| {
|
||||||
if !is_send {
|
with_forced_trimmed_paths!({
|
||||||
diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`"));
|
if !is_send {
|
||||||
}
|
diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`"));
|
||||||
if !is_sync {
|
}
|
||||||
diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`"));
|
if !is_sync {
|
||||||
}
|
diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`"));
|
||||||
|
}
|
||||||
|
|
||||||
diag.note(format!("required for `{ty}` to implement `Send` and `Sync`"));
|
diag.note(format!("required for `{ty}` to implement `Send` and `Sync`"));
|
||||||
|
|
||||||
diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`");
|
diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`");
|
||||||
}
|
});
|
||||||
));
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""};
|
let semicolon = if is_expr_final_block_expr(cx.tcx, e) { ";" } else { "" };
|
||||||
let mut app = Applicability::MachineApplicable;
|
let mut app = Applicability::MachineApplicable;
|
||||||
match method_segment.ident.as_str() {
|
match method_segment.ident.as_str() {
|
||||||
"is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => {
|
"is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => {
|
||||||
|
@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
|
||||||
),
|
),
|
||||||
app,
|
app,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
"is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => {
|
"is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
|
@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
|
||||||
),
|
),
|
||||||
app,
|
app,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||||
use clippy_utils::source::snippet;
|
use clippy_utils::source::snippet;
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{CoroutineSource, Body, BodyId, CoroutineKind, ExprKind, QPath};
|
use rustc_hir::{Body, BodyId, CoroutineKind, CoroutineSource, ExprKind, QPath};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ declare_clippy_lint! {
|
||||||
/// An await is likely missing.
|
/// An await is likely missing.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// async fn foo() {}
|
/// async fn foo() {}
|
||||||
///
|
///
|
||||||
/// fn bar() {
|
/// fn bar() {
|
||||||
|
@ -26,7 +26,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// async fn foo() {}
|
/// async fn foo() {}
|
||||||
///
|
///
|
||||||
/// fn bar() {
|
/// fn bar() {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! checks for attributes
|
//! checks for attributes
|
||||||
|
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
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::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use clippy_utils::macros::{is_panic, macro_backtrace};
|
use clippy_utils::macros::{is_panic, macro_backtrace};
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
|
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_ast::token::{Token, TokenKind};
|
use rustc_ast::token::{Token, TokenKind};
|
||||||
|
@ -129,7 +129,7 @@ declare_clippy_lint! {
|
||||||
/// a valid semver. Failing that, the contained information is useless.
|
/// a valid semver. Failing that, the contained information is useless.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[deprecated(since = "forever")]
|
/// #[deprecated(since = "forever")]
|
||||||
/// fn something_else() { /* ... */ }
|
/// fn something_else() { /* ... */ }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -156,14 +156,14 @@ declare_clippy_lint! {
|
||||||
/// currently works for basic cases but is not perfect.
|
/// currently works for basic cases but is not perfect.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[allow(dead_code)]
|
/// #[allow(dead_code)]
|
||||||
///
|
///
|
||||||
/// fn not_quite_good_code() { }
|
/// fn not_quite_good_code() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // Good (as inner attribute)
|
/// // Good (as inner attribute)
|
||||||
/// #![allow(dead_code)]
|
/// #![allow(dead_code)]
|
||||||
///
|
///
|
||||||
|
@ -198,25 +198,25 @@ declare_clippy_lint! {
|
||||||
/// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
|
/// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// Some doc comment with a blank line after it.
|
/// /// Some doc comment with a blank line after it.
|
||||||
///
|
///
|
||||||
/// fn not_quite_good_code() { }
|
/// fn not_quite_good_code() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// Good (no blank line)
|
/// /// Good (no blank line)
|
||||||
/// fn this_is_fine() { }
|
/// fn this_is_fine() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // Good (convert to a regular comment)
|
/// // Good (convert to a regular comment)
|
||||||
///
|
///
|
||||||
/// fn this_is_fine_too() { }
|
/// fn this_is_fine_too() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// //! Good (convert to a comment on an inner attribute)
|
/// //! Good (convert to a comment on an inner attribute)
|
||||||
///
|
///
|
||||||
/// fn this_is_fine_as_well() { }
|
/// fn this_is_fine_as_well() { }
|
||||||
|
@ -236,12 +236,12 @@ declare_clippy_lint! {
|
||||||
/// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
|
/// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #![deny(clippy::restriction)]
|
/// #![deny(clippy::restriction)]
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #![deny(clippy::as_conversions)]
|
/// #![deny(clippy::as_conversions)]
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.47.0"]
|
#[clippy::version = "1.47.0"]
|
||||||
|
@ -265,13 +265,13 @@ declare_clippy_lint! {
|
||||||
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
/// fn main() { }
|
/// fn main() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[rustfmt::skip]
|
/// #[rustfmt::skip]
|
||||||
/// fn main() { }
|
/// fn main() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -290,13 +290,13 @@ declare_clippy_lint! {
|
||||||
/// by the conditional compilation engine.
|
/// by the conditional compilation engine.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg(linux)]
|
/// #[cfg(linux)]
|
||||||
/// fn conditional() { }
|
/// fn conditional() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # mod hidden {
|
/// # mod hidden {
|
||||||
/// #[cfg(target_os = "linux")]
|
/// #[cfg(target_os = "linux")]
|
||||||
/// fn conditional() { }
|
/// fn conditional() { }
|
||||||
|
@ -325,14 +325,14 @@ declare_clippy_lint! {
|
||||||
/// ensure that others understand the reasoning
|
/// ensure that others understand the reasoning
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #![feature(lint_reasons)]
|
/// #![feature(lint_reasons)]
|
||||||
///
|
///
|
||||||
/// #![allow(clippy::some_lint)]
|
/// #![allow(clippy::some_lint)]
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #![feature(lint_reasons)]
|
/// #![feature(lint_reasons)]
|
||||||
///
|
///
|
||||||
/// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
|
/// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
|
||||||
|
@ -352,7 +352,7 @@ declare_clippy_lint! {
|
||||||
/// panicking with the expected message, and not another unrelated panic.
|
/// panicking with the expected message, and not another unrelated panic.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn random() -> i32 { 0 }
|
/// fn random() -> i32 { 0 }
|
||||||
///
|
///
|
||||||
/// #[should_panic]
|
/// #[should_panic]
|
||||||
|
@ -363,7 +363,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn random() -> i32 { 0 }
|
/// fn random() -> i32 { 0 }
|
||||||
///
|
///
|
||||||
/// #[should_panic = "attempt to divide by zero"]
|
/// #[should_panic = "attempt to divide by zero"]
|
||||||
|
@ -386,13 +386,13 @@ declare_clippy_lint! {
|
||||||
/// If there is only one condition, no need to wrap it into `any` or `all` combinators.
|
/// If there is only one condition, no need to wrap it into `any` or `all` combinators.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg(any(unix))]
|
/// #[cfg(any(unix))]
|
||||||
/// pub struct Bar;
|
/// pub struct Bar;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg(unix)]
|
/// #[cfg(unix)]
|
||||||
/// pub struct Bar;
|
/// pub struct Bar;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -409,16 +409,16 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// Misspelling `feature` as `features` can be sometimes hard to spot. It
|
/// Misspelling `feature` as `features` can be sometimes hard to spot. It
|
||||||
/// may cause conditional compilation not work quitely.
|
/// may cause conditional compilation not work quietly.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg(features = "some-feature")]
|
/// #[cfg(features = "some-feature")]
|
||||||
/// fn conditional() { }
|
/// fn conditional() { }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[cfg(feature = "some-feature")]
|
/// #[cfg(feature = "some-feature")]
|
||||||
/// fn conditional() { }
|
/// fn conditional() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -602,9 +602,26 @@ fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
|
||||||
|
|
||||||
if let AttrArgs::Delimited(args) = &normal_attr.item.args
|
if let AttrArgs::Delimited(args) = &normal_attr.item.args
|
||||||
&& let mut tt_iter = args.tokens.trees()
|
&& let mut tt_iter = args.tokens.trees()
|
||||||
&& let Some(TokenTree::Token(Token { kind: TokenKind::Ident(sym::expected, _), .. }, _)) = tt_iter.next()
|
&& let Some(TokenTree::Token(
|
||||||
&& let Some(TokenTree::Token(Token { kind: TokenKind::Eq, .. }, _)) = tt_iter.next()
|
Token {
|
||||||
&& let Some(TokenTree::Token(Token { kind: TokenKind::Literal(_), .. }, _)) = tt_iter.next()
|
kind: TokenKind::Ident(sym::expected, _),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
)) = tt_iter.next()
|
||||||
|
&& let Some(TokenTree::Token(
|
||||||
|
Token {
|
||||||
|
kind: TokenKind::Eq, ..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
)) = tt_iter.next()
|
||||||
|
&& let Some(TokenTree::Token(
|
||||||
|
Token {
|
||||||
|
kind: TokenKind::Literal(_),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
)) = tt_iter.next()
|
||||||
{
|
{
|
||||||
// `#[should_panic(expected = "..")]` found, good
|
// `#[should_panic(expected = "..")]` found, good
|
||||||
return;
|
return;
|
||||||
|
@ -914,7 +931,9 @@ fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
|
||||||
fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
|
fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
|
||||||
for item in items {
|
for item in items {
|
||||||
if let NestedMetaItem::MetaItem(meta) = item {
|
if let NestedMetaItem::MetaItem(meta) = item {
|
||||||
if meta.has_name(sym!(features)) && let Some(val) = meta.value_str() {
|
if meta.has_name(sym!(features))
|
||||||
|
&& let Some(val) = meta.value_str()
|
||||||
|
{
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
MAYBE_MISUSED_CFG,
|
MAYBE_MISUSED_CFG,
|
||||||
|
@ -933,16 +952,16 @@ fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) {
|
fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||||
if attr.has_name(sym::cfg) &&
|
if attr.has_name(sym::cfg)
|
||||||
let Some(items) = attr.meta_item_list()
|
&& let Some(items) = attr.meta_item_list()
|
||||||
{
|
{
|
||||||
check_nested_cfg(cx, &items);
|
check_nested_cfg(cx, &items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
|
fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||||
if attr.has_name(sym::cfg) &&
|
if attr.has_name(sym::cfg)
|
||||||
let Some(items) = attr.meta_item_list()
|
&& let Some(items) = attr.meta_item_list()
|
||||||
{
|
{
|
||||||
check_nested_misused_cfg(cx, &items);
|
check_nested_misused_cfg(cx, &items);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
|
use clippy_config::types::DisallowedPath;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::{match_def_path, paths};
|
use clippy_utils::{match_def_path, paths};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{CoroutineSource, Body, CoroutineKind};
|
use rustc_hir::{Body, CoroutineKind, CoroutineSource};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::mir::CoroutineLayout;
|
use rustc_middle::mir::CoroutineLayout;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
use crate::utils::conf::DisallowedPath;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks for calls to await while holding a non-async-aware MutexGuard.
|
/// Checks for calls to await while holding a non-async-aware MutexGuard.
|
||||||
|
@ -29,7 +28,7 @@ declare_clippy_lint! {
|
||||||
/// to wrap the `.lock()` call in a block instead of explicitly dropping the guard.
|
/// to wrap the `.lock()` call in a block instead of explicitly dropping the guard.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::sync::Mutex;
|
/// # use std::sync::Mutex;
|
||||||
/// # async fn baz() {}
|
/// # async fn baz() {}
|
||||||
/// async fn foo(x: &Mutex<u32>) {
|
/// async fn foo(x: &Mutex<u32>) {
|
||||||
|
@ -47,7 +46,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::sync::Mutex;
|
/// # use std::sync::Mutex;
|
||||||
/// # async fn baz() {}
|
/// # async fn baz() {}
|
||||||
/// async fn foo(x: &Mutex<u32>) {
|
/// async fn foo(x: &Mutex<u32>) {
|
||||||
|
@ -87,7 +86,7 @@ declare_clippy_lint! {
|
||||||
/// to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.
|
/// to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::cell::RefCell;
|
/// # use std::cell::RefCell;
|
||||||
/// # async fn baz() {}
|
/// # async fn baz() {}
|
||||||
/// async fn foo(x: &RefCell<u32>) {
|
/// async fn foo(x: &RefCell<u32>) {
|
||||||
|
@ -105,7 +104,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::cell::RefCell;
|
/// # use std::cell::RefCell;
|
||||||
/// # async fn baz() {}
|
/// # async fn baz() {}
|
||||||
/// async fn foo(x: &RefCell<u32>) {
|
/// async fn foo(x: &RefCell<u32>) {
|
||||||
|
@ -151,7 +150,7 @@ declare_clippy_lint! {
|
||||||
/// ]
|
/// ]
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # async fn baz() {}
|
/// # async fn baz() {}
|
||||||
/// struct CustomLockType;
|
/// struct CustomLockType;
|
||||||
/// struct OtherCustomLockType;
|
/// struct OtherCustomLockType;
|
||||||
|
|
|
@ -21,7 +21,7 @@ declare_clippy_lint! {
|
||||||
/// Style, using blocks in the condition makes it hard to read.
|
/// Style, using blocks in the condition makes it hard to read.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn somefunc() -> bool { true };
|
/// # fn somefunc() -> bool { true };
|
||||||
/// if { true } { /* ... */ }
|
/// if { true } { /* ... */ }
|
||||||
///
|
///
|
||||||
|
@ -29,7 +29,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn somefunc() -> bool { true };
|
/// # fn somefunc() -> bool { true };
|
||||||
/// if true { /* ... */ }
|
/// if true { /* ... */ }
|
||||||
///
|
///
|
||||||
|
|
|
@ -18,13 +18,13 @@ declare_clippy_lint! {
|
||||||
/// It is shorter to use the equivalent.
|
/// It is shorter to use the equivalent.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// assert_eq!("a".is_empty(), false);
|
/// assert_eq!("a".is_empty(), false);
|
||||||
/// assert_ne!("a".is_empty(), true);
|
/// assert_ne!("a".is_empty(), true);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// assert!(!"a".is_empty());
|
/// assert!(!"a".is_empty());
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.53.0"]
|
#[clippy::version = "1.53.0"]
|
||||||
|
|
|
@ -21,7 +21,7 @@ declare_clippy_lint! {
|
||||||
/// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
|
/// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let condition = false;
|
/// # let condition = false;
|
||||||
/// if condition {
|
/// if condition {
|
||||||
/// 1_i64
|
/// 1_i64
|
||||||
|
@ -30,12 +30,12 @@ declare_clippy_lint! {
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let condition = false;
|
/// # let condition = false;
|
||||||
/// i64::from(condition);
|
/// i64::from(condition);
|
||||||
/// ```
|
/// ```
|
||||||
/// or
|
/// or
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let condition = false;
|
/// # let condition = false;
|
||||||
/// condition as i64;
|
/// condition as i64;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -55,7 +55,11 @@ impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||||
if let Some(If { cond, then, r#else: Some(r#else) }) = If::hir(expr)
|
if let Some(If {
|
||||||
|
cond,
|
||||||
|
then,
|
||||||
|
r#else: Some(r#else),
|
||||||
|
}) = If::hir(expr)
|
||||||
&& let Some(then_lit) = int_literal(then)
|
&& let Some(then_lit) = int_literal(then)
|
||||||
&& let Some(else_lit) = int_literal(r#else)
|
&& let Some(else_lit) = int_literal(r#else)
|
||||||
{
|
{
|
||||||
|
@ -90,19 +94,18 @@ fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>
|
||||||
let into_snippet = snippet.clone().maybe_par();
|
let into_snippet = snippet.clone().maybe_par();
|
||||||
let as_snippet = snippet.as_ty(ty);
|
let as_snippet = snippet.as_ty(ty);
|
||||||
|
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
BOOL_TO_INT_WITH_IF,
|
BOOL_TO_INT_WITH_IF,
|
||||||
expr.span,
|
expr.span,
|
||||||
"boolean to int conversion using if",
|
"boolean to int conversion using if",
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(expr.span, "replace with from", suggestion, applicability);
|
||||||
expr.span,
|
diag.note(format!(
|
||||||
"replace with from",
|
"`{as_snippet}` or `{into_snippet}.into()` can also be valid options"
|
||||||
suggestion,
|
));
|
||||||
applicability,
|
},
|
||||||
);
|
);
|
||||||
diag.note(format!("`{as_snippet}` or `{into_snippet}.into()` can also be valid options"));
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +113,7 @@ fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>
|
||||||
fn int_literal<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>) -> Option<&'tcx rustc_hir::Expr<'tcx>> {
|
fn int_literal<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>) -> Option<&'tcx rustc_hir::Expr<'tcx>> {
|
||||||
if let ExprKind::Block(block, _) = expr.kind
|
if let ExprKind::Block(block, _) = expr.kind
|
||||||
&& let Block {
|
&& let Block {
|
||||||
stmts: [], // Shouldn't lint if statements with side effects
|
stmts: [], // Shouldn't lint if statements with side effects
|
||||||
expr: Some(expr),
|
expr: Some(expr),
|
||||||
..
|
..
|
||||||
} = block
|
} = block
|
||||||
|
|
|
@ -472,8 +472,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
|
||||||
self.bool_expr(e);
|
self.bool_expr(e);
|
||||||
},
|
},
|
||||||
ExprKind::Unary(UnOp::Not, inner) => {
|
ExprKind::Unary(UnOp::Not, inner) => {
|
||||||
if let ExprKind::Unary(UnOp::Not, ex) = inner.kind &&
|
if let ExprKind::Unary(UnOp::Not, ex) = inner.kind
|
||||||
!self.cx.typeck_results().node_types()[ex.hir_id].is_bool() {
|
&& !self.cx.typeck_results().node_types()[ex.hir_id].is_bool()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
|
if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
|
||||||
|
@ -500,10 +501,10 @@ struct NotSimplificationVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||||
if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind &&
|
if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind
|
||||||
!inner.span.from_expansion() &&
|
&& !inner.span.from_expansion()
|
||||||
let Some(suggestion) = simplify_not(self.cx, inner)
|
&& let Some(suggestion) = simplify_not(self.cx, inner)
|
||||||
&& self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
|
&& self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
|
||||||
{
|
{
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
self.cx,
|
self.cx,
|
||||||
|
|
|
@ -19,7 +19,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Known problems
|
/// ### Known problems
|
||||||
/// False negative on such code:
|
/// False negative on such code:
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// let x = &12;
|
/// let x = &12;
|
||||||
/// let addr_x = &x as *const _ as usize;
|
/// let addr_x = &x as *const _ as usize;
|
||||||
/// let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.
|
/// let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.
|
||||||
|
@ -28,14 +28,14 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let s = &String::new();
|
/// let s = &String::new();
|
||||||
///
|
///
|
||||||
/// let a: &String = &* s;
|
/// let a: &String = &* s;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let s = &String::new();
|
/// # let s = &String::new();
|
||||||
/// let a: &String = s;
|
/// let a: &String = s;
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -24,11 +24,11 @@ declare_clippy_lint! {
|
||||||
/// [in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
|
/// [in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x: Box<String> = Box::new(Default::default());
|
/// let x: Box<String> = Box::new(Default::default());
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x: Box<String> = Box::default();
|
/// let x: Box<String> = Box::default();
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.66.0"]
|
||||||
|
@ -61,9 +61,9 @@ impl LateLintPass<'_> for BoxDefault {
|
||||||
} else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) {
|
} else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) {
|
||||||
with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()"))
|
with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()"))
|
||||||
} else {
|
} else {
|
||||||
return
|
return;
|
||||||
},
|
},
|
||||||
Applicability::MachineApplicable
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,8 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||||
Node::Expr(Expr {
|
Node::Expr(Expr {
|
||||||
kind: ExprKind::Call(path, args),
|
kind: ExprKind::Call(path, args),
|
||||||
..
|
..
|
||||||
}) | Node::Block(Block {
|
})
|
||||||
|
| Node::Block(Block {
|
||||||
expr:
|
expr:
|
||||||
Some(Expr {
|
Some(Expr {
|
||||||
kind: ExprKind::Call(path, args),
|
kind: ExprKind::Call(path, args),
|
||||||
|
@ -119,10 +120,10 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
) => {
|
) => {
|
||||||
if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) &&
|
if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
|
||||||
let Some(sig) = expr_sig(cx, path) &&
|
&& let Some(sig) = expr_sig(cx, path)
|
||||||
let Some(input) = sig.input(index) &&
|
&& let Some(input) = sig.input(index)
|
||||||
!cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait()
|
&& !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait()
|
||||||
{
|
{
|
||||||
input.no_bound_vars().is_some()
|
input.no_bound_vars().is_some()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,12 +9,19 @@ use rustc_middle::ty::{self, Ty, TypeAndMut};
|
||||||
use super::AS_PTR_CAST_MUT;
|
use super::AS_PTR_CAST_MUT;
|
||||||
|
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
|
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
|
||||||
if let ty::RawPtr(ptrty @ TypeAndMut { mutbl: Mutability::Mut, .. }) = cast_to.kind()
|
if let ty::RawPtr(
|
||||||
&& let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) =
|
ptrty @ TypeAndMut {
|
||||||
cx.typeck_results().node_type(cast_expr.hir_id).kind()
|
mutbl: Mutability::Mut, ..
|
||||||
|
},
|
||||||
|
) = cast_to.kind()
|
||||||
|
&& let ty::RawPtr(TypeAndMut {
|
||||||
|
mutbl: Mutability::Not, ..
|
||||||
|
}) = cx.typeck_results().node_type(cast_expr.hir_id).kind()
|
||||||
&& let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
|
&& let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
|
||||||
&& method_name.ident.name == rustc_span::sym::as_ptr
|
&& method_name.ident.name == rustc_span::sym::as_ptr
|
||||||
&& let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id)
|
&& let Some(as_ptr_did) = cx
|
||||||
|
.typeck_results()
|
||||||
|
.type_dependent_def_id(cast_expr.peel_blocks().hir_id)
|
||||||
&& let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity()
|
&& let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity()
|
||||||
&& let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
|
&& let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
|
||||||
&& let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
|
&& let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
|
||||||
|
@ -30,7 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
||||||
&format!("casting the result of `as_ptr` to *{ptrty}"),
|
&format!("casting the result of `as_ptr` to *{ptrty}"),
|
||||||
"replace with",
|
"replace with",
|
||||||
format!("{recv}.as_mut_ptr()"),
|
format!("{recv}.as_mut_ptr()"),
|
||||||
applicability
|
applicability,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::in_constant;
|
use clippy_utils::in_constant;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
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 rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
|
|
@ -26,8 +26,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
// There probably is no obvious reason to do this, just to be consistent with `as` cases.
|
// There probably is no obvious reason to do this, just to be consistent with `as` cases.
|
||||||
&& !is_hir_ty_cfg_dependant(cx, cast_to)
|
&& !is_hir_ty_cfg_dependant(cx, cast_to)
|
||||||
{
|
{
|
||||||
let (cast_from, cast_to) =
|
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));
|
||||||
(cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));
|
|
||||||
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
|
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,9 +80,9 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||||
cx.tcx.get_diagnostic_name(def_id),
|
cx.tcx.get_diagnostic_name(def_id),
|
||||||
Some(
|
Some(
|
||||||
sym::ptr_write_unaligned
|
sym::ptr_write_unaligned
|
||||||
| sym::ptr_read_unaligned
|
| sym::ptr_read_unaligned
|
||||||
| sym::intrinsics_unaligned_volatile_load
|
| sym::intrinsics_unaligned_volatile_load
|
||||||
| sym::intrinsics_unaligned_volatile_store
|
| sym::intrinsics_unaligned_volatile_store
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source;
|
use clippy_utils::source;
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::snippet_with_context;
|
use clippy_utils::source::snippet_with_context;
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
|
|
@ -22,8 +22,8 @@ mod unnecessary_cast;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod zero_ptr;
|
mod zero_ptr;
|
||||||
|
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::is_hir_ty_cfg_dependant;
|
use clippy_utils::is_hir_ty_cfg_dependant;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
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;
|
||||||
|
@ -45,7 +45,7 @@ declare_clippy_lint! {
|
||||||
/// those places in the code.
|
/// those places in the code.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = u64::MAX;
|
/// let x = u64::MAX;
|
||||||
/// x as f64;
|
/// x as f64;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -67,7 +67,7 @@ declare_clippy_lint! {
|
||||||
/// as a one-time check to see where numerical wrapping can arise.
|
/// as a one-time check to see where numerical wrapping can arise.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let y: i8 = -1;
|
/// let y: i8 = -1;
|
||||||
/// y as u128; // will return 18446744073709551615
|
/// y as u128; // will return 18446744073709551615
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -90,13 +90,13 @@ declare_clippy_lint! {
|
||||||
/// checks could be beneficial.
|
/// checks could be beneficial.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn as_u8(x: u64) -> u8 {
|
/// fn as_u8(x: u64) -> u8 {
|
||||||
/// x as u8
|
/// x as u8
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// fn as_u8(x: u64) -> u8 {
|
/// fn as_u8(x: u64) -> u8 {
|
||||||
/// if let Ok(x) = u8::try_from(x) {
|
/// if let Ok(x) = u8::try_from(x) {
|
||||||
/// x
|
/// x
|
||||||
|
@ -132,7 +132,7 @@ declare_clippy_lint! {
|
||||||
/// example below.
|
/// example below.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// 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"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
@ -155,7 +155,7 @@ declare_clippy_lint! {
|
||||||
/// people reading the code to know that the conversion is lossless.
|
/// people reading the code to know that the conversion is lossless.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn as_u64(x: u8) -> u64 {
|
/// fn as_u64(x: u8) -> u64 {
|
||||||
/// x as u64
|
/// x as u64
|
||||||
/// }
|
/// }
|
||||||
|
@ -163,7 +163,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// Using `::from` would look like this:
|
/// Using `::from` would look like this:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn as_u64(x: u8) -> u64 {
|
/// fn as_u64(x: u8) -> u64 {
|
||||||
/// u64::from(x)
|
/// u64::from(x)
|
||||||
/// }
|
/// }
|
||||||
|
@ -191,14 +191,14 @@ declare_clippy_lint! {
|
||||||
/// intermediate references, raw pointers and trait objects may or may not work.
|
/// intermediate references, raw pointers and trait objects may or may not work.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = 2i32 as i32;
|
/// let _ = 2i32 as i32;
|
||||||
/// let _ = 0.5 as f32;
|
/// let _ = 0.5 as f32;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Better:
|
/// Better:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = 2_i32;
|
/// let _ = 2_i32;
|
||||||
/// let _ = 0.5_f32;
|
/// let _ = 0.5_f32;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -223,7 +223,7 @@ declare_clippy_lint! {
|
||||||
/// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
|
/// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = (&1u8 as *const u8) as *const u16;
|
/// let _ = (&1u8 as *const u8) as *const u16;
|
||||||
/// let _ = (&mut 1u8 as *mut u8) as *mut u16;
|
/// let _ = (&mut 1u8 as *mut u8) as *mut u16;
|
||||||
///
|
///
|
||||||
|
@ -249,13 +249,13 @@ declare_clippy_lint! {
|
||||||
/// Casting to isize also doesn't make sense since there are no signed addresses.
|
/// Casting to isize also doesn't make sense since there are no signed addresses.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn fun() -> i32 { 1 }
|
/// fn fun() -> i32 { 1 }
|
||||||
/// let _ = fun as i64;
|
/// let _ = fun as i64;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn fun() -> i32 { 1 }
|
/// # fn fun() -> i32 { 1 }
|
||||||
/// let _ = fun as usize;
|
/// let _ = fun as usize;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -276,7 +276,7 @@ declare_clippy_lint! {
|
||||||
/// a comment) to perform the truncation.
|
/// a comment) to perform the truncation.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn fn1() -> i16 {
|
/// fn fn1() -> i16 {
|
||||||
/// 1
|
/// 1
|
||||||
/// };
|
/// };
|
||||||
|
@ -284,7 +284,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // Cast to usize first, then comment with the reason for the truncation
|
/// // Cast to usize first, then comment with the reason for the truncation
|
||||||
/// fn fn1() -> i16 {
|
/// fn fn1() -> i16 {
|
||||||
/// 1
|
/// 1
|
||||||
|
@ -310,7 +310,7 @@ declare_clippy_lint! {
|
||||||
/// pointer casts in your code.
|
/// pointer casts in your code.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // fn1 is cast as `usize`
|
/// // fn1 is cast as `usize`
|
||||||
/// fn fn1() -> u16 {
|
/// fn fn1() -> u16 {
|
||||||
/// 1
|
/// 1
|
||||||
|
@ -319,7 +319,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // maybe you intended to call the function?
|
/// // maybe you intended to call the function?
|
||||||
/// fn fn2() -> u16 {
|
/// fn fn2() -> u16 {
|
||||||
/// 1
|
/// 1
|
||||||
|
@ -378,14 +378,14 @@ declare_clippy_lint! {
|
||||||
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
|
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let ptr: *const u32 = &42_u32;
|
/// let ptr: *const u32 = &42_u32;
|
||||||
/// let mut_ptr: *mut u32 = &mut 42_u32;
|
/// let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
/// let _ = ptr as *const i32;
|
/// let _ = ptr as *const i32;
|
||||||
/// let _ = mut_ptr as *mut i32;
|
/// let _ = mut_ptr as *mut i32;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let ptr: *const u32 = &42_u32;
|
/// let ptr: *const u32 = &42_u32;
|
||||||
/// let mut_ptr: *mut u32 = &mut 42_u32;
|
/// let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
/// let _ = ptr.cast::<i32>();
|
/// let _ = ptr.cast::<i32>();
|
||||||
|
@ -408,13 +408,13 @@ declare_clippy_lint! {
|
||||||
/// type.
|
/// type.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let ptr: *const u32 = &42_u32;
|
/// let ptr: *const u32 = &42_u32;
|
||||||
/// let mut_ptr = ptr as *mut u32;
|
/// let mut_ptr = ptr as *mut u32;
|
||||||
/// let ptr = mut_ptr as *const u32;
|
/// let ptr = mut_ptr as *const u32;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let ptr: *const u32 = &42_u32;
|
/// let ptr: *const u32 = &42_u32;
|
||||||
/// let mut_ptr = ptr.cast_mut();
|
/// let mut_ptr = ptr.cast_mut();
|
||||||
/// let ptr = mut_ptr.cast_const();
|
/// let ptr = mut_ptr.cast_const();
|
||||||
|
@ -434,7 +434,7 @@ declare_clippy_lint! {
|
||||||
/// The resulting integral value will not match the value of the variant it came from.
|
/// The resulting integral value will not match the value of the variant it came from.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// enum E { X = 256 };
|
/// enum E { X = 256 };
|
||||||
/// let _ = E::X as u8;
|
/// let _ = E::X as u8;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -457,7 +457,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// // Missing data
|
/// // Missing data
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = [1_i32, 2, 3, 4];
|
/// let a = [1_i32, 2, 3, 4];
|
||||||
/// let p = &a as *const [i32] as *const [u8];
|
/// let p = &a as *const [i32] as *const [u8];
|
||||||
/// unsafe {
|
/// unsafe {
|
||||||
|
@ -465,7 +465,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// // Undefined Behavior (note: also potential alignment issues)
|
/// // Undefined Behavior (note: also potential alignment issues)
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = [1_u8, 2, 3, 4];
|
/// let a = [1_u8, 2, 3, 4];
|
||||||
/// let p = &a as *const [u8] as *const [u32];
|
/// let p = &a as *const [u8] as *const [u32];
|
||||||
/// unsafe {
|
/// unsafe {
|
||||||
|
@ -473,7 +473,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
|
/// Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = [1_i32, 2, 3, 4];
|
/// let a = [1_i32, 2, 3, 4];
|
||||||
/// let old_ptr = &a as *const [i32];
|
/// let old_ptr = &a as *const [i32];
|
||||||
/// // The data pointer is cast to a pointer to the target `u8` not `[u8]`
|
/// // The data pointer is cast to a pointer to the target `u8` not `[u8]`
|
||||||
|
@ -497,7 +497,7 @@ declare_clippy_lint! {
|
||||||
/// The cast is easily confused with casting a c-like enum value to an integer.
|
/// The cast is easily confused with casting a c-like enum value to an integer.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// enum E { X(i32) };
|
/// enum E { X(i32) };
|
||||||
/// let _ = E::X as usize;
|
/// let _ = E::X as usize;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -515,12 +515,12 @@ declare_clippy_lint! {
|
||||||
/// The `unsigned_abs()` method avoids panic when called on the MIN value.
|
/// The `unsigned_abs()` method avoids panic when called on the MIN value.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x: i32 = -42;
|
/// let x: i32 = -42;
|
||||||
/// let y: u32 = x.abs() as u32;
|
/// let y: u32 = x.abs() as u32;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x: i32 = -42;
|
/// let x: i32 = -42;
|
||||||
/// let y: u32 = x.unsigned_abs();
|
/// let y: u32 = x.unsigned_abs();
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -541,13 +541,13 @@ declare_clippy_lint! {
|
||||||
/// The lint is allowed by default as using `_` is less wordy than always specifying the type.
|
/// The lint is allowed by default as using `_` is less wordy than always specifying the type.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(n: usize) {}
|
/// fn foo(n: usize) {}
|
||||||
/// let n: u16 = 256;
|
/// let n: u16 = 256;
|
||||||
/// foo(n as _);
|
/// foo(n as _);
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(n: usize) {}
|
/// fn foo(n: usize) {}
|
||||||
/// let n: u16 = 256;
|
/// let n: u16 = 256;
|
||||||
/// foo(n as usize);
|
/// foo(n as usize);
|
||||||
|
@ -570,7 +570,7 @@ declare_clippy_lint! {
|
||||||
/// Read the `ptr::addr_of` docs for more information.
|
/// Read the `ptr::addr_of` docs for more information.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let val = 1;
|
/// let val = 1;
|
||||||
/// let p = &val as *const i32;
|
/// let p = &val as *const i32;
|
||||||
///
|
///
|
||||||
|
@ -578,7 +578,7 @@ declare_clippy_lint! {
|
||||||
/// let p_mut = &mut val_mut as *mut i32;
|
/// let p_mut = &mut val_mut as *mut i32;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let val = 1;
|
/// let val = 1;
|
||||||
/// let p = std::ptr::addr_of!(val);
|
/// let p = std::ptr::addr_of!(val);
|
||||||
///
|
///
|
||||||
|
@ -627,13 +627,13 @@ declare_clippy_lint! {
|
||||||
/// mutability is used, making it unlikely that having it as a mutable pointer is correct.
|
/// mutability is used, making it unlikely that having it as a mutable pointer is correct.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let mut vec = Vec::<u8>::with_capacity(1);
|
/// let mut vec = Vec::<u8>::with_capacity(1);
|
||||||
/// let ptr = vec.as_ptr() as *mut u8;
|
/// let ptr = vec.as_ptr() as *mut u8;
|
||||||
/// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
|
/// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let mut vec = Vec::<u8>::with_capacity(1);
|
/// let mut vec = Vec::<u8>::with_capacity(1);
|
||||||
/// let ptr = vec.as_mut_ptr();
|
/// let ptr = vec.as_mut_ptr();
|
||||||
/// unsafe { ptr.write(4) };
|
/// unsafe { ptr.write(4) };
|
||||||
|
@ -675,12 +675,12 @@ declare_clippy_lint! {
|
||||||
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
|
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = 0 as *const u32;
|
/// let a = 0 as *const u32;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = std::ptr::null::<u32>();
|
/// let a = std::ptr::null::<u32>();
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::snippet_with_applicability;
|
use clippy_utils::source::snippet_with_applicability;
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::msrvs::{Msrv, POINTER_CAST_CONSTNESS};
|
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -18,7 +18,7 @@ pub(super) fn check<'tcx>(
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if msrv.meets(POINTER_CAST_CONSTNESS);
|
if msrv.meets(msrvs::POINTER_CAST_CONSTNESS);
|
||||||
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind();
|
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind();
|
||||||
if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind();
|
if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind();
|
||||||
if matches!((from_mutbl, to_mutbl),
|
if matches!((from_mutbl, to_mutbl),
|
||||||
|
|
|
@ -97,7 +97,9 @@ pub(super) fn check<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip cast of fn call that returns type alias
|
// skip cast of fn call that returns type alias
|
||||||
if let ExprKind::Cast(inner, ..) = expr.kind && is_cast_from_ty_alias(cx, inner, cast_from) {
|
if let ExprKind::Cast(inner, ..) = expr.kind
|
||||||
|
&& is_cast_from_ty_alias(cx, inner, cast_from)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,11 +191,10 @@ fn lint_unnecessary_cast(
|
||||||
let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)
|
let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)
|
||||||
&& let ExprKind::MethodCall(..) = parent_expr.kind
|
&& let ExprKind::MethodCall(..) = parent_expr.kind
|
||||||
&& literal_str.starts_with('-')
|
&& literal_str.starts_with('-')
|
||||||
{
|
{
|
||||||
format!("({literal_str}_{cast_to})")
|
format!("({literal_str}_{cast_to})")
|
||||||
|
} else {
|
||||||
} else {
|
format!("{literal_str}_{cast_to}")
|
||||||
format!("{literal_str}_{cast_to}")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
@ -269,7 +270,9 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
|
||||||
&& let Some(parent) = get_parent_node(cx.tcx, hir_id)
|
&& let Some(parent) = get_parent_node(cx.tcx, hir_id)
|
||||||
&& let Node::Local(l) = parent
|
&& let Node::Local(l) = parent
|
||||||
{
|
{
|
||||||
if let Some(e) = l.init && is_cast_from_ty_alias(cx, e, cast_from) {
|
if let Some(e) = l.init
|
||||||
|
&& is_cast_from_ty_alias(cx, e, cast_from)
|
||||||
|
{
|
||||||
return ControlFlow::Break::<()>(());
|
return ControlFlow::Break::<()>(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! lint on manually implemented checked conversions that could be transformed into `try_from`
|
//! lint on manually implemented checked conversions that could be transformed into `try_from`
|
||||||
|
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::snippet_with_applicability;
|
use clippy_utils::source::snippet_with_applicability;
|
||||||
use clippy_utils::{in_constant, is_integer_literal, SpanlessEq};
|
use clippy_utils::{in_constant, is_integer_literal, SpanlessEq};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
@ -19,13 +19,13 @@ declare_clippy_lint! {
|
||||||
/// Reduces the readability of statements & is error prone.
|
/// Reduces the readability of statements & is error prone.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let foo: u32 = 5;
|
/// # let foo: u32 = 5;
|
||||||
/// foo <= i32::MAX as u32;
|
/// foo <= i32::MAX as u32;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let foo = 1;
|
/// # let foo = 1;
|
||||||
/// # #[allow(unused)]
|
/// # #[allow(unused)]
|
||||||
/// i32::try_from(foo).is_ok();
|
/// i32::try_from(foo).is_ok();
|
||||||
|
|
|
@ -32,7 +32,7 @@ declare_clippy_lint! {
|
||||||
/// makes code look more complex than it really is.
|
/// makes code look more complex than it really is.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let (x, y) = (true, true);
|
/// # let (x, y) = (true, true);
|
||||||
/// if x {
|
/// if x {
|
||||||
/// if y {
|
/// if y {
|
||||||
|
@ -42,7 +42,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let (x, y) = (true, true);
|
/// # let (x, y) = (true, true);
|
||||||
/// if x && y {
|
/// if x && y {
|
||||||
/// // …
|
/// // …
|
||||||
|
|
|
@ -20,7 +20,7 @@ declare_clippy_lint! {
|
||||||
/// instead.
|
/// instead.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let samples = vec![3, 1, 2];
|
/// # let samples = vec![3, 1, 2];
|
||||||
/// let mut sorted_samples = samples.clone();
|
/// let mut sorted_samples = samples.clone();
|
||||||
/// sorted_samples.sort();
|
/// sorted_samples.sort();
|
||||||
|
@ -29,7 +29,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let samples = vec![3, 1, 2];
|
/// # let samples = vec![3, 1, 2];
|
||||||
/// let mut sorted_samples = samples.clone();
|
/// let mut sorted_samples = samples.clone();
|
||||||
/// sorted_samples.sort();
|
/// sorted_samples.sort();
|
||||||
|
|
|
@ -18,7 +18,7 @@ declare_clippy_lint! {
|
||||||
/// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
|
/// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[macro_export]
|
/// #[macro_export]
|
||||||
/// macro_rules! print_message {
|
/// macro_rules! print_message {
|
||||||
/// () => {
|
/// () => {
|
||||||
|
@ -28,7 +28,7 @@ declare_clippy_lint! {
|
||||||
/// pub const MESSAGE: &str = "Hello!";
|
/// pub const MESSAGE: &str = "Hello!";
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[macro_export]
|
/// #[macro_export]
|
||||||
/// macro_rules! print_message {
|
/// macro_rules! print_message {
|
||||||
/// () => {
|
/// () => {
|
||||||
|
|
|
@ -6,8 +6,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION_INFO,
|
crate::utils::internal_lints::almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION_INFO,
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL_INFO,
|
|
||||||
#[cfg(feature = "internal")]
|
|
||||||
crate::utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS_INFO,
|
crate::utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS_INFO,
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS_INFO,
|
crate::utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS_INFO,
|
||||||
|
@ -30,6 +28,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO,
|
crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO,
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
|
crate::utils::internal_lints::metadata_collector::METADATA_COLLECTOR_INFO,
|
||||||
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO,
|
crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO,
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO,
|
crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO,
|
||||||
|
@ -37,6 +37,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
|
crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
|
crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
|
||||||
|
#[cfg(feature = "internal")]
|
||||||
|
crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO,
|
||||||
crate::absolute_paths::ABSOLUTE_PATHS_INFO,
|
crate::absolute_paths::ABSOLUTE_PATHS_INFO,
|
||||||
crate::allow_attributes::ALLOW_ATTRIBUTES_INFO,
|
crate::allow_attributes::ALLOW_ATTRIBUTES_INFO,
|
||||||
crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,
|
crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,
|
||||||
|
@ -272,6 +274,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::loops::NEVER_LOOP_INFO,
|
crate::loops::NEVER_LOOP_INFO,
|
||||||
crate::loops::SAME_ITEM_PUSH_INFO,
|
crate::loops::SAME_ITEM_PUSH_INFO,
|
||||||
crate::loops::SINGLE_ELEMENT_LOOP_INFO,
|
crate::loops::SINGLE_ELEMENT_LOOP_INFO,
|
||||||
|
crate::loops::UNUSED_ENUMERATE_INDEX_INFO,
|
||||||
crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
|
crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
|
||||||
crate::loops::WHILE_LET_LOOP_INFO,
|
crate::loops::WHILE_LET_LOOP_INFO,
|
||||||
crate::loops::WHILE_LET_ON_ITERATOR_INFO,
|
crate::loops::WHILE_LET_ON_ITERATOR_INFO,
|
||||||
|
@ -428,6 +431,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::methods::TYPE_ID_ON_BOX_INFO,
|
crate::methods::TYPE_ID_ON_BOX_INFO,
|
||||||
crate::methods::UNINIT_ASSUMED_INIT_INFO,
|
crate::methods::UNINIT_ASSUMED_INIT_INFO,
|
||||||
crate::methods::UNIT_HASH_INFO,
|
crate::methods::UNIT_HASH_INFO,
|
||||||
|
crate::methods::UNNECESSARY_FALLIBLE_CONVERSIONS_INFO,
|
||||||
crate::methods::UNNECESSARY_FILTER_MAP_INFO,
|
crate::methods::UNNECESSARY_FILTER_MAP_INFO,
|
||||||
crate::methods::UNNECESSARY_FIND_MAP_INFO,
|
crate::methods::UNNECESSARY_FIND_MAP_INFO,
|
||||||
crate::methods::UNNECESSARY_FOLD_INFO,
|
crate::methods::UNNECESSARY_FOLD_INFO,
|
||||||
|
@ -441,6 +445,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::methods::USELESS_ASREF_INFO,
|
crate::methods::USELESS_ASREF_INFO,
|
||||||
crate::methods::VEC_RESIZE_TO_ZERO_INFO,
|
crate::methods::VEC_RESIZE_TO_ZERO_INFO,
|
||||||
crate::methods::VERBOSE_FILE_READS_INFO,
|
crate::methods::VERBOSE_FILE_READS_INFO,
|
||||||
|
crate::methods::WAKER_CLONE_WAKE_INFO,
|
||||||
crate::methods::WRONG_SELF_CONVENTION_INFO,
|
crate::methods::WRONG_SELF_CONVENTION_INFO,
|
||||||
crate::methods::ZST_OFFSET_INFO,
|
crate::methods::ZST_OFFSET_INFO,
|
||||||
crate::min_ident_chars::MIN_IDENT_CHARS_INFO,
|
crate::min_ident_chars::MIN_IDENT_CHARS_INFO,
|
||||||
|
|
|
@ -23,12 +23,12 @@ declare_clippy_lint! {
|
||||||
/// generic `Default`.
|
/// generic `Default`.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let s: String = Default::default();
|
/// let s: String = Default::default();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let s = String::default();
|
/// let s = String::default();
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
@ -49,7 +49,7 @@ declare_clippy_lint! {
|
||||||
/// Assignments to patterns that are of tuple type are not linted.
|
/// Assignments to patterns that are of tuple type are not linted.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// # #[derive(Default)]
|
/// # #[derive(Default)]
|
||||||
/// # struct A { i: i32 }
|
/// # struct A { i: i32 }
|
||||||
/// let mut a: A = Default::default();
|
/// let mut a: A = Default::default();
|
||||||
|
@ -57,7 +57,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// # #[derive(Default)]
|
/// # #[derive(Default)]
|
||||||
/// # struct A { i: i32 }
|
/// # struct A { i: i32 }
|
||||||
/// let a = A {
|
/// let a = A {
|
||||||
|
|
|
@ -17,7 +17,7 @@ declare_clippy_lint! {
|
||||||
/// This adds code complexity and an unnecessary function call.
|
/// This adds code complexity and an unnecessary function call.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::marker::PhantomData;
|
/// # use std::marker::PhantomData;
|
||||||
/// #[derive(Default)]
|
/// #[derive(Default)]
|
||||||
/// struct S<T> {
|
/// struct S<T> {
|
||||||
|
@ -29,7 +29,7 @@ declare_clippy_lint! {
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::marker::PhantomData;
|
/// # use std::marker::PhantomData;
|
||||||
/// struct S<T> {
|
/// struct S<T> {
|
||||||
/// _marker: PhantomData<T>
|
/// _marker: PhantomData<T>
|
||||||
|
|
|
@ -14,12 +14,12 @@ declare_clippy_lint! {
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// `std::iter::empty()` is the more idiomatic way.
|
/// `std::iter::empty()` is the more idiomatic way.
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = std::iter::Empty::<usize>::default();
|
/// let _ = std::iter::Empty::<usize>::default();
|
||||||
/// let iter: std::iter::Empty<usize> = std::iter::Empty::default();
|
/// let iter: std::iter::Empty<usize> = std::iter::Empty::default();
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _ = std::iter::empty::<usize>();
|
/// let _ = std::iter::empty::<usize>();
|
||||||
/// let iter: std::iter::Empty<usize> = std::iter::empty();
|
/// let iter: std::iter::Empty<usize> = std::iter::empty();
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -68,7 +68,10 @@ fn make_sugg(
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
format!("std::iter::empty::<{}>()", snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0)
|
format!(
|
||||||
|
"std::iter::empty::<{}>()",
|
||||||
|
snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
"std::iter::empty()".to_owned()
|
"std::iter::empty()".to_owned()
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,13 @@ declare_clippy_lint! {
|
||||||
/// This lint can only be allowed at the function level or above.
|
/// This lint can only be allowed at the function level or above.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let i = 10;
|
/// let i = 10;
|
||||||
/// let f = 1.23;
|
/// let f = 1.23;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let i = 10i32;
|
/// let i = 10i32;
|
||||||
/// let f = 1.23f64;
|
/// let f = 1.23f64;
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -17,7 +17,7 @@ declare_clippy_lint! {
|
||||||
/// specified layout. These cases may lead to undefined behavior in unsafe blocks.
|
/// specified layout. These cases may lead to undefined behavior in unsafe blocks.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// union Foo {
|
/// union Foo {
|
||||||
/// a: i32,
|
/// a: i32,
|
||||||
/// b: u32,
|
/// b: u32,
|
||||||
|
@ -30,7 +30,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[repr(C)]
|
/// #[repr(C)]
|
||||||
/// union Foo {
|
/// union Foo {
|
||||||
/// a: i32,
|
/// a: i32,
|
||||||
|
|
|
@ -29,14 +29,14 @@ declare_clippy_lint! {
|
||||||
/// when not part of a method chain.
|
/// when not part of a method chain.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::ops::Deref;
|
/// use std::ops::Deref;
|
||||||
/// let a: &mut String = &mut String::from("foo");
|
/// let a: &mut String = &mut String::from("foo");
|
||||||
/// let b: &str = a.deref();
|
/// let b: &str = a.deref();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a: &mut String = &mut String::from("foo");
|
/// let a: &mut String = &mut String::from("foo");
|
||||||
/// let b = &*a;
|
/// let b = &*a;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -68,7 +68,7 @@ declare_clippy_lint! {
|
||||||
/// in such a case can change the semantics of the code.
|
/// in such a case can change the semantics of the code.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn fun(_a: &i32) {}
|
/// fn fun(_a: &i32) {}
|
||||||
///
|
///
|
||||||
/// let x: &i32 = &&&&&&5;
|
/// let x: &i32 = &&&&&&5;
|
||||||
|
@ -76,7 +76,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn fun(_a: &i32) {}
|
/// # fn fun(_a: &i32) {}
|
||||||
/// let x: &i32 = &5;
|
/// let x: &i32 = &5;
|
||||||
/// fun(x);
|
/// fun(x);
|
||||||
|
@ -95,7 +95,7 @@ declare_clippy_lint! {
|
||||||
/// The address-of operator at the use site is clearer about the need for a reference.
|
/// The address-of operator at the use site is clearer about the need for a reference.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = Some("");
|
/// let x = Some("");
|
||||||
/// if let Some(ref x) = x {
|
/// if let Some(ref x) = x {
|
||||||
/// // use `x` here
|
/// // use `x` here
|
||||||
|
@ -103,7 +103,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = Some("");
|
/// let x = Some("");
|
||||||
/// if let Some(x) = x {
|
/// if let Some(x) = x {
|
||||||
/// // use `&x` here
|
/// // use `&x` here
|
||||||
|
@ -123,12 +123,12 @@ declare_clippy_lint! {
|
||||||
/// This unnecessarily complicates the code.
|
/// This unnecessarily complicates the code.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = String::new();
|
/// let x = String::new();
|
||||||
/// let y: &str = &*x;
|
/// let y: &str = &*x;
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let x = String::new();
|
/// let x = String::new();
|
||||||
/// let y: &str = &x;
|
/// let y: &str = &x;
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -353,23 +353,26 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
|
||||||
// priority.
|
// priority.
|
||||||
if let Some(fn_id) = typeck.type_dependent_def_id(hir_id)
|
if let Some(fn_id) = typeck.type_dependent_def_id(hir_id)
|
||||||
&& let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
|
&& let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
|
||||||
&& let arg_ty
|
&& let arg_ty = cx
|
||||||
= cx.tcx.erase_regions(use_cx.adjustments.last().map_or(expr_ty, |a| a.target))
|
.tcx
|
||||||
|
.erase_regions(use_cx.adjustments.last().map_or(expr_ty, |a| a.target))
|
||||||
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
|
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
|
||||||
&& let args = cx
|
&& let args = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default()
|
.node_args_opt(hir_id)
|
||||||
&& let impl_ty = if cx.tcx.fn_sig(fn_id)
|
.map(|args| &args[1..])
|
||||||
.instantiate_identity()
|
.unwrap_or_default()
|
||||||
.skip_binder()
|
&& let impl_ty =
|
||||||
.inputs()[0].is_ref()
|
if cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder().inputs()[0]
|
||||||
{
|
.is_ref()
|
||||||
// Trait methods taking `&self`
|
{
|
||||||
sub_ty
|
// Trait methods taking `&self`
|
||||||
} else {
|
sub_ty
|
||||||
// Trait methods taking `self`
|
} else {
|
||||||
arg_ty
|
// Trait methods taking `self`
|
||||||
} && impl_ty.is_ref()
|
arg_ty
|
||||||
|
}
|
||||||
|
&& impl_ty.is_ref()
|
||||||
&& implements_trait(
|
&& implements_trait(
|
||||||
cx,
|
cx,
|
||||||
impl_ty,
|
impl_ty,
|
||||||
|
@ -414,9 +417,9 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
|
||||||
let (required_refs, msg) = if can_auto_borrow {
|
let (required_refs, msg) = if can_auto_borrow {
|
||||||
(1, if deref_count == 1 { borrow_msg } else { deref_msg })
|
(1, if deref_count == 1 { borrow_msg } else { deref_msg })
|
||||||
} else if let Some(&Adjustment {
|
} else if let Some(&Adjustment {
|
||||||
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
|
kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
|
||||||
..
|
..
|
||||||
}) = next_adjust
|
}) = next_adjust
|
||||||
&& matches!(mutability, AutoBorrowMutability::Mut { .. })
|
&& matches!(mutability, AutoBorrowMutability::Mut { .. })
|
||||||
&& !stability.is_reborrow_stable()
|
&& !stability.is_reborrow_stable()
|
||||||
{
|
{
|
||||||
|
@ -705,9 +708,11 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
|
||||||
{
|
{
|
||||||
match parent.kind {
|
match parent.kind {
|
||||||
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
|
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
|
||||||
if child.hir_id == e.hir_id => true,
|
if child.hir_id == e.hir_id =>
|
||||||
ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)
|
{
|
||||||
| ExprKind::Field(_, _) => true,
|
true
|
||||||
|
},
|
||||||
|
ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar) | ExprKind::Field(_, _) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::indent_of;
|
use clippy_utils::source::indent_of;
|
||||||
use clippy_utils::{is_default_equivalent, peel_blocks};
|
use clippy_utils::{is_default_equivalent, peel_blocks};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -21,7 +21,7 @@ declare_clippy_lint! {
|
||||||
/// It is less concise.
|
/// It is less concise.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// bar: bool
|
/// bar: bool
|
||||||
/// }
|
/// }
|
||||||
|
@ -36,7 +36,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[derive(Default)]
|
/// #[derive(Default)]
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// bar: bool
|
/// bar: bool
|
||||||
|
|
|
@ -173,7 +173,7 @@ declare_clippy_lint! {
|
||||||
/// `Eq` themselves.
|
/// `Eq` themselves.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[derive(PartialEq)]
|
/// #[derive(PartialEq)]
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// i_am_eq: i32,
|
/// i_am_eq: i32,
|
||||||
|
@ -181,7 +181,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[derive(PartialEq, Eq)]
|
/// #[derive(PartialEq, Eq)]
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// i_am_eq: i32,
|
/// i_am_eq: i32,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use clippy_config::types::DisallowedPath;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::macros::macro_backtrace;
|
use clippy_utils::macros::macro_backtrace;
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::Attribute;
|
||||||
|
@ -8,8 +9,6 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{ExpnId, Span};
|
use rustc_span::{ExpnId, Span};
|
||||||
|
|
||||||
use crate::utils::conf;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Denies the configured macros in clippy.toml
|
/// Denies the configured macros in clippy.toml
|
||||||
|
@ -35,7 +34,7 @@ declare_clippy_lint! {
|
||||||
/// { path = "serde::Serialize", reason = "no serializing" },
|
/// { path = "serde::Serialize", reason = "no serializing" },
|
||||||
/// ]
|
/// ]
|
||||||
/// ```
|
/// ```
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// use serde::Serialize;
|
/// use serde::Serialize;
|
||||||
///
|
///
|
||||||
/// // Example code where clippy issues a warning
|
/// // Example code where clippy issues a warning
|
||||||
|
@ -55,13 +54,13 @@ declare_clippy_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DisallowedMacros {
|
pub struct DisallowedMacros {
|
||||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
conf_disallowed: Vec<DisallowedPath>,
|
||||||
disallowed: DefIdMap<usize>,
|
disallowed: DefIdMap<usize>,
|
||||||
seen: FxHashSet<ExpnId>,
|
seen: FxHashSet<ExpnId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisallowedMacros {
|
impl DisallowedMacros {
|
||||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conf_disallowed,
|
conf_disallowed,
|
||||||
disallowed: DefIdMap::default(),
|
disallowed: DefIdMap::default(),
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
|
use clippy_config::types::DisallowedPath;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
|
use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
|
||||||
|
|
||||||
use rustc_hir::def_id::DefIdMap;
|
use rustc_hir::def_id::DefIdMap;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
|
||||||
use crate::utils::conf;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Denies the configured methods and functions in clippy.toml
|
/// Denies the configured methods and functions in clippy.toml
|
||||||
|
@ -59,12 +57,12 @@ declare_clippy_lint! {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisallowedMethods {
|
pub struct DisallowedMethods {
|
||||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
conf_disallowed: Vec<DisallowedPath>,
|
||||||
disallowed: DefIdMap<usize>,
|
disallowed: DefIdMap<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisallowedMethods {
|
impl DisallowedMethods {
|
||||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conf_disallowed,
|
conf_disallowed,
|
||||||
disallowed: DefIdMap::default(),
|
disallowed: DefIdMap::default(),
|
||||||
|
|
|
@ -15,7 +15,7 @@ declare_clippy_lint! {
|
||||||
/// avoided.
|
/// avoided.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let foo = 3.14;
|
/// let foo = 3.14;
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
|
|
@ -30,7 +30,7 @@ declare_clippy_lint! {
|
||||||
/// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
|
/// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // Assuming that `clippy.toml` contains the following line:
|
/// // Assuming that `clippy.toml` contains the following line:
|
||||||
/// // allowed-scripts = ["Latin", "Cyrillic"]
|
/// // allowed-scripts = ["Latin", "Cyrillic"]
|
||||||
/// let counter = 10; // OK, latin is allowed.
|
/// let counter = 10; // OK, latin is allowed.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use clippy_config::types::DisallowedPath;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
@ -8,8 +8,6 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use crate::utils::conf;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Denies the configured types in clippy.toml.
|
/// Denies the configured types in clippy.toml.
|
||||||
|
@ -50,15 +48,16 @@ declare_clippy_lint! {
|
||||||
style,
|
style,
|
||||||
"use of disallowed types"
|
"use of disallowed types"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisallowedTypes {
|
pub struct DisallowedTypes {
|
||||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
conf_disallowed: Vec<DisallowedPath>,
|
||||||
def_ids: FxHashMap<DefId, usize>,
|
def_ids: FxHashMap<DefId, usize>,
|
||||||
prim_tys: FxHashMap<PrimTy, usize>,
|
prim_tys: FxHashMap<PrimTy, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisallowedTypes {
|
impl DisallowedTypes {
|
||||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conf_disallowed,
|
conf_disallowed,
|
||||||
def_ids: FxHashMap::default(),
|
def_ids: FxHashMap::default(),
|
||||||
|
@ -123,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &conf::DisallowedPath) {
|
fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &DisallowedPath) {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
DISALLOWED_TYPES,
|
DISALLOWED_TYPES,
|
||||||
|
|
|
@ -58,14 +58,14 @@ declare_clippy_lint! {
|
||||||
/// would fail.
|
/// would fail.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// Do something with the foo_bar parameter. See also
|
/// /// Do something with the foo_bar parameter. See also
|
||||||
/// /// that::other::module::foo.
|
/// /// that::other::module::foo.
|
||||||
/// // ^ `foo_bar` and `that::other::module::foo` should be ticked.
|
/// // ^ `foo_bar` and `that::other::module::foo` should be ticked.
|
||||||
/// fn doit(foo_bar: usize) {}
|
/// fn doit(foo_bar: usize) {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // Link text with `[]` brackets should be written as following:
|
/// // Link text with `[]` brackets should be written as following:
|
||||||
/// /// Consume the array and return the inner
|
/// /// Consume the array and return the inner
|
||||||
/// /// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].
|
/// /// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].
|
||||||
|
@ -88,7 +88,7 @@ declare_clippy_lint! {
|
||||||
/// preconditions, so that users can be sure they are using them safely.
|
/// preconditions, so that users can be sure they are using them safely.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///# type Universe = ();
|
///# type Universe = ();
|
||||||
/// /// This function should really be documented
|
/// /// This function should really be documented
|
||||||
/// pub unsafe fn start_apocalypse(u: &mut Universe) {
|
/// pub unsafe fn start_apocalypse(u: &mut Universe) {
|
||||||
|
@ -98,7 +98,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// At least write a line about safety:
|
/// At least write a line about safety:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///# type Universe = ();
|
///# type Universe = ();
|
||||||
/// /// # Safety
|
/// /// # Safety
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -126,7 +126,7 @@ declare_clippy_lint! {
|
||||||
/// Since the following function returns a `Result` it has an `# Errors` section in
|
/// Since the following function returns a `Result` it has an `# Errors` section in
|
||||||
/// its doc comment:
|
/// its doc comment:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///# use std::io;
|
///# use std::io;
|
||||||
/// /// # Errors
|
/// /// # Errors
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -155,7 +155,7 @@ declare_clippy_lint! {
|
||||||
/// Since the following function may panic it has a `# Panics` section in
|
/// Since the following function may panic it has a `# Panics` section in
|
||||||
/// its doc comment:
|
/// its doc comment:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// # Panics
|
/// /// # Panics
|
||||||
/// ///
|
/// ///
|
||||||
/// /// Will panic if y is 0
|
/// /// Will panic if y is 0
|
||||||
|
@ -182,7 +182,7 @@ declare_clippy_lint! {
|
||||||
/// if the `fn main()` is left implicit.
|
/// if the `fn main()` is left implicit.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// An example of a doctest with a `main()` function
|
/// /// An example of a doctest with a `main()` function
|
||||||
/// ///
|
/// ///
|
||||||
/// /// # Examples
|
/// /// # Examples
|
||||||
|
@ -210,12 +210,12 @@ declare_clippy_lint! {
|
||||||
/// It is likely a typo when defining an intra-doc link
|
/// It is likely a typo when defining an intra-doc link
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// See also: ['foo']
|
/// /// See also: ['foo']
|
||||||
/// fn bar() {}
|
/// fn bar() {}
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// See also: [`foo`]
|
/// /// See also: [`foo`]
|
||||||
/// fn bar() {}
|
/// fn bar() {}
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -235,7 +235,7 @@ declare_clippy_lint! {
|
||||||
/// need to describe safety preconditions that users are required to uphold.
|
/// need to describe safety preconditions that users are required to uphold.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///# type Universe = ();
|
///# type Universe = ();
|
||||||
/// /// # Safety
|
/// /// # Safety
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -248,7 +248,7 @@ declare_clippy_lint! {
|
||||||
/// The function is safe, so there shouldn't be any preconditions
|
/// The function is safe, so there shouldn't be any preconditions
|
||||||
/// that have to be explained for safety reasons.
|
/// that have to be explained for safety reasons.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///# type Universe = ();
|
///# type Universe = ();
|
||||||
/// /// This function should really be documented
|
/// /// This function should really be documented
|
||||||
/// pub fn start_apocalypse(u: &mut Universe) {
|
/// pub fn start_apocalypse(u: &mut Universe) {
|
||||||
|
@ -569,9 +569,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
||||||
if let End(Heading(_, _, _)) = event {
|
if let End(Heading(_, _, _)) = event {
|
||||||
in_heading = false;
|
in_heading = false;
|
||||||
}
|
}
|
||||||
if ticks_unbalanced
|
if ticks_unbalanced && let Some(span) = fragments.span(cx, paragraph_range.clone()) {
|
||||||
&& let Some(span) = fragments.span(cx, paragraph_range.clone())
|
|
||||||
{
|
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
DOC_MARKDOWN,
|
DOC_MARKDOWN,
|
||||||
|
@ -617,8 +615,9 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
||||||
check_link_quotes(cx, trimmed_text, range.clone(), fragments);
|
check_link_quotes(cx, trimmed_text, range.clone(), fragments);
|
||||||
}
|
}
|
||||||
if let Some(link) = in_link.as_ref()
|
if let Some(link) = in_link.as_ref()
|
||||||
&& let Ok(url) = Url::parse(link)
|
&& let Ok(url) = Url::parse(link)
|
||||||
&& (url.scheme() == "https" || url.scheme() == "http") {
|
&& (url.scheme() == "https" || url.scheme() == "http")
|
||||||
|
{
|
||||||
// Don't check the text associated with external URLs
|
// Don't check the text associated with external URLs
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -716,7 +715,9 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, range: Range<u
|
||||||
// Because of the global session, we need to create a new session in a different thread with
|
// Because of the global session, we need to create a new session in a different thread with
|
||||||
// the edition we need.
|
// the edition we need.
|
||||||
let text = text.to_owned();
|
let text = text.to_owned();
|
||||||
if thread::spawn(move || has_needless_main(text, edition)).join().expect("thread::spawn failed")
|
if thread::spawn(move || has_needless_main(text, edition))
|
||||||
|
.join()
|
||||||
|
.expect("thread::spawn failed")
|
||||||
&& let Some(span) = fragments.span(cx, range.start..range.end - trailing_whitespace)
|
&& let Some(span) = fragments.span(cx, range.start..range.end - trailing_whitespace)
|
||||||
{
|
{
|
||||||
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
|
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
|
||||||
|
@ -756,11 +757,12 @@ fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
|
fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
|
||||||
/// Checks if a string is camel-case, i.e., contains at least two uppercase
|
/// Checks if a string is upper-camel-case, i.e., starts with an uppercase and
|
||||||
/// letters (`Clippy` is ok) and one lower-case letter (`NASA` is ok).
|
/// contains at least two uppercase letters (`Clippy` is ok) and one lower-case
|
||||||
|
/// letter (`NASA` is ok).
|
||||||
/// Plurals are also excluded (`IDs` is ok).
|
/// Plurals are also excluded (`IDs` is ok).
|
||||||
fn is_camel_case(s: &str) -> bool {
|
fn is_camel_case(s: &str) -> bool {
|
||||||
if s.starts_with(|c: char| c.is_ascii_digit()) {
|
if s.starts_with(|c: char| c.is_ascii_digit() | c.is_ascii_lowercase()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ declare_clippy_lint! {
|
||||||
/// mistake.
|
/// mistake.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn simple_double_parens() -> i32 {
|
/// fn simple_double_parens() -> i32 {
|
||||||
/// ((0))
|
/// ((0))
|
||||||
/// }
|
/// }
|
||||||
|
@ -22,7 +22,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn simple_no_parens() -> i32 {
|
/// fn simple_no_parens() -> i32 {
|
||||||
/// 0
|
/// 0
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -16,7 +16,7 @@ declare_clippy_lint! {
|
||||||
/// have been intended.
|
/// have been intended.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo;
|
/// struct Foo;
|
||||||
/// let x = Foo;
|
/// let x = Foo;
|
||||||
/// std::mem::drop(x);
|
/// std::mem::drop(x);
|
||||||
|
@ -36,7 +36,7 @@ declare_clippy_lint! {
|
||||||
/// have been intended.
|
/// have been intended.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo;
|
/// struct Foo;
|
||||||
/// let x = Foo;
|
/// let x = Foo;
|
||||||
/// std::mem::forget(x);
|
/// std::mem::forget(x);
|
||||||
|
@ -57,7 +57,7 @@ declare_clippy_lint! {
|
||||||
/// destructor, possibly causing leaks.
|
/// destructor, possibly causing leaks.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::mem;
|
/// # use std::mem;
|
||||||
/// # use std::rc::Rc;
|
/// # use std::rc::Rc;
|
||||||
/// mem::forget(Rc::new(55))
|
/// mem::forget(Rc::new(55))
|
||||||
|
@ -90,7 +90,8 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
|
||||||
let is_copy = is_copy(cx, arg_ty);
|
let is_copy = is_copy(cx, arg_ty);
|
||||||
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
|
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
|
||||||
let (lint, msg, note_span) = match fn_name {
|
let (lint, msg, note_span) = match fn_name {
|
||||||
// early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references, forgetting_copy_types
|
// early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references,
|
||||||
|
// forgetting_copy_types
|
||||||
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,
|
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,
|
||||||
sym::mem_forget if arg_ty.is_ref() => return,
|
sym::mem_forget if arg_ty.is_ref() => return,
|
||||||
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
|
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
|
||||||
|
@ -100,8 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
|
||||||
if !(arg_ty.needs_drop(cx.tcx, cx.param_env)
|
if !(arg_ty.needs_drop(cx.tcx, cx.param_env)
|
||||||
|| is_must_use_func_call(cx, arg)
|
|| is_must_use_func_call(cx, arg)
|
||||||
|| is_must_use_ty(cx, arg_ty)
|
|| is_must_use_ty(cx, arg_ty)
|
||||||
|| drop_is_single_call_in_arm
|
|| drop_is_single_call_in_arm) =>
|
||||||
) =>
|
|
||||||
{
|
{
|
||||||
(DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span))
|
(DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span))
|
||||||
},
|
},
|
||||||
|
@ -122,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
|
||||||
} else {
|
} else {
|
||||||
(FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span))
|
(FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
span_lint_and_note(
|
span_lint_and_note(
|
||||||
|
|
|
@ -15,7 +15,7 @@ declare_clippy_lint! {
|
||||||
/// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
|
/// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn a() {}
|
/// # fn a() {}
|
||||||
/// # fn b() {}
|
/// # fn b() {}
|
||||||
/// # let x: i32 = 1;
|
/// # let x: i32 = 1;
|
||||||
|
@ -28,7 +28,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # fn a() {}
|
/// # fn a() {}
|
||||||
/// # fn b() {}
|
/// # fn b() {}
|
||||||
/// # let x: i32 = 1;
|
/// # let x: i32 = 1;
|
||||||
|
|
|
@ -16,7 +16,7 @@ declare_clippy_lint! {
|
||||||
/// destructured, which might be the intention behind adding the implementation as a marker.
|
/// destructured, which might be the intention behind adding the implementation as a marker.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct S;
|
/// struct S;
|
||||||
///
|
///
|
||||||
/// impl Drop for S {
|
/// impl Drop for S {
|
||||||
|
@ -24,7 +24,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct S;
|
/// struct S;
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.62.0"]
|
#[clippy::version = "1.62.0"]
|
||||||
|
|
|
@ -23,12 +23,12 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// enum Test {}
|
/// enum Test {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #![feature(never_type)]
|
/// #![feature(never_type)]
|
||||||
///
|
///
|
||||||
/// struct Test(!);
|
/// struct Test(!);
|
||||||
|
|
|
@ -15,11 +15,11 @@ declare_clippy_lint! {
|
||||||
/// Empty brackets after a struct declaration can be omitted.
|
/// Empty brackets after a struct declaration can be omitted.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Cookie {}
|
/// struct Cookie {}
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Cookie;
|
/// struct Cookie;
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.62.0"]
|
#[clippy::version = "1.62.0"]
|
||||||
|
@ -35,7 +35,8 @@ impl EarlyLintPass for EmptyStructsWithBrackets {
|
||||||
|
|
||||||
if let ItemKind::Struct(var_data, _) = &item.kind
|
if let ItemKind::Struct(var_data, _) = &item.kind
|
||||||
&& has_brackets(var_data)
|
&& has_brackets(var_data)
|
||||||
&& has_no_fields(cx, var_data, span_after_ident) {
|
&& has_no_fields(cx, var_data, span_after_ident)
|
||||||
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
EMPTY_STRUCTS_WITH_BRACKETS,
|
EMPTY_STRUCTS_WITH_BRACKETS,
|
||||||
|
@ -46,8 +47,9 @@ impl EarlyLintPass for EmptyStructsWithBrackets {
|
||||||
span_after_ident,
|
span_after_ident,
|
||||||
"remove the brackets",
|
"remove the brackets",
|
||||||
";",
|
";",
|
||||||
Applicability::Unspecified);
|
Applicability::Unspecified,
|
||||||
},
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Known problems
|
/// ### Known problems
|
||||||
/// The suggestion may have type inference errors in some cases. e.g.
|
/// The suggestion may have type inference errors in some cases. e.g.
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let mut map = std::collections::HashMap::new();
|
/// let mut map = std::collections::HashMap::new();
|
||||||
/// let _ = if !map.contains_key(&0) {
|
/// let _ = if !map.contains_key(&0) {
|
||||||
/// map.insert(0, 0)
|
/// map.insert(0, 0)
|
||||||
|
@ -33,7 +33,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::collections::HashMap;
|
/// # use std::collections::HashMap;
|
||||||
/// # let mut map = HashMap::new();
|
/// # let mut map = HashMap::new();
|
||||||
/// # let k = 1;
|
/// # let k = 1;
|
||||||
|
@ -43,7 +43,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::collections::HashMap;
|
/// # use std::collections::HashMap;
|
||||||
/// # let mut map = HashMap::new();
|
/// # let mut map = HashMap::new();
|
||||||
/// # let k = 1;
|
/// # let k = 1;
|
||||||
|
|
|
@ -19,7 +19,7 @@ declare_clippy_lint! {
|
||||||
/// architectures, but works fine on 64 bit.
|
/// architectures, but works fine on 64 bit.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # #[cfg(target_pointer_width = "64")]
|
/// # #[cfg(target_pointer_width = "64")]
|
||||||
/// #[repr(usize)]
|
/// #[repr(usize)]
|
||||||
/// enum NonPortable {
|
/// enum NonPortable {
|
||||||
|
|
|
@ -68,7 +68,8 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if !in_external_macro(cx.sess(), expr.span)
|
if !in_external_macro(cx.sess(), expr.span)
|
||||||
&& let ExprKind::Let(let_expr) = expr.kind
|
&& let ExprKind::Let(let_expr) = expr.kind
|
||||||
&& unary_pattern(let_expr.pat) {
|
&& unary_pattern(let_expr.pat)
|
||||||
|
{
|
||||||
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
|
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
|
||||||
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
|
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
@ -79,7 +80,9 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
|
||||||
"({})",
|
"({})",
|
||||||
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
|
snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
|
||||||
),
|
),
|
||||||
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
|
_ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability)
|
||||||
|
.0
|
||||||
|
.to_string(),
|
||||||
};
|
};
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -41,10 +41,11 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
|
||||||
};
|
};
|
||||||
|
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ItemKind::TyAlias(..) if item.ident.name == sym::Error
|
ItemKind::TyAlias(..)
|
||||||
&& is_visible_outside_module(cx, item.owner_id.def_id)
|
if item.ident.name == sym::Error
|
||||||
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
|
&& is_visible_outside_module(cx, item.owner_id.def_id)
|
||||||
&& implements_trait(cx, ty, error_def_id, &[]) =>
|
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
|
||||||
|
&& implements_trait(cx, ty, error_def_id, &[]) =>
|
||||||
{
|
{
|
||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
|
@ -53,13 +54,14 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
|
||||||
"exported type alias named `Error` that implements `Error`",
|
"exported type alias named `Error` that implements `Error`",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
ItemKind::Impl(imp) if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_def_id())
|
ItemKind::Impl(imp)
|
||||||
&& error_def_id == trait_def_id
|
if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_def_id())
|
||||||
&& let Some(def_id) = path_res(cx, imp.self_ty).opt_def_id().and_then(DefId::as_local)
|
&& error_def_id == trait_def_id
|
||||||
&& let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id)
|
&& let Some(def_id) = path_res(cx, imp.self_ty).opt_def_id().and_then(DefId::as_local)
|
||||||
&& let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id())
|
&& let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id)
|
||||||
&& ident.name == sym::Error
|
&& let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id())
|
||||||
&& is_visible_outside_module(cx, def_id) =>
|
&& ident.name == sym::Error
|
||||||
|
&& is_visible_outside_module(cx, def_id) =>
|
||||||
{
|
{
|
||||||
span_lint_hir_and_then(
|
span_lint_hir_and_then(
|
||||||
cx,
|
cx,
|
||||||
|
@ -69,9 +71,9 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
|
||||||
"exported type named `Error` that implements `Error`",
|
"exported type named `Error` that implements `Error`",
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_note(item.span, "`Error` was implemented here");
|
diag.span_note(item.span, "`Error` was implemented here");
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ declare_clippy_lint! {
|
||||||
/// into something.
|
/// into something.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(x: Box<u32>) {}
|
/// fn foo(x: Box<u32>) {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(x: u32) {}
|
/// fn foo(x: u32) {}
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
|
|
|
@ -119,19 +119,21 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||||
|
|
||||||
match body.value.kind {
|
match body.value.kind {
|
||||||
ExprKind::Call(callee, args)
|
ExprKind::Call(callee, args)
|
||||||
if matches!(callee.kind, ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..))) =>
|
if matches!(
|
||||||
|
callee.kind,
|
||||||
|
ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..))
|
||||||
|
) =>
|
||||||
{
|
{
|
||||||
let callee_ty = typeck.expr_ty(callee).peel_refs();
|
let callee_ty = typeck.expr_ty(callee).peel_refs();
|
||||||
if matches!(
|
if matches!(type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc))
|
||||||
type_diagnostic_name(cx, callee_ty),
|
|| !check_inputs(typeck, body.params, None, args)
|
||||||
Some(sym::Arc | sym::Rc)
|
{
|
||||||
) || !check_inputs(typeck, body.params, None, args) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let callee_ty_adjusted = typeck.expr_adjustments(callee).last().map_or(
|
let callee_ty_adjusted = typeck
|
||||||
callee_ty,
|
.expr_adjustments(callee)
|
||||||
|a| a.target.peel_refs(),
|
.last()
|
||||||
);
|
.map_or(callee_ty, |a| a.target.peel_refs());
|
||||||
|
|
||||||
let sig = match callee_ty_adjusted.kind() {
|
let sig = match callee_ty_adjusted.kind() {
|
||||||
ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(),
|
ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(),
|
||||||
|
@ -160,36 +162,26 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||||
// For now ignore all callee types which reference a type parameter.
|
// For now ignore all callee types which reference a type parameter.
|
||||||
&& !generic_args.types().any(|t| matches!(t.kind(), ty::Param(_)))
|
&& !generic_args.types().any(|t| matches!(t.kind(), ty::Param(_)))
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
|
||||||
cx,
|
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
|
||||||
REDUNDANT_CLOSURE,
|
if let Ok((ClosureKind::FnMut, _)) = cx.tcx.infer_ctxt().build().type_implements_fn_trait(
|
||||||
expr.span,
|
cx.param_env,
|
||||||
"redundant closure",
|
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
|
||||||
|diag| {
|
ImplPolarity::Positive,
|
||||||
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
|
) && path_to_local(callee).map_or(false, |l| {
|
||||||
if let Ok((ClosureKind::FnMut, _))
|
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
|
||||||
= cx.tcx.infer_ctxt().build().type_implements_fn_trait(
|
}) {
|
||||||
cx.param_env,
|
// Mutable closure is used after current expr; we cannot consume it.
|
||||||
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
|
snippet = format!("&mut {snippet}");
|
||||||
ImplPolarity::Positive,
|
|
||||||
) && path_to_local(callee)
|
|
||||||
.map_or(
|
|
||||||
false,
|
|
||||||
|l| local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr),
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Mutable closure is used after current expr; we cannot consume it.
|
|
||||||
snippet = format!("&mut {snippet}");
|
|
||||||
}
|
|
||||||
diag.span_suggestion(
|
|
||||||
expr.span,
|
|
||||||
"replace the closure with the function itself",
|
|
||||||
snippet,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
diag.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"replace the closure with the function itself",
|
||||||
|
snippet,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
|
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
|
||||||
|
|
|
@ -22,7 +22,7 @@ declare_clippy_lint! {
|
||||||
/// readability and API.
|
/// readability and API.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct S {
|
/// struct S {
|
||||||
/// is_pending: bool,
|
/// is_pending: bool,
|
||||||
/// is_processing: bool,
|
/// is_processing: bool,
|
||||||
|
@ -31,7 +31,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// enum S {
|
/// enum S {
|
||||||
/// Pending,
|
/// Pending,
|
||||||
/// Processing,
|
/// Processing,
|
||||||
|
@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
|
||||||
// functions with a body are already checked by `check_fn`
|
// functions with a body are already checked by `check_fn`
|
||||||
if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
|
if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
|
||||||
&& fn_sig.header.abi == Abi::Rust
|
&& fn_sig.header.abi == Abi::Rust
|
||||||
{
|
{
|
||||||
self.check_fn_sig(cx, fn_sig.decl, fn_sig.span);
|
self.check_fn_sig(cx, fn_sig.decl, fn_sig.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,11 +174,8 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
|
||||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
if let Some(fn_header) = fn_kind.header()
|
if let Some(fn_header) = fn_kind.header()
|
||||||
&& fn_header.abi == Abi::Rust
|
&& fn_header.abi == Abi::Rust
|
||||||
&& get_parent_as_impl(cx.tcx, hir_id)
|
&& get_parent_as_impl(cx.tcx, hir_id).map_or(true, |impl_item| impl_item.of_trait.is_none())
|
||||||
.map_or(true,
|
{
|
||||||
|impl_item| impl_item.of_trait.is_none()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
self.check_fn_sig(cx, fn_decl, span);
|
self.check_fn_sig(cx, fn_decl, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ declare_clippy_lint! {
|
||||||
/// disable them by default.
|
/// disable them by default.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// enum Foo {
|
/// enum Foo {
|
||||||
/// Bar,
|
/// Bar,
|
||||||
/// Baz
|
/// Baz
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[non_exhaustive]
|
/// #[non_exhaustive]
|
||||||
/// enum Foo {
|
/// enum Foo {
|
||||||
/// Bar,
|
/// Bar,
|
||||||
|
@ -47,14 +47,14 @@ declare_clippy_lint! {
|
||||||
/// disable them by default.
|
/// disable them by default.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// bar: u8,
|
/// bar: u8,
|
||||||
/// baz: String,
|
/// baz: String,
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[non_exhaustive]
|
/// #[non_exhaustive]
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// bar: u8,
|
/// bar: u8,
|
||||||
|
|
|
@ -17,7 +17,7 @@ declare_clippy_lint! {
|
||||||
/// the main function.
|
/// the main function.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// std::process::exit(0)
|
/// std::process::exit(0)
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
|
@ -19,7 +19,7 @@ declare_clippy_lint! {
|
||||||
/// Using `(e)println! is clearer and more concise
|
/// Using `(e)println! is clearer and more concise
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::io::Write;
|
/// # use std::io::Write;
|
||||||
/// # let bar = "furchtbar";
|
/// # let bar = "furchtbar";
|
||||||
/// writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
|
/// writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
|
||||||
|
@ -27,7 +27,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::io::Write;
|
/// # use std::io::Write;
|
||||||
/// # let bar = "furchtbar";
|
/// # let bar = "furchtbar";
|
||||||
/// eprintln!("foo: {:?}", bar);
|
/// eprintln!("foo: {:?}", bar);
|
||||||
|
@ -58,7 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
||||||
Some(sym::io_stderr) => ("stderr", "e"),
|
Some(sym::io_stderr) => ("stderr", "e"),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else { return; };
|
let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// ordering is important here, since `writeln!` uses `write!` internally
|
// ordering is important here, since `writeln!` uses `write!` internally
|
||||||
let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
|
let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
|
||||||
|
@ -78,18 +80,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
||||||
macro_name.replace("write", "print"),
|
macro_name.replace("write", "print"),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(format!("{dest_name}().write_fmt(...)"), "print".into())
|
||||||
format!("{dest_name}().write_fmt(...)"),
|
|
||||||
"print".into(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
let inputs_snippet = snippet_with_applicability(
|
let inputs_snippet =
|
||||||
cx,
|
snippet_with_applicability(cx, format_args_inputs_span(&format_args), "..", &mut applicability);
|
||||||
format_args_inputs_span(&format_args),
|
|
||||||
"..",
|
|
||||||
&mut applicability,
|
|
||||||
);
|
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
EXPLICIT_WRITE,
|
EXPLICIT_WRITE,
|
||||||
|
|
|
@ -23,13 +23,13 @@ declare_clippy_lint! {
|
||||||
/// requires using a turbofish, which serves no purpose but to satisfy the compiler.
|
/// requires using a turbofish, which serves no purpose but to satisfy the compiler.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn unused_ty<T>(x: u8) {
|
/// fn unused_ty<T>(x: u8) {
|
||||||
/// // ..
|
/// // ..
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn no_unused_ty(x: u8) {
|
/// fn no_unused_ty(x: u8) {
|
||||||
/// // ..
|
/// // ..
|
||||||
/// }
|
/// }
|
||||||
|
@ -177,20 +177,22 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.map(|(idx, param)| {
|
.map(|(idx, param)| {
|
||||||
if let Some(next) = explicit_params.get(idx + 1) && end != Some(next.def_id) {
|
if let Some(next) = explicit_params.get(idx + 1)
|
||||||
// Extend the current span forward, up until the next param in the list.
|
&& end != Some(next.def_id)
|
||||||
param.span.until(next.span)
|
{
|
||||||
} else {
|
// Extend the current span forward, up until the next param in the list.
|
||||||
// Extend the current span back to include the comma following the previous
|
param.span.until(next.span)
|
||||||
// param. If the span of the next param in the list has already been
|
} else {
|
||||||
// extended, we continue the chain. This is why we're iterating in reverse.
|
// Extend the current span back to include the comma following the previous
|
||||||
end = Some(param.def_id);
|
// param. If the span of the next param in the list has already been
|
||||||
|
// extended, we continue the chain. This is why we're iterating in reverse.
|
||||||
|
end = Some(param.def_id);
|
||||||
|
|
||||||
// idx will never be 0, else we'd be removing the entire list of generics
|
// idx will never be 0, else we'd be removing the entire list of generics
|
||||||
let prev = explicit_params[idx - 1];
|
let prev = explicit_params[idx - 1];
|
||||||
let prev_span = self.get_bound_span(prev);
|
let prev_span = self.get_bound_span(prev);
|
||||||
self.get_bound_span(param).with_lo(prev_span.hi())
|
self.get_bound_span(param).with_lo(prev_span.hi())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ declare_clippy_lint! {
|
||||||
/// `TryFrom` should be used if there's a possibility of failure.
|
/// `TryFrom` should be used if there's a possibility of failure.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo(i32);
|
/// struct Foo(i32);
|
||||||
///
|
///
|
||||||
/// impl From<String> for Foo {
|
/// impl From<String> for Foo {
|
||||||
|
@ -28,7 +28,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo(i32);
|
/// struct Foo(i32);
|
||||||
///
|
///
|
||||||
/// impl TryFrom<String> for Foo {
|
/// impl TryFrom<String> for Foo {
|
||||||
|
|
|
@ -18,13 +18,13 @@ declare_clippy_lint! {
|
||||||
/// Rust will truncate the literal silently.
|
/// Rust will truncate the literal silently.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let v: f32 = 0.123_456_789_9;
|
/// let v: f32 = 0.123_456_789_9;
|
||||||
/// println!("{}", v); // 0.123_456_789
|
/// println!("{}", v); // 0.123_456_789
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// 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
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -44,12 +44,12 @@ declare_clippy_lint! {
|
||||||
/// conversion to a float.
|
/// conversion to a float.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _: f32 = 16_777_217.0; // 16_777_216.0
|
/// let _: f32 = 16_777_217.0; // 16_777_216.0
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let _: f32 = 16_777_216.0;
|
/// let _: f32 = 16_777_216.0;
|
||||||
/// let _: f64 = 16_777_217.0;
|
/// let _: f64 = 16_777_217.0;
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -27,7 +27,7 @@ declare_clippy_lint! {
|
||||||
/// Negatively impacts accuracy.
|
/// Negatively impacts accuracy.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = 3f32;
|
/// let a = 3f32;
|
||||||
/// let _ = a.powf(1.0 / 3.0);
|
/// let _ = a.powf(1.0 / 3.0);
|
||||||
/// let _ = (1.0 + a).ln();
|
/// let _ = (1.0 + a).ln();
|
||||||
|
@ -35,7 +35,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let a = 3f32;
|
/// let a = 3f32;
|
||||||
/// let _ = a.cbrt();
|
/// let _ = a.cbrt();
|
||||||
/// let _ = a.ln_1p();
|
/// let _ = a.ln_1p();
|
||||||
|
@ -57,7 +57,7 @@ declare_clippy_lint! {
|
||||||
/// Negatively impacts accuracy and performance.
|
/// Negatively impacts accuracy and performance.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::f32::consts::E;
|
/// use std::f32::consts::E;
|
||||||
///
|
///
|
||||||
/// let a = 3f32;
|
/// let a = 3f32;
|
||||||
|
@ -83,7 +83,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// is better expressed as
|
/// is better expressed as
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::f32::consts::E;
|
/// use std::f32::consts::E;
|
||||||
///
|
///
|
||||||
/// let a = 3f32;
|
/// let a = 3f32;
|
||||||
|
@ -323,9 +323,9 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args:
|
||||||
let maybe_neg_sugg = |expr, hir_id| {
|
let maybe_neg_sugg = |expr, hir_id| {
|
||||||
let sugg = Sugg::hir(cx, expr, "..");
|
let sugg = Sugg::hir(cx, expr, "..");
|
||||||
if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id {
|
if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id {
|
||||||
format!("-{}", sugg.maybe_par())
|
-sugg
|
||||||
} else {
|
} else {
|
||||||
sugg.to_string()
|
sugg
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -470,25 +470,13 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
|
|
||||||
let maybe_neg_sugg = |expr| {
|
let maybe_neg_sugg = |expr| {
|
||||||
let sugg = Sugg::hir(cx, expr, "..");
|
let sugg = Sugg::hir(cx, expr, "..");
|
||||||
if let BinOpKind::Sub = op {
|
if let BinOpKind::Sub = op { -sugg } else { sugg }
|
||||||
format!("-{sugg}")
|
|
||||||
} else {
|
|
||||||
sugg.to_string()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) {
|
let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) {
|
||||||
(
|
(inner_lhs, Sugg::hir(cx, inner_rhs, ".."), maybe_neg_sugg(rhs))
|
||||||
inner_lhs,
|
|
||||||
Sugg::hir(cx, inner_rhs, "..").to_string(),
|
|
||||||
maybe_neg_sugg(rhs),
|
|
||||||
)
|
|
||||||
} else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) {
|
} else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) {
|
||||||
(
|
(inner_lhs, maybe_neg_sugg(inner_rhs), Sugg::hir(cx, lhs, ".."))
|
||||||
inner_lhs,
|
|
||||||
maybe_neg_sugg(inner_rhs),
|
|
||||||
Sugg::hir(cx, lhs, "..").to_string(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,13 +23,13 @@ declare_clippy_lint! {
|
||||||
/// if `foo: &str`.
|
/// if `foo: &str`.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let foo = "foo";
|
/// let foo = "foo";
|
||||||
/// format!("{}", foo);
|
/// format!("{}", foo);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let foo = "foo";
|
/// let foo = "foo";
|
||||||
/// foo.to_owned();
|
/// foo.to_owned();
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -54,7 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
|
||||||
([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
|
([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
|
||||||
([], [_]) => {
|
([], [_]) => {
|
||||||
// Simulate macro expansion, converting {{ and }} to { and }.
|
// Simulate macro expansion, converting {{ and }} to { and }.
|
||||||
let Some(snippet) = snippet_opt(cx, format_args.span) else { return };
|
let Some(snippet) = snippet_opt(cx, format_args.span) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let s_expand = snippet.replace("{{", "{").replace("}}", "}");
|
let s_expand = snippet.replace("{{", "{").replace("}}", "}");
|
||||||
let sugg = format!("{s_expand}.to_string()");
|
let sugg = format!("{s_expand}.to_string()");
|
||||||
span_useless_format(cx, call_site, sugg, applicability);
|
span_useless_format(cx, call_site, sugg, applicability);
|
||||||
|
@ -76,13 +78,14 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let sugg = if is_new_string {
|
let sugg = if is_new_string {
|
||||||
snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability).0.into_owned()
|
snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability)
|
||||||
|
.0
|
||||||
|
.into_owned()
|
||||||
} else {
|
} else {
|
||||||
let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), "<arg>", &mut applicability);
|
let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), "<arg>", &mut applicability);
|
||||||
format!("{}.to_string()", sugg.maybe_par())
|
format!("{}.to_string()", sugg.maybe_par())
|
||||||
};
|
};
|
||||||
span_useless_format(cx, call_site, sugg, applicability);
|
span_useless_format(cx, call_site, sugg, applicability);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
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::is_diag_trait_item;
|
use clippy_utils::is_diag_trait_item;
|
||||||
use clippy_utils::macros::{
|
use clippy_utils::macros::{
|
||||||
find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro,
|
find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro,
|
||||||
is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage,
|
is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage,
|
||||||
};
|
};
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
@ -35,12 +35,12 @@ declare_clippy_lint! {
|
||||||
/// The recommended code is both shorter and avoids a temporary allocation.
|
/// The recommended code is both shorter and avoids a temporary allocation.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: {}", format!("something failed at {}", Location::caller()));
|
/// println!("error: {}", format!("something failed at {}", Location::caller()));
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: something failed at {}", Location::caller());
|
/// println!("error: something failed at {}", Location::caller());
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -61,12 +61,12 @@ declare_clippy_lint! {
|
||||||
/// unnecessary.
|
/// unnecessary.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: something failed at {}", Location::caller().to_string());
|
/// println!("error: something failed at {}", Location::caller().to_string());
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::panic::Location;
|
/// # use std::panic::Location;
|
||||||
/// println!("error: something failed at {}", Location::caller());
|
/// println!("error: something failed at {}", Location::caller());
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -87,7 +87,7 @@ declare_clippy_lint! {
|
||||||
/// The inlined syntax, where allowed, is simpler.
|
/// The inlined syntax, where allowed, is simpler.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let var = 42;
|
/// # let var = 42;
|
||||||
/// # let width = 1;
|
/// # let width = 1;
|
||||||
/// # let prec = 2;
|
/// # let prec = 2;
|
||||||
|
@ -98,7 +98,7 @@ declare_clippy_lint! {
|
||||||
/// format!("{:.*}", prec, var);
|
/// format!("{:.*}", prec, var);
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let var = 42;
|
/// # let var = 42;
|
||||||
/// # let width = 1;
|
/// # let width = 1;
|
||||||
/// # let prec = 2;
|
/// # let prec = 2;
|
||||||
|
@ -111,12 +111,12 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// If allow-mixed-uninlined-format-args is set to false in clippy.toml,
|
/// If allow-mixed-uninlined-format-args is set to false in clippy.toml,
|
||||||
/// the following code will also trigger the lint:
|
/// the following code will also trigger the lint:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let var = 42;
|
/// # let var = 42;
|
||||||
/// format!("{} {}", var, 1+2);
|
/// format!("{} {}", var, 1+2);
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let var = 42;
|
/// # let var = 42;
|
||||||
/// format!("{var} {}", 1+2);
|
/// format!("{var} {}", 1+2);
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -141,13 +141,13 @@ declare_clippy_lint! {
|
||||||
/// an expected formatting operation such as adding padding isn't happening.
|
/// an expected formatting operation such as adding padding isn't happening.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// println!("{:.}", 1.0);
|
/// println!("{:.}", 1.0);
|
||||||
///
|
///
|
||||||
/// println!("not padded: {:5}", format_args!("..."));
|
/// println!("not padded: {:5}", format_args!("..."));
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// println!("{}", 1.0);
|
/// println!("{}", 1.0);
|
||||||
///
|
///
|
||||||
/// println!("not padded: {}", format_args!("..."));
|
/// println!("not padded: {}", format_args!("..."));
|
||||||
|
@ -370,7 +370,7 @@ fn check_one_arg(
|
||||||
};
|
};
|
||||||
fixes.push((pos_span, replacement));
|
fixes.push((pos_span, replacement));
|
||||||
fixes.push((arg_span, String::new()));
|
fixes.push((arg_span, String::new()));
|
||||||
true // successful inlining, continue checking
|
true // successful inlining, continue checking
|
||||||
} else {
|
} else {
|
||||||
// Do not continue inlining (return false) in case
|
// Do not continue inlining (return false) in case
|
||||||
// * if we can't inline a numbered argument, e.g. `print!("{0} ...", foo.bar, ...)`
|
// * if we can't inline a numbered argument, e.g. `print!("{0} ...", foo.bar, ...)`
|
||||||
|
|
|
@ -21,7 +21,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::fmt;
|
/// use std::fmt;
|
||||||
///
|
///
|
||||||
/// struct Structure(i32);
|
/// struct Structure(i32);
|
||||||
|
@ -33,7 +33,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::fmt;
|
/// use std::fmt;
|
||||||
///
|
///
|
||||||
/// struct Structure(i32);
|
/// struct Structure(i32);
|
||||||
|
@ -59,7 +59,7 @@ declare_clippy_lint! {
|
||||||
/// should write to the `Formatter`, not stdout/stderr.
|
/// should write to the `Formatter`, not stdout/stderr.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::fmt::{Display, Error, Formatter};
|
/// use std::fmt::{Display, Error, Formatter};
|
||||||
///
|
///
|
||||||
/// struct S;
|
/// struct S;
|
||||||
|
@ -72,7 +72,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::fmt::{Display, Error, Formatter};
|
/// use std::fmt::{Display, Error, Formatter};
|
||||||
///
|
///
|
||||||
/// struct S;
|
/// struct S;
|
||||||
|
|
|
@ -21,13 +21,13 @@ declare_clippy_lint! {
|
||||||
/// While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.
|
/// While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let mut s = String::new();
|
/// let mut s = String::new();
|
||||||
/// s += &format!("0x{:X}", 1024);
|
/// s += &format!("0x{:X}", 1024);
|
||||||
/// s.push_str(&format!("0x{:X}", 1024));
|
/// s.push_str(&format!("0x{:X}", 1024));
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// use std::fmt::Write as _; // import without risk of name clashing
|
/// use std::fmt::Write as _; // import without risk of name clashing
|
||||||
///
|
///
|
||||||
/// let mut s = String::new();
|
/// let mut s = String::new();
|
||||||
|
@ -58,7 +58,7 @@ fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||||
arms.iter().any(|arm| is_format(cx, arm.body))
|
arms.iter().any(|arm| is_format(cx, arm.body))
|
||||||
},
|
},
|
||||||
Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else)) => {
|
Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else)) => {
|
||||||
is_format(cx, then) ||r#else.is_some_and(|e| is_format(cx, e))
|
is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e))
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -69,17 +69,15 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
let arg = match expr.kind {
|
let arg = match expr.kind {
|
||||||
ExprKind::MethodCall(_, _, [arg], _) => {
|
ExprKind::MethodCall(_, _, [arg], _) => {
|
||||||
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) &&
|
if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||||
match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
|
&& match_def_path(cx, fn_def_id, &paths::PUSH_STR)
|
||||||
|
{
|
||||||
arg
|
arg
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ExprKind::AssignOp(op, left, arg)
|
|
||||||
if op.node == BinOpKind::Add && is_string(cx, left) => {
|
|
||||||
arg
|
|
||||||
},
|
},
|
||||||
|
ExprKind::AssignOp(op, left, arg) if op.node == BinOpKind::Add && is_string(cx, left) => arg,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if is_format(cx, arg) {
|
if is_format(cx, arg) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ declare_clippy_lint! {
|
||||||
/// This is either a typo in the binary operator or confusing.
|
/// This is either a typo in the binary operator or confusing.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let foo = true;
|
/// # let foo = true;
|
||||||
/// # let bar = false;
|
/// # let bar = false;
|
||||||
/// // &&! looks like a different operator
|
/// // &&! looks like a different operator
|
||||||
|
@ -45,7 +45,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let foo = true;
|
/// # let foo = true;
|
||||||
/// # let bar = false;
|
/// # let bar = false;
|
||||||
/// if foo && !bar {}
|
/// if foo && !bar {}
|
||||||
|
|
|
@ -14,7 +14,7 @@ declare_clippy_lint! {
|
||||||
/// comment.
|
/// comment.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// //// My amazing data structure
|
/// //// My amazing data structure
|
||||||
/// pub struct Foo {
|
/// pub struct Foo {
|
||||||
/// // ...
|
/// // ...
|
||||||
|
@ -22,7 +22,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// /// My amazing data structure
|
/// /// My amazing data structure
|
||||||
/// pub struct Foo {
|
/// pub struct Foo {
|
||||||
/// // ...
|
/// // ...
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::macros::span_is_local;
|
use clippy_utils::macros::span_is_local;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::path_def_id;
|
use clippy_utils::path_def_id;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
@ -24,7 +24,7 @@ declare_clippy_lint! {
|
||||||
/// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
|
/// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct StringWrapper(String);
|
/// struct StringWrapper(String);
|
||||||
///
|
///
|
||||||
/// impl Into<StringWrapper> for String {
|
/// impl Into<StringWrapper> for String {
|
||||||
|
@ -34,7 +34,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct StringWrapper(String);
|
/// struct StringWrapper(String);
|
||||||
///
|
///
|
||||||
/// impl From<String> for StringWrapper {
|
/// impl From<String> for StringWrapper {
|
||||||
|
@ -88,7 +88,8 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
||||||
cx.tcx.sess.source_map().guess_head_span(item.span),
|
cx.tcx.sess.source_map().guess_head_span(item.span),
|
||||||
"an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true",
|
"an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true",
|
||||||
|diag| {
|
|diag| {
|
||||||
// If the target type is likely foreign mention the orphan rules as it's a common source of confusion
|
// If the target type is likely foreign mention the orphan rules as it's a common source of
|
||||||
|
// confusion
|
||||||
if path_def_id(cx, target_ty.peel_refs()).map_or(true, |id| !id.is_local()) {
|
if path_def_id(cx, target_ty.peel_refs()).map_or(true, |id| !id.is_local()) {
|
||||||
diag.help(
|
diag.help(
|
||||||
"`impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n\
|
"`impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n\
|
||||||
|
@ -96,7 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = format!("replace the `Into` implementation with `From<{}>`", middle_trait_ref.self_ty());
|
let message = format!(
|
||||||
|
"replace the `Into` implementation with `From<{}>`",
|
||||||
|
middle_trait_ref.self_ty()
|
||||||
|
);
|
||||||
if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) {
|
if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) {
|
||||||
diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
|
diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,12 +114,12 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
||||||
extract_msrv_attr!(LateContext);
|
extract_msrv_attr!(LateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the occurences of `Self` and `self`
|
/// Finds the occurrences of `Self` and `self`
|
||||||
struct SelfFinder<'a, 'tcx> {
|
struct SelfFinder<'a, 'tcx> {
|
||||||
cx: &'a LateContext<'tcx>,
|
cx: &'a LateContext<'tcx>,
|
||||||
/// Occurences of `Self`
|
/// Occurrences of `Self`
|
||||||
upper: Vec<Span>,
|
upper: Vec<Span>,
|
||||||
/// Occurences of `self`
|
/// Occurrences of `self`
|
||||||
lower: Vec<Span>,
|
lower: Vec<Span>,
|
||||||
/// If any of the `self`/`Self` usages were from an expansion, or the body contained a binding
|
/// If any of the `self`/`Self` usages were from an expansion, or the body contained a binding
|
||||||
/// already named `val`
|
/// already named `val`
|
||||||
|
|
|
@ -18,13 +18,13 @@ declare_clippy_lint! {
|
||||||
/// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.
|
/// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::ffi::c_void;
|
/// # use std::ffi::c_void;
|
||||||
/// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
|
/// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
|
||||||
/// let _ = unsafe { Box::from_raw(ptr) };
|
/// let _ = unsafe { Box::from_raw(ptr) };
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::ffi::c_void;
|
/// # use std::ffi::c_void;
|
||||||
/// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
|
/// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
|
||||||
/// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
|
/// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
|
||||||
|
@ -40,14 +40,22 @@ declare_lint_pass!(FromRawWithVoidPtr => [FROM_RAW_WITH_VOID_PTR]);
|
||||||
impl LateLintPass<'_> for FromRawWithVoidPtr {
|
impl LateLintPass<'_> for FromRawWithVoidPtr {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
|
if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
|
||||||
&& let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
|
&& let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
|
||||||
&& seg.ident.name == sym!(from_raw)
|
&& seg.ident.name == sym!(from_raw)
|
||||||
&& let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
|
&& let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
|
||||||
&& let arg_kind = cx.typeck_results().expr_ty(arg).kind()
|
&& let arg_kind = cx.typeck_results().expr_ty(arg).kind()
|
||||||
&& let RawPtr(TypeAndMut { ty, .. }) = arg_kind
|
&& let RawPtr(TypeAndMut { ty, .. }) = arg_kind
|
||||||
&& is_c_void(cx, *ty) {
|
&& is_c_void(cx, *ty)
|
||||||
|
{
|
||||||
let msg = format!("creating a `{type_str}` from a void raw pointer");
|
let msg = format!("creating a `{type_str}` from a void raw pointer");
|
||||||
span_lint_and_help(cx, FROM_RAW_WITH_VOID_PTR, expr.span, &msg, Some(arg.span), "cast this to a pointer of the appropriate type");
|
span_lint_and_help(
|
||||||
|
cx,
|
||||||
|
FROM_RAW_WITH_VOID_PTR,
|
||||||
|
expr.span,
|
||||||
|
&msg,
|
||||||
|
Some(arg.span),
|
||||||
|
"cast this to a pointer of the appropriate type",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ declare_clippy_lint! {
|
||||||
/// grouping some parameters into a new type.
|
/// grouping some parameters into a new type.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # struct Color;
|
/// # struct Color;
|
||||||
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
|
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
|
||||||
/// // ..
|
/// // ..
|
||||||
|
@ -46,7 +46,7 @@ declare_clippy_lint! {
|
||||||
/// multiple functions.
|
/// multiple functions.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn im_too_long() {
|
/// fn im_too_long() {
|
||||||
/// println!("");
|
/// println!("");
|
||||||
/// // ... 100 more LoC
|
/// // ... 100 more LoC
|
||||||
|
@ -129,7 +129,7 @@ declare_clippy_lint! {
|
||||||
/// a remnant of a refactoring that removed the return type.
|
/// a remnant of a refactoring that removed the return type.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[must_use]
|
/// #[must_use]
|
||||||
/// fn useless() { }
|
/// fn useless() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -151,7 +151,7 @@ declare_clippy_lint! {
|
||||||
/// attribute to improve the lint message.
|
/// attribute to improve the lint message.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[must_use]
|
/// #[must_use]
|
||||||
/// fn double_must_use() -> Result<(), ()> {
|
/// fn double_must_use() -> Result<(), ()> {
|
||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
|
@ -183,7 +183,7 @@ declare_clippy_lint! {
|
||||||
/// `#[must_use]`.
|
/// `#[must_use]`.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// // this could be annotated with `#[must_use]`.
|
/// // this could be annotated with `#[must_use]`.
|
||||||
/// pub fn id<T>(t: T) -> T { t }
|
/// pub fn id<T>(t: T) -> T { t }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -211,7 +211,7 @@ declare_clippy_lint! {
|
||||||
/// instead.
|
/// instead.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// pub fn read_u8() -> Result<u8, ()> { Err(()) }
|
/// pub fn read_u8() -> Result<u8, ()> { Err(()) }
|
||||||
/// ```
|
/// ```
|
||||||
/// should become
|
/// should become
|
||||||
|
@ -262,7 +262,7 @@ declare_clippy_lint! {
|
||||||
/// The size determined by Clippy is platform-dependent.
|
/// The size determined by Clippy is platform-dependent.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// pub enum ParseError {
|
/// pub enum ParseError {
|
||||||
/// UnparsedBytes([u8; 512]),
|
/// UnparsedBytes([u8; 512]),
|
||||||
/// UnexpectedEof,
|
/// UnexpectedEof,
|
||||||
|
@ -274,7 +274,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// should be
|
/// should be
|
||||||
/// ```
|
/// ```no_run
|
||||||
/// pub enum ParseError {
|
/// pub enum ParseError {
|
||||||
/// UnparsedBytes(Box<[u8; 512]>),
|
/// UnparsedBytes(Box<[u8; 512]>),
|
||||||
/// UnexpectedEof,
|
/// UnexpectedEof,
|
||||||
|
@ -301,7 +301,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
|
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct A {
|
/// struct A {
|
||||||
/// a: String,
|
/// a: String,
|
||||||
/// b: String,
|
/// b: String,
|
||||||
|
@ -315,7 +315,7 @@ declare_clippy_lint! {
|
||||||
|
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct A {
|
/// struct A {
|
||||||
/// a: String,
|
/// a: String,
|
||||||
/// b: String,
|
/// b: String,
|
||||||
|
@ -340,14 +340,14 @@ declare_clippy_lint! {
|
||||||
/// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor.
|
/// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// trait MyTrait {}
|
/// trait MyTrait {}
|
||||||
/// fn foo(a: impl MyTrait) {
|
/// fn foo(a: impl MyTrait) {
|
||||||
/// // [...]
|
/// // [...]
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// trait MyTrait {}
|
/// trait MyTrait {}
|
||||||
/// fn foo<T: MyTrait>(a: T) {
|
/// fn foo<T: MyTrait>(a: T) {
|
||||||
/// // [...]
|
/// // [...]
|
||||||
|
|
|
@ -118,9 +118,10 @@ fn check_needless_must_use(
|
||||||
if sig.header.is_async() {
|
if sig.header.is_async() {
|
||||||
let infcx = cx.tcx.infer_ctxt().build();
|
let infcx = cx.tcx.infer_ctxt().build();
|
||||||
if let Some(future_ty) = infcx.get_impl_future_output_ty(return_ty(cx, item_id))
|
if let Some(future_ty) = infcx.get_impl_future_output_ty(return_ty(cx, item_id))
|
||||||
&& !is_must_use_ty(cx, future_ty) {
|
&& !is_must_use_ty(cx, future_ty)
|
||||||
return;
|
{
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
|
|
|
@ -21,7 +21,9 @@ fn result_err_ty<'tcx>(
|
||||||
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
|
||||||
if !in_external_macro(cx.sess(), item_span)
|
if !in_external_macro(cx.sess(), item_span)
|
||||||
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
&& let hir::FnRetTy::Return(hir_ty) = decl.output
|
||||||
&& let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_identity().output())
|
&& let ty = cx
|
||||||
|
.tcx
|
||||||
|
.erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_identity().output())
|
||||||
&& is_type_diagnostic_item(cx, ty, sym::Result)
|
&& is_type_diagnostic_item(cx, ty, sym::Result)
|
||||||
&& let ty::Adt(_, args) = ty.kind()
|
&& let ty::Adt(_, args) = ty.kind()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,11 +34,11 @@ declare_clippy_lint! {
|
||||||
/// produced.
|
/// produced.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
|
/// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
|
/// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.44.0"]
|
#[clippy::version = "1.44.0"]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! lint on if branches that could be swapped so no `!` operation is necessary
|
//! lint on if branches that could be swapped so no `!` operation is necessary
|
||||||
//! on the condition
|
//! on the condition
|
||||||
|
|
||||||
|
use clippy_utils::consts::{constant_simple, Constant};
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::is_else_clause;
|
use clippy_utils::is_else_clause;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
||||||
|
@ -16,7 +17,7 @@ declare_clippy_lint! {
|
||||||
/// Negations reduce the readability of statements.
|
/// Negations reduce the readability of statements.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let v: Vec<usize> = vec![];
|
/// # let v: Vec<usize> = vec![];
|
||||||
/// # fn a() {}
|
/// # fn a() {}
|
||||||
/// # fn b() {}
|
/// # fn b() {}
|
||||||
|
@ -29,7 +30,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// Could be written:
|
/// Could be written:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let v: Vec<usize> = vec![];
|
/// # let v: Vec<usize> = vec![];
|
||||||
/// # fn a() {}
|
/// # fn a() {}
|
||||||
/// # fn b() {}
|
/// # fn b() {}
|
||||||
|
@ -47,6 +48,13 @@ declare_clippy_lint! {
|
||||||
|
|
||||||
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
|
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
|
||||||
|
|
||||||
|
fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
|
||||||
|
if let Some(value) = constant_simple(cx, cx.typeck_results(), expr) {
|
||||||
|
return Constant::Int(0) == value;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
impl LateLintPass<'_> for IfNotElse {
|
impl LateLintPass<'_> for IfNotElse {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
|
||||||
// While loops will be desugared to ExprKind::If. This will cause the lint to fire.
|
// While loops will be desugared to ExprKind::If. This will cause the lint to fire.
|
||||||
|
@ -72,7 +80,9 @@ impl LateLintPass<'_> for IfNotElse {
|
||||||
"remove the `!` and swap the blocks of the `if`/`else`",
|
"remove the `!` and swap the blocks of the `if`/`else`",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => {
|
ExprKind::Binary(ref kind, _, lhs) if kind.node == BinOpKind::Ne && !is_zero_const(lhs, cx) => {
|
||||||
|
// Disable firing the lint on `… != 0`, as these are likely to be bit tests.
|
||||||
|
// For example, `if foo & 0x0F00 != 0 { … } else { … }` already is in the "proper" order.
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
IF_NOT_ELSE,
|
IF_NOT_ELSE,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
|
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::source::snippet_with_context;
|
use clippy_utils::source::snippet_with_context;
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};
|
use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};
|
||||||
|
@ -21,7 +21,7 @@ declare_clippy_lint! {
|
||||||
/// in comparison to `bool::then`.
|
/// in comparison to `bool::then`.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let v = vec![0];
|
/// # let v = vec![0];
|
||||||
/// let a = if v.is_empty() {
|
/// let a = if v.is_empty() {
|
||||||
/// println!("true!");
|
/// println!("true!");
|
||||||
|
@ -33,7 +33,7 @@ declare_clippy_lint! {
|
||||||
///
|
///
|
||||||
/// Could be written:
|
/// Could be written:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let v = vec![0];
|
/// # let v = vec![0];
|
||||||
/// let a = v.is_empty().then(|| {
|
/// let a = v.is_empty().then(|| {
|
||||||
/// println!("true!");
|
/// println!("true!");
|
||||||
|
@ -76,7 +76,11 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||||
|
|
||||||
let ctxt = expr.span.ctxt();
|
let ctxt = expr.span.ctxt();
|
||||||
|
|
||||||
if let Some(higher::If { cond, then, r#else: Some(els) }) = higher::If::hir(expr)
|
if let Some(higher::If {
|
||||||
|
cond,
|
||||||
|
then,
|
||||||
|
r#else: Some(els),
|
||||||
|
}) = higher::If::hir(expr)
|
||||||
&& let ExprKind::Block(then_block, _) = then.kind
|
&& let ExprKind::Block(then_block, _) = then.kind
|
||||||
&& let Some(then_expr) = then_block.expr
|
&& let Some(then_expr) = then_block.expr
|
||||||
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
|
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
|
||||||
|
@ -86,7 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||||
&& !contains_return(then_block.stmts)
|
&& !contains_return(then_block.stmts)
|
||||||
{
|
{
|
||||||
let mut app = Applicability::Unspecified;
|
let mut app = Applicability::Unspecified;
|
||||||
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app).maybe_par().to_string();
|
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app)
|
||||||
|
.maybe_par()
|
||||||
|
.to_string();
|
||||||
let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
|
let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
|
||||||
let mut method_body = if then_block.stmts.is_empty() {
|
let mut method_body = if then_block.stmts.is_empty() {
|
||||||
arg_snip.into_owned()
|
arg_snip.into_owned()
|
||||||
|
@ -100,9 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||||
"then"
|
"then"
|
||||||
};
|
};
|
||||||
|
|
||||||
let help = format!(
|
let help =
|
||||||
"consider using `bool::{method_name}` like: `{cond_snip}.{method_name}({method_body})`",
|
format!("consider using `bool::{method_name}` like: `{cond_snip}.{method_name}({method_body})`",);
|
||||||
);
|
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
IF_THEN_SOME_ELSE_NONE,
|
IF_THEN_SOME_ELSE_NONE,
|
||||||
|
|
|
@ -15,14 +15,14 @@ declare_clippy_lint! {
|
||||||
/// would detect a type change that `_` would ignore.
|
/// would detect a type change that `_` would ignore.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// match std::fs::create_dir("tmp-work-dir") {
|
/// match std::fs::create_dir("tmp-work-dir") {
|
||||||
/// Ok(_) => println!("Working directory created"),
|
/// Ok(_) => println!("Working directory created"),
|
||||||
/// Err(s) => eprintln!("Could not create directory: {s}"),
|
/// Err(s) => eprintln!("Could not create directory: {s}"),
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// match std::fs::create_dir("tmp-work-dir") {
|
/// match std::fs::create_dir("tmp-work-dir") {
|
||||||
/// Ok(()) => println!("Working directory created"),
|
/// Ok(()) => println!("Working directory created"),
|
||||||
/// Err(s) => eprintln!("Could not create directory: {s}"),
|
/// Err(s) => eprintln!("Could not create directory: {s}"),
|
||||||
|
@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
if matches!(pat.kind, PatKind::Wild) && cx.typeck_results().pat_ty(pat).is_unit() {
|
if matches!(pat.kind, PatKind::Wild) && cx.typeck_results().pat_ty(pat).peel_refs().is_unit() {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
IGNORED_UNIT_PATTERNS,
|
IGNORED_UNIT_PATTERNS,
|
||||||
|
|
|
@ -35,7 +35,7 @@ declare_clippy_lint! {
|
||||||
/// pieces of code, possibly including external crates.
|
/// pieces of code, possibly including external crates.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::collections::HashMap;
|
/// # use std::collections::HashMap;
|
||||||
/// # use std::hash::{Hash, BuildHasher};
|
/// # use std::hash::{Hash, BuildHasher};
|
||||||
/// # trait Serialize {};
|
/// # trait Serialize {};
|
||||||
|
@ -44,7 +44,7 @@ declare_clippy_lint! {
|
||||||
/// pub fn foo(map: &mut HashMap<i32, i32>) { }
|
/// pub fn foo(map: &mut HashMap<i32, i32>) { }
|
||||||
/// ```
|
/// ```
|
||||||
/// could be rewritten as
|
/// could be rewritten as
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::collections::HashMap;
|
/// # use std::collections::HashMap;
|
||||||
/// # use std::hash::{Hash, BuildHasher};
|
/// # use std::hash::{Hash, BuildHasher};
|
||||||
/// # trait Serialize {};
|
/// # trait Serialize {};
|
||||||
|
|
|
@ -24,13 +24,13 @@ declare_clippy_lint! {
|
||||||
/// corresponding statements.
|
/// corresponding statements.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(x: usize) -> usize {
|
/// fn foo(x: usize) -> usize {
|
||||||
/// x
|
/// x
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// add return
|
/// add return
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// fn foo(x: usize) -> usize {
|
/// fn foo(x: usize) -> usize {
|
||||||
/// return x;
|
/// return x;
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -18,7 +18,7 @@ declare_clippy_lint! {
|
||||||
/// The built-in function is more readable and may be faster.
|
/// The built-in function is more readable and may be faster.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///let mut u:u32 = 7000;
|
///let mut u:u32 = 7000;
|
||||||
///
|
///
|
||||||
/// if u != u32::MAX {
|
/// if u != u32::MAX {
|
||||||
|
@ -26,7 +26,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
///let mut u:u32 = 7000;
|
///let mut u:u32 = 7000;
|
||||||
///
|
///
|
||||||
/// u = u.saturating_add(1);
|
/// u = u.saturating_add(1);
|
||||||
|
@ -82,18 +82,18 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
|
||||||
|
|
||||||
fn get_int_max(ty: Ty<'_>) -> Option<u128> {
|
fn get_int_max(ty: Ty<'_>) -> Option<u128> {
|
||||||
match ty.peel_refs().kind() {
|
match ty.peel_refs().kind() {
|
||||||
Int(IntTy::I8) => i8::max_value().try_into().ok(),
|
Int(IntTy::I8) => i8::MAX.try_into().ok(),
|
||||||
Int(IntTy::I16) => i16::max_value().try_into().ok(),
|
Int(IntTy::I16) => i16::MAX.try_into().ok(),
|
||||||
Int(IntTy::I32) => i32::max_value().try_into().ok(),
|
Int(IntTy::I32) => i32::MAX.try_into().ok(),
|
||||||
Int(IntTy::I64) => i64::max_value().try_into().ok(),
|
Int(IntTy::I64) => i64::MAX.try_into().ok(),
|
||||||
Int(IntTy::I128) => i128::max_value().try_into().ok(),
|
Int(IntTy::I128) => i128::MAX.try_into().ok(),
|
||||||
Int(IntTy::Isize) => isize::max_value().try_into().ok(),
|
Int(IntTy::Isize) => isize::MAX.try_into().ok(),
|
||||||
Uint(UintTy::U8) => u8::max_value().try_into().ok(),
|
Uint(UintTy::U8) => Some(u8::MAX.into()),
|
||||||
Uint(UintTy::U16) => u16::max_value().try_into().ok(),
|
Uint(UintTy::U16) => Some(u16::MAX.into()),
|
||||||
Uint(UintTy::U32) => u32::max_value().try_into().ok(),
|
Uint(UintTy::U32) => Some(u32::MAX.into()),
|
||||||
Uint(UintTy::U64) => u64::max_value().try_into().ok(),
|
Uint(UintTy::U64) => Some(u64::MAX.into()),
|
||||||
Uint(UintTy::U128) => Some(u128::max_value()),
|
Uint(UintTy::U128) => Some(u128::MAX),
|
||||||
Uint(UintTy::Usize) => usize::max_value().try_into().ok(),
|
Uint(UintTy::Usize) => usize::MAX.try_into().ok(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ declare_clippy_lint! {
|
||||||
/// Simplicity and readability. Instead we can easily use an builtin function.
|
/// Simplicity and readability. Instead we can easily use an builtin function.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let end: u32 = 10;
|
/// # let end: u32 = 10;
|
||||||
/// # let start: u32 = 5;
|
/// # let start: u32 = 5;
|
||||||
/// let mut i: u32 = end - start;
|
/// let mut i: u32 = end - start;
|
||||||
|
@ -26,7 +26,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # let end: u32 = 10;
|
/// # let end: u32 = 10;
|
||||||
/// # let start: u32 = 5;
|
/// # let start: u32 = 5;
|
||||||
/// let mut i: u32 = end - start;
|
/// let mut i: u32 = end - start;
|
||||||
|
|
|
@ -29,7 +29,7 @@ declare_clippy_lint! {
|
||||||
/// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)
|
/// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::ops::{Deref,DerefMut};
|
/// # use std::ops::{Deref,DerefMut};
|
||||||
/// fn f() -> impl Deref<Target = i32> + DerefMut<Target = i32> {
|
/// fn f() -> impl Deref<Target = i32> + DerefMut<Target = i32> {
|
||||||
/// // ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound
|
/// // ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound
|
||||||
|
@ -37,7 +37,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # use std::ops::{Deref,DerefMut};
|
/// # use std::ops::{Deref,DerefMut};
|
||||||
/// fn f() -> impl DerefMut<Target = i32> {
|
/// fn f() -> impl DerefMut<Target = i32> {
|
||||||
/// Box::new(123)
|
/// Box::new(123)
|
||||||
|
@ -230,19 +230,24 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
|
||||||
// Example:
|
// Example:
|
||||||
// `impl Deref<Target = i32> + DerefMut<Target = u32>` is not allowed.
|
// `impl Deref<Target = i32> + DerefMut<Target = u32>` is not allowed.
|
||||||
// `DerefMut::Target` needs to match `Deref::Target`.
|
// `DerefMut::Target` needs to match `Deref::Target`.
|
||||||
let implied_bounds: Vec<_> = opaque_ty.bounds.iter().filter_map(|bound| {
|
let implied_bounds: Vec<_> = opaque_ty
|
||||||
if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
|
.bounds
|
||||||
&& let [.., path] = poly_trait.trait_ref.path.segments
|
.iter()
|
||||||
&& poly_trait.bound_generic_params.is_empty()
|
.filter_map(|bound| {
|
||||||
&& let Some(trait_def_id) = path.res.opt_def_id()
|
if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
|
||||||
&& let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates
|
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||||
&& !predicates.is_empty() // If the trait has no supertrait, there is nothing to add.
|
&& poly_trait.bound_generic_params.is_empty()
|
||||||
{
|
&& let Some(trait_def_id) = path.res.opt_def_id()
|
||||||
Some((bound.span(), path, predicates, trait_def_id))
|
&& let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates
|
||||||
} else {
|
&& !predicates.is_empty()
|
||||||
None
|
// If the trait has no supertrait, there is nothing to add.
|
||||||
}
|
{
|
||||||
}).collect();
|
Some((bound.span(), path, predicates, trait_def_id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Lint all bounds in the `impl Trait` type that are also in the `implied_bounds` vec.
|
// Lint all bounds in the `impl Trait` type that are also in the `implied_bounds` vec.
|
||||||
// This involves some extra logic when generic arguments are present, since
|
// This involves some extra logic when generic arguments are present, since
|
||||||
|
@ -253,30 +258,31 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
|
||||||
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
||||||
&& let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
|
&& let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
|
||||||
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
|
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
|
||||||
&& let Some((implied_by_span, implied_by_args, implied_by_bindings)) = implied_bounds
|
&& let Some((implied_by_span, implied_by_args, implied_by_bindings)) =
|
||||||
.iter()
|
implied_bounds
|
||||||
.find_map(|&(span, implied_by_path, preds, implied_by_def_id)| {
|
.iter()
|
||||||
let implied_by_args = implied_by_path.args.map_or([].as_slice(), |a| a.args);
|
.find_map(|&(span, implied_by_path, preds, implied_by_def_id)| {
|
||||||
let implied_by_bindings = implied_by_path.args.map_or([].as_slice(), |a| a.bindings);
|
let implied_by_args = implied_by_path.args.map_or([].as_slice(), |a| a.args);
|
||||||
|
let implied_by_bindings = implied_by_path.args.map_or([].as_slice(), |a| a.bindings);
|
||||||
|
|
||||||
preds.iter().find_map(|(clause, _)| {
|
preds.iter().find_map(|(clause, _)| {
|
||||||
if let ClauseKind::Trait(tr) = clause.kind().skip_binder()
|
if let ClauseKind::Trait(tr) = clause.kind().skip_binder()
|
||||||
&& tr.def_id() == def_id
|
&& tr.def_id() == def_id
|
||||||
&& is_same_generics(
|
&& is_same_generics(
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
tr.trait_ref.args,
|
tr.trait_ref.args,
|
||||||
implied_by_args,
|
implied_by_args,
|
||||||
implied_args,
|
implied_args,
|
||||||
implied_by_def_id,
|
implied_by_def_id,
|
||||||
def_id,
|
def_id,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Some((span, implied_by_args, implied_by_bindings))
|
Some((span, implied_by_args, implied_by_bindings))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
{
|
{
|
||||||
emit_lint(
|
emit_lint(
|
||||||
cx,
|
cx,
|
||||||
|
@ -286,7 +292,7 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
|
||||||
implied_bindings,
|
implied_bindings,
|
||||||
implied_by_bindings,
|
implied_by_bindings,
|
||||||
implied_by_args,
|
implied_by_args,
|
||||||
implied_by_span
|
implied_by_span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ declare_clippy_lint! {
|
||||||
/// Since the order of fields in a constructor doesn't affect the
|
/// Since the order of fields in a constructor doesn't affect the
|
||||||
/// resulted instance as the below example indicates,
|
/// resulted instance as the below example indicates,
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// #[derive(Debug, PartialEq, Eq)]
|
/// #[derive(Debug, PartialEq, Eq)]
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// x: i32,
|
/// x: i32,
|
||||||
|
@ -35,7 +35,7 @@ declare_clippy_lint! {
|
||||||
/// inconsistent order can be confusing and decreases readability and consistency.
|
/// inconsistent order can be confusing and decreases readability and consistency.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// struct Foo {
|
/// struct Foo {
|
||||||
/// x: i32,
|
/// x: i32,
|
||||||
/// y: i32,
|
/// y: i32,
|
||||||
|
@ -47,7 +47,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// # struct Foo {
|
/// # struct Foo {
|
||||||
/// # x: i32,
|
/// # x: i32,
|
||||||
/// # y: i32,
|
/// # y: i32,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_utils::consts::{constant, Constant};
|
use clippy_utils::consts::{constant, Constant};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::higher::IfLet;
|
use clippy_utils::higher::IfLet;
|
||||||
use clippy_utils::msrvs::{self, Msrv};
|
|
||||||
use clippy_utils::ty::is_copy;
|
use clippy_utils::ty::is_copy;
|
||||||
use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
|
use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
@ -31,7 +31,7 @@ declare_clippy_lint! {
|
||||||
/// patterns.
|
/// patterns.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
/// let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||||
///
|
///
|
||||||
/// if let Some(slice) = slice {
|
/// if let Some(slice) = slice {
|
||||||
|
@ -39,7 +39,7 @@ declare_clippy_lint! {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Use instead:
|
/// Use instead:
|
||||||
/// ```rust
|
/// ```no_run
|
||||||
/// let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
/// let slice: Option<&[u32]> = Some(&[1, 2, 3]);
|
||||||
///
|
///
|
||||||
/// if let Some(&[first, ..]) = slice {
|
/// if let Some(&[first, ..]) = slice {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue